pax_global_header00006660000000000000000000000064136150263610014515gustar00rootroot0000000000000052 comment=e64e752a28a4a41b0a43cba3bedf9571c22af807 libbytesize-2.2/000077500000000000000000000000001361502636100137055ustar00rootroot00000000000000libbytesize-2.2/.gitignore000066400000000000000000000015051361502636100156760ustar00rootroot00000000000000ByteSize-1.0.gir ByteSize-1.0.typelib Makefile Makefile.in aclocal.m4 ar-lib compile py-compile config.cache config.guess config.log config.status config.sub configure depcomp install-sh libtool ltmain.sh m4/ autom4te.cache/ missing po/*.po po/*.mpo po/*.mo dist/libbytesize.spec src/bytesize.pc docs/libbytesize-decl-list.txt docs/libbytesize-decl.txt docs/libbytesize-decl.txt.bak docs/libbytesize-overrides.txt docs/libbytesize-undeclared.txt docs/libbytesize-undocumented.txt docs/libbytesize-unused.txt docs/libbytesize.types docs/xml/ docs/html/ docs/libbytesize-docs.xml dist/libbytesize.spec **/*.deps **/*.libs **/*.la **/*.lo **/*.pyc **/__pycache__ **/Makefile **/Makefile.in **/*.stamp *.tar.gz **/*.po **/*.gmo **/*.po~ tests/*.log tests/*.trs test-driver tests/canary_tests.sh tests/libbytesize_unittest.sh tools/bs_calc.pylibbytesize-2.2/ABOUT-NLS000066400000000000000000002671331361502636100151500ustar00rootroot000000000000001 Notes on the Free Translation Project *************************************** Free software is going international! The Free Translation Project is a way to get maintainers of free software, translators, and users all together, so that free software will gradually become able to speak many languages. A few packages already provide translations for their messages. If you found this `ABOUT-NLS' file inside a distribution, you may assume that the distributed package does use GNU `gettext' internally, itself available at your nearest GNU archive site. But you do _not_ need to install GNU `gettext' prior to configuring, installing or using this package with messages translated. Installers will find here some useful hints. These notes also explain how users should proceed for getting the programs to use the available translations. They tell how people wanting to contribute and work on translations can contact the appropriate team. 1.1 INSTALL Matters =================== Some packages are "localizable" when properly installed; the programs they contain can be made to speak your own native language. Most such packages use GNU `gettext'. Other packages have their own ways to internationalization, predating GNU `gettext'. By default, this package will be installed to allow translation of messages. It will automatically detect whether the system already provides the GNU `gettext' functions. Installers may use special options at configuration time for changing the default behaviour. The command: ./configure --disable-nls will _totally_ disable translation of messages. When you already have GNU `gettext' installed on your system and run configure without an option for your new package, `configure' will probably detect the previously built and installed `libintl' library and will decide to use it. If not, you may have to to use the `--with-libintl-prefix' option to tell `configure' where to look for it. Internationalized packages usually have many `po/LL.po' files, where LL gives an ISO 639 two-letter code identifying the language. Unless translations have been forbidden at `configure' time by using the `--disable-nls' switch, all available translations are installed together with the package. However, the environment variable `LINGUAS' may be set, prior to configuration, to limit the installed set. `LINGUAS' should then contain a space separated list of two-letter codes, stating which languages are allowed. 1.2 Using This Package ====================== As a user, if your language has been installed for this package, you only have to set the `LANG' environment variable to the appropriate `LL_CC' combination. If you happen to have the `LC_ALL' or some other `LC_xxx' environment variables set, you should unset them before setting `LANG', otherwise the setting of `LANG' will not have the desired effect. Here `LL' is an ISO 639 two-letter language code, and `CC' is an ISO 3166 two-letter country code. For example, let's suppose that you speak German and live in Germany. At the shell prompt, merely execute `setenv LANG de_DE' (in `csh'), `export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash'). This can be done from your `.login' or `.profile' file, once and for all. You might think that the country code specification is redundant. But in fact, some languages have dialects in different countries. For example, `de_AT' is used for Austria, and `pt_BR' for Brazil. The country code serves to distinguish the dialects. The locale naming convention of `LL_CC', with `LL' denoting the language and `CC' denoting the country, is the one use on systems based on GNU libc. On other systems, some variations of this scheme are used, such as `LL' or `LL_CC.ENCODING'. You can get the list of locales supported by your system for your language by running the command `locale -a | grep '^LL''. Not all programs have translations for all languages. By default, an English message is shown in place of a nonexistent translation. If you understand other languages, you can set up a priority list of languages. This is done through a different environment variable, called `LANGUAGE'. GNU `gettext' gives preference to `LANGUAGE' over `LANG' for the purpose of message handling, but you still need to have `LANG' set to the primary language; this is required by other parts of the system libraries. For example, some Swedish users who would rather read translations in German than English for when Swedish is not available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'. Special advice for Norwegian users: The language code for Norwegian bokma*l changed from `no' to `nb' recently (in 2003). During the transition period, while some message catalogs for this language are installed under `nb' and some older ones under `no', it's recommended for Norwegian users to set `LANGUAGE' to `nb:no' so that both newer and older translations are used. In the `LANGUAGE' environment variable, but not in the `LANG' environment variable, `LL_CC' combinations can be abbreviated as `LL' to denote the language's main dialect. For example, `de' is equivalent to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT' (Portuguese as spoken in Portugal) in this context. 1.3 Translating Teams ===================== For the Free Translation Project to be a success, we need interested people who like their own language and write it well, and who are also able to synergize with other translators speaking the same language. Each translation team has its own mailing list. The up-to-date list of teams can be found at the Free Translation Project's homepage, `http://translationproject.org/', in the "Teams" area. If you'd like to volunteer to _work_ at translating messages, you should become a member of the translating team for your own language. The subscribing address is _not_ the same as the list itself, it has `-request' appended. For example, speakers of Swedish can send a message to `sv-request@li.org', having this message body: subscribe Keep in mind that team members are expected to participate _actively_ in translations, or at solving translational difficulties, rather than merely lurking around. If your team does not exist yet and you want to start one, or if you are unsure about what to do or how to get started, please write to `coordinator@translationproject.org' to reach the coordinator for all translator teams. The English team is special. It works at improving and uniformizing the terminology in use. Proven linguistic skills are praised more than programming skills, here. 1.4 Available Packages ====================== Languages are not equally supported in all packages. The following matrix shows the current state of internationalization, as of June 2010. The matrix shows, in regard of each package, for which languages PO files have been submitted to translation coordination, with a translation percentage of at least 50%. Ready PO files af am an ar as ast az be be@latin bg bn_IN bs ca +--------------------------------------------------+ a2ps | [] [] | aegis | | ant-phone | | anubis | | aspell | [] [] | bash | | bfd | | bibshelf | [] | binutils | | bison | | bison-runtime | [] | bluez-pin | [] [] | bombono-dvd | | buzztard | | cflow | | clisp | | coreutils | [] [] | cpio | | cppi | | cpplib | [] | cryptsetup | | dfarc | | dialog | [] [] | dico | | diffutils | [] | dink | | doodle | | e2fsprogs | [] | enscript | [] | exif | | fetchmail | [] | findutils | [] | flex | [] | freedink | | gas | | gawk | [] [] | gcal | [] | gcc | | gettext-examples | [] [] [] [] | gettext-runtime | [] [] | gettext-tools | [] [] | gip | [] | gjay | | gliv | [] | glunarclock | [] [] | gnubiff | | gnucash | [] | gnuedu | | gnulib | | gnunet | | gnunet-gtk | | gnutls | | gold | | gpe-aerial | | gpe-beam | | gpe-bluetooth | | gpe-calendar | | gpe-clock | [] | gpe-conf | | gpe-contacts | | gpe-edit | | gpe-filemanager | | gpe-go | | gpe-login | | gpe-ownerinfo | [] | gpe-package | | gpe-sketchbook | | gpe-su | [] | gpe-taskmanager | [] | gpe-timesheet | [] | gpe-today | [] | gpe-todo | | gphoto2 | | gprof | [] | gpsdrive | | gramadoir | | grep | | grub | [] [] | gsasl | | gss | | gst-plugins-bad | [] | gst-plugins-base | [] | gst-plugins-good | [] | gst-plugins-ugly | [] | gstreamer | [] [] [] | gtick | | gtkam | [] | gtkorphan | [] | gtkspell | [] [] [] | gutenprint | | hello | [] | help2man | | hylafax | | idutils | | indent | [] [] | iso_15924 | | iso_3166 | [] [] [] [] [] [] [] | iso_3166_2 | | iso_4217 | | iso_639 | [] [] [] [] | iso_639_3 | | jwhois | | kbd | | keytouch | [] | keytouch-editor | | keytouch-keyboa... | [] | klavaro | [] | latrine | | ld | [] | leafpad | [] [] | libc | [] [] | libexif | () | libextractor | | libgnutls | | libgpewidget | | libgpg-error | | libgphoto2 | | libgphoto2_port | | libgsasl | | libiconv | [] | libidn | | lifelines | | liferea | [] [] | lilypond | | linkdr | [] | lordsawar | | lprng | | lynx | [] | m4 | | mailfromd | | mailutils | | make | | man-db | | man-db-manpages | | minicom | | mkisofs | | myserver | | nano | [] [] | opcodes | | parted | | pies | | popt | | psmisc | | pspp | [] | pwdutils | | radius | [] | recode | [] [] | rosegarden | | rpm | | rush | | sarg | | screem | | scrollkeeper | [] [] [] | sed | [] [] | sharutils | [] [] | shishi | | skencil | | solfege | | solfege-manual | | soundtracker | | sp | | sysstat | | tar | [] | texinfo | | tin | | unicode-han-tra... | | unicode-transla... | | util-linux-ng | [] | vice | | vmm | | vorbis-tools | | wastesedge | | wdiff | | wget | [] [] | wyslij-po | | xchat | [] [] [] [] | xdg-user-dirs | [] [] [] [] [] [] [] [] [] | xkeyboard-config | [] [] | +--------------------------------------------------+ af am an ar as ast az be be@latin bg bn_IN bs ca 6 0 1 2 3 19 1 10 3 28 3 1 38 crh cs da de el en en_GB en_ZA eo es et eu fa +-------------------------------------------------+ a2ps | [] [] [] [] [] [] [] | aegis | [] [] [] | ant-phone | [] () | anubis | [] [] | aspell | [] [] [] [] [] | bash | [] [] [] | bfd | [] | bibshelf | [] [] [] | binutils | [] | bison | [] [] | bison-runtime | [] [] [] [] | bluez-pin | [] [] [] [] [] [] | bombono-dvd | [] | buzztard | [] [] [] | cflow | [] [] | clisp | [] [] [] [] | coreutils | [] [] [] [] | cpio | | cppi | | cpplib | [] [] [] | cryptsetup | [] | dfarc | [] [] [] | dialog | [] [] [] [] [] | dico | | diffutils | [] [] [] [] [] [] | dink | [] [] [] | doodle | [] | e2fsprogs | [] [] [] | enscript | [] [] [] | exif | () [] [] | fetchmail | [] [] () [] [] [] | findutils | [] [] [] | flex | [] [] | freedink | [] [] [] | gas | [] | gawk | [] [] [] | gcal | [] | gcc | [] [] | gettext-examples | [] [] [] [] | gettext-runtime | [] [] [] [] | gettext-tools | [] [] [] | gip | [] [] [] [] | gjay | [] | gliv | [] [] [] | glunarclock | [] [] | gnubiff | () | gnucash | [] () () () () | gnuedu | [] [] | gnulib | [] [] | gnunet | | gnunet-gtk | [] | gnutls | [] [] | gold | [] | gpe-aerial | [] [] [] [] | gpe-beam | [] [] [] [] | gpe-bluetooth | [] [] | gpe-calendar | [] | gpe-clock | [] [] [] [] | gpe-conf | [] [] [] | gpe-contacts | [] [] [] | gpe-edit | [] [] | gpe-filemanager | [] [] [] | gpe-go | [] [] [] [] | gpe-login | [] [] | gpe-ownerinfo | [] [] [] [] | gpe-package | [] [] [] | gpe-sketchbook | [] [] [] [] | gpe-su | [] [] [] [] | gpe-taskmanager | [] [] [] [] | gpe-timesheet | [] [] [] [] | gpe-today | [] [] [] [] | gpe-todo | [] [] [] | gphoto2 | [] [] () [] [] [] | gprof | [] [] [] | gpsdrive | [] [] [] | gramadoir | [] [] [] | grep | [] | grub | [] [] | gsasl | [] | gss | | gst-plugins-bad | [] [] [] [] [] | gst-plugins-base | [] [] [] [] [] | gst-plugins-good | [] [] [] [] [] [] | gst-plugins-ugly | [] [] [] [] [] [] | gstreamer | [] [] [] [] [] | gtick | [] () [] | gtkam | [] [] () [] [] | gtkorphan | [] [] [] [] | gtkspell | [] [] [] [] [] [] [] | gutenprint | [] [] [] | hello | [] [] [] [] | help2man | [] | hylafax | [] [] | idutils | [] [] | indent | [] [] [] [] [] [] [] | iso_15924 | [] () [] [] | iso_3166 | [] [] [] [] () [] [] [] () | iso_3166_2 | () | iso_4217 | [] [] [] () [] [] | iso_639 | [] [] [] [] () [] [] | iso_639_3 | [] | jwhois | [] | kbd | [] [] [] [] [] | keytouch | [] [] | keytouch-editor | [] [] | keytouch-keyboa... | [] | klavaro | [] [] [] [] | latrine | [] () | ld | [] [] | leafpad | [] [] [] [] [] [] | libc | [] [] [] [] | libexif | [] [] () | libextractor | | libgnutls | [] | libgpewidget | [] [] | libgpg-error | [] [] | libgphoto2 | [] () | libgphoto2_port | [] () [] | libgsasl | | libiconv | [] [] [] [] [] | libidn | [] [] [] | lifelines | [] () | liferea | [] [] [] [] [] | lilypond | [] [] [] | linkdr | [] [] [] | lordsawar | [] | lprng | | lynx | [] [] [] [] | m4 | [] [] [] [] | mailfromd | | mailutils | [] | make | [] [] [] | man-db | | man-db-manpages | | minicom | [] [] [] [] | mkisofs | | myserver | | nano | [] [] [] | opcodes | [] [] | parted | [] [] | pies | | popt | [] [] [] [] [] | psmisc | [] [] [] | pspp | [] | pwdutils | [] | radius | [] | recode | [] [] [] [] [] [] | rosegarden | () () () | rpm | [] [] [] | rush | | sarg | | screem | | scrollkeeper | [] [] [] [] [] | sed | [] [] [] [] [] [] | sharutils | [] [] [] [] | shishi | | skencil | [] () [] | solfege | [] [] [] | solfege-manual | [] [] | soundtracker | [] [] [] | sp | [] | sysstat | [] [] [] | tar | [] [] [] [] | texinfo | [] [] [] | tin | [] [] | unicode-han-tra... | | unicode-transla... | | util-linux-ng | [] [] [] [] | vice | () () | vmm | [] | vorbis-tools | [] [] | wastesedge | [] | wdiff | [] [] | wget | [] [] [] | wyslij-po | | xchat | [] [] [] [] [] | xdg-user-dirs | [] [] [] [] [] [] [] [] [] | xkeyboard-config | [] [] [] [] [] [] | +-------------------------------------------------+ crh cs da de el en en_GB en_ZA eo es et eu fa 5 64 105 117 18 1 8 0 28 89 18 19 0 fi fr ga gl gu he hi hr hu hy id is it ja ka kn +----------------------------------------------------+ a2ps | [] [] [] [] | aegis | [] [] | ant-phone | [] [] | anubis | [] [] [] [] | aspell | [] [] [] [] | bash | [] [] [] [] | bfd | [] [] [] | bibshelf | [] [] [] [] [] | binutils | [] [] [] | bison | [] [] [] [] | bison-runtime | [] [] [] [] [] [] | bluez-pin | [] [] [] [] [] [] [] [] | bombono-dvd | [] | buzztard | [] | cflow | [] [] [] | clisp | [] | coreutils | [] [] [] [] [] | cpio | [] [] [] [] | cppi | [] [] | cpplib | [] [] [] | cryptsetup | [] [] [] | dfarc | [] [] [] | dialog | [] [] [] [] [] [] [] | dico | | diffutils | [] [] [] [] [] [] [] [] [] | dink | [] | doodle | [] [] | e2fsprogs | [] [] | enscript | [] [] [] [] | exif | [] [] [] [] [] [] | fetchmail | [] [] [] [] | findutils | [] [] [] [] [] [] | flex | [] [] [] | freedink | [] [] [] | gas | [] [] | gawk | [] [] [] [] () [] | gcal | [] | gcc | [] | gettext-examples | [] [] [] [] [] [] [] | gettext-runtime | [] [] [] [] [] [] | gettext-tools | [] [] [] [] | gip | [] [] [] [] [] [] | gjay | [] | gliv | [] () | glunarclock | [] [] [] [] | gnubiff | () [] () | gnucash | () () () () () [] | gnuedu | [] [] | gnulib | [] [] [] [] [] [] | gnunet | | gnunet-gtk | [] | gnutls | [] [] | gold | [] [] | gpe-aerial | [] [] [] | gpe-beam | [] [] [] [] | gpe-bluetooth | [] [] [] [] | gpe-calendar | [] [] | gpe-clock | [] [] [] [] [] | gpe-conf | [] [] [] [] | gpe-contacts | [] [] [] [] | gpe-edit | [] [] [] | gpe-filemanager | [] [] [] [] | gpe-go | [] [] [] [] [] | gpe-login | [] [] [] | gpe-ownerinfo | [] [] [] [] [] | gpe-package | [] [] [] | gpe-sketchbook | [] [] [] [] | gpe-su | [] [] [] [] [] [] | gpe-taskmanager | [] [] [] [] [] | gpe-timesheet | [] [] [] [] [] | gpe-today | [] [] [] [] [] [] [] | gpe-todo | [] [] [] | gphoto2 | [] [] [] [] [] [] | gprof | [] [] [] [] | gpsdrive | [] [] [] | gramadoir | [] [] [] | grep | [] [] | grub | [] [] [] [] | gsasl | [] [] [] [] [] | gss | [] [] [] [] [] | gst-plugins-bad | [] [] [] [] [] [] | gst-plugins-base | [] [] [] [] [] [] | gst-plugins-good | [] [] [] [] [] [] | gst-plugins-ugly | [] [] [] [] [] [] | gstreamer | [] [] [] [] [] | gtick | [] [] [] [] [] | gtkam | [] [] [] [] [] | gtkorphan | [] [] [] | gtkspell | [] [] [] [] [] [] [] [] [] | gutenprint | [] [] [] [] | hello | [] [] [] | help2man | [] [] | hylafax | [] | idutils | [] [] [] [] [] [] | indent | [] [] [] [] [] [] [] [] | iso_15924 | [] () [] [] | iso_3166 | [] () [] [] [] [] [] [] [] [] [] [] | iso_3166_2 | () [] [] [] | iso_4217 | [] () [] [] [] [] | iso_639 | [] () [] [] [] [] [] [] [] | iso_639_3 | () [] [] | jwhois | [] [] [] [] [] | kbd | [] [] | keytouch | [] [] [] [] [] [] | keytouch-editor | [] [] [] [] [] | keytouch-keyboa... | [] [] [] [] [] | klavaro | [] [] | latrine | [] [] [] | ld | [] [] [] [] | leafpad | [] [] [] [] [] [] [] () | libc | [] [] [] [] [] | libexif | [] | libextractor | | libgnutls | [] [] | libgpewidget | [] [] [] [] | libgpg-error | [] [] | libgphoto2 | [] [] [] | libgphoto2_port | [] [] [] | libgsasl | [] [] [] [] [] | libiconv | [] [] [] [] [] [] | libidn | [] [] [] [] | lifelines | () | liferea | [] [] [] [] | lilypond | [] [] | linkdr | [] [] [] [] [] | lordsawar | | lprng | [] | lynx | [] [] [] [] [] | m4 | [] [] [] [] [] [] | mailfromd | | mailutils | [] [] | make | [] [] [] [] [] [] [] [] [] | man-db | [] [] | man-db-manpages | [] | minicom | [] [] [] [] [] | mkisofs | [] [] [] [] | myserver | | nano | [] [] [] [] [] [] | opcodes | [] [] [] [] | parted | [] [] [] [] | pies | | popt | [] [] [] [] [] [] [] [] [] | psmisc | [] [] [] | pspp | | pwdutils | [] [] | radius | [] [] | recode | [] [] [] [] [] [] [] [] | rosegarden | () () () () () | rpm | [] [] | rush | | sarg | [] | screem | [] [] | scrollkeeper | [] [] [] [] | sed | [] [] [] [] [] [] [] [] | sharutils | [] [] [] [] [] [] [] | shishi | [] | skencil | [] | solfege | [] [] [] [] | solfege-manual | [] [] | soundtracker | [] [] | sp | [] () | sysstat | [] [] [] [] [] | tar | [] [] [] [] [] [] [] | texinfo | [] [] [] [] | tin | [] | unicode-han-tra... | | unicode-transla... | [] [] | util-linux-ng | [] [] [] [] [] [] | vice | () () () | vmm | [] | vorbis-tools | [] | wastesedge | () () | wdiff | [] | wget | [] [] [] [] [] [] [] [] | wyslij-po | [] [] [] | xchat | [] [] [] [] [] [] [] [] [] | xdg-user-dirs | [] [] [] [] [] [] [] [] [] [] [] [] [] | xkeyboard-config | [] [] [] [] [] | +----------------------------------------------------+ fi fr ga gl gu he hi hr hu hy id is it ja ka kn 105 121 53 20 4 8 3 5 53 2 120 5 84 67 0 4 ko ku ky lg lt lv mk ml mn mr ms mt nb nds ne +-----------------------------------------------+ a2ps | [] | aegis | | ant-phone | | anubis | [] [] | aspell | [] | bash | | bfd | | bibshelf | [] [] | binutils | | bison | [] | bison-runtime | [] [] [] [] [] | bluez-pin | [] [] [] [] [] | bombono-dvd | | buzztard | | cflow | | clisp | | coreutils | [] | cpio | | cppi | | cpplib | | cryptsetup | | dfarc | [] | dialog | [] [] [] [] [] | dico | | diffutils | [] [] | dink | | doodle | | e2fsprogs | | enscript | | exif | [] | fetchmail | | findutils | | flex | | freedink | [] | gas | | gawk | | gcal | | gcc | | gettext-examples | [] [] [] [] | gettext-runtime | [] | gettext-tools | [] | gip | [] [] | gjay | | gliv | | glunarclock | [] | gnubiff | | gnucash | () () () () | gnuedu | | gnulib | | gnunet | | gnunet-gtk | | gnutls | [] | gold | | gpe-aerial | [] | gpe-beam | [] | gpe-bluetooth | [] [] | gpe-calendar | [] | gpe-clock | [] [] [] [] [] | gpe-conf | [] [] | gpe-contacts | [] [] | gpe-edit | [] | gpe-filemanager | [] [] | gpe-go | [] [] [] | gpe-login | [] | gpe-ownerinfo | [] [] | gpe-package | [] [] | gpe-sketchbook | [] [] | gpe-su | [] [] [] [] [] [] | gpe-taskmanager | [] [] [] [] [] [] | gpe-timesheet | [] [] | gpe-today | [] [] [] [] | gpe-todo | [] [] | gphoto2 | | gprof | [] | gpsdrive | | gramadoir | | grep | | grub | | gsasl | | gss | | gst-plugins-bad | [] [] [] [] | gst-plugins-base | [] [] | gst-plugins-good | [] [] | gst-plugins-ugly | [] [] [] [] [] | gstreamer | | gtick | | gtkam | [] | gtkorphan | [] [] | gtkspell | [] [] [] [] [] [] [] | gutenprint | | hello | [] [] [] | help2man | | hylafax | | idutils | | indent | | iso_15924 | [] [] | iso_3166 | [] [] () [] [] [] [] [] | iso_3166_2 | | iso_4217 | [] [] | iso_639 | [] [] | iso_639_3 | [] | jwhois | [] | kbd | | keytouch | [] | keytouch-editor | [] | keytouch-keyboa... | [] | klavaro | [] | latrine | [] | ld | | leafpad | [] [] [] | libc | [] | libexif | | libextractor | | libgnutls | [] | libgpewidget | [] [] | libgpg-error | | libgphoto2 | | libgphoto2_port | | libgsasl | | libiconv | | libidn | | lifelines | | liferea | | lilypond | | linkdr | | lordsawar | | lprng | | lynx | | m4 | | mailfromd | | mailutils | | make | [] | man-db | | man-db-manpages | | minicom | [] | mkisofs | | myserver | | nano | [] [] | opcodes | | parted | | pies | | popt | [] [] [] | psmisc | | pspp | | pwdutils | | radius | | recode | | rosegarden | | rpm | | rush | | sarg | | screem | | scrollkeeper | [] [] | sed | | sharutils | | shishi | | skencil | | solfege | [] | solfege-manual | | soundtracker | | sp | | sysstat | [] | tar | [] | texinfo | [] | tin | | unicode-han-tra... | | unicode-transla... | | util-linux-ng | | vice | | vmm | | vorbis-tools | | wastesedge | | wdiff | | wget | [] | wyslij-po | | xchat | [] [] [] | xdg-user-dirs | [] [] [] [] [] [] [] [] | xkeyboard-config | [] [] [] | +-----------------------------------------------+ ko ku ky lg lt lv mk ml mn mr ms mt nb nds ne 20 5 10 1 13 48 4 2 2 4 24 10 20 3 1 nl nn or pa pl ps pt pt_BR ro ru rw sk sl sq sr +---------------------------------------------------+ a2ps | [] [] [] [] [] [] [] [] | aegis | [] [] [] | ant-phone | [] [] | anubis | [] [] [] | aspell | [] [] [] [] [] | bash | [] [] | bfd | [] | bibshelf | [] [] | binutils | [] [] | bison | [] [] [] | bison-runtime | [] [] [] [] [] [] [] | bluez-pin | [] [] [] [] [] [] [] [] | bombono-dvd | [] () | buzztard | [] [] | cflow | [] | clisp | [] [] | coreutils | [] [] [] [] [] [] | cpio | [] [] [] | cppi | [] | cpplib | [] | cryptsetup | [] | dfarc | [] | dialog | [] [] [] [] | dico | [] | diffutils | [] [] [] [] [] [] | dink | () | doodle | [] [] | e2fsprogs | [] [] | enscript | [] [] [] [] [] | exif | [] [] [] () [] | fetchmail | [] [] [] [] | findutils | [] [] [] [] [] | flex | [] [] [] [] [] | freedink | [] [] | gas | | gawk | [] [] [] [] | gcal | | gcc | [] | gettext-examples | [] [] [] [] [] [] [] [] | gettext-runtime | [] [] [] [] [] [] [] [] [] | gettext-tools | [] [] [] [] [] [] | gip | [] [] [] [] [] | gjay | | gliv | [] [] [] [] [] [] | glunarclock | [] [] [] [] [] | gnubiff | [] () | gnucash | [] () () () | gnuedu | [] | gnulib | [] [] [] [] | gnunet | | gnunet-gtk | | gnutls | [] [] | gold | | gpe-aerial | [] [] [] [] [] [] [] | gpe-beam | [] [] [] [] [] [] [] | gpe-bluetooth | [] [] | gpe-calendar | [] [] [] [] | gpe-clock | [] [] [] [] [] [] [] [] | gpe-conf | [] [] [] [] [] [] [] | gpe-contacts | [] [] [] [] [] | gpe-edit | [] [] [] | gpe-filemanager | [] [] [] | gpe-go | [] [] [] [] [] [] [] [] | gpe-login | [] [] | gpe-ownerinfo | [] [] [] [] [] [] [] [] | gpe-package | [] [] | gpe-sketchbook | [] [] [] [] [] [] [] | gpe-su | [] [] [] [] [] [] [] [] | gpe-taskmanager | [] [] [] [] [] [] [] [] | gpe-timesheet | [] [] [] [] [] [] [] [] | gpe-today | [] [] [] [] [] [] [] [] | gpe-todo | [] [] [] [] [] | gphoto2 | [] [] [] [] [] [] [] [] | gprof | [] [] [] | gpsdrive | [] [] | gramadoir | [] [] | grep | [] [] [] [] | grub | [] [] [] | gsasl | [] [] [] [] | gss | [] [] [] | gst-plugins-bad | [] [] [] [] [] [] | gst-plugins-base | [] [] [] [] [] | gst-plugins-good | [] [] [] [] [] | gst-plugins-ugly | [] [] [] [] [] [] | gstreamer | [] [] [] [] [] | gtick | [] [] [] | gtkam | [] [] [] [] [] [] | gtkorphan | [] | gtkspell | [] [] [] [] [] [] [] [] [] [] | gutenprint | [] [] | hello | [] [] [] [] | help2man | [] [] | hylafax | [] | idutils | [] [] [] [] [] | indent | [] [] [] [] [] [] [] | iso_15924 | [] [] [] [] | iso_3166 | [] [] [] [] [] () [] [] [] [] [] [] [] [] | iso_3166_2 | [] [] [] | iso_4217 | [] [] [] [] [] [] [] [] | iso_639 | [] [] [] [] [] [] [] [] [] | iso_639_3 | [] [] | jwhois | [] [] [] [] | kbd | [] [] [] | keytouch | [] [] [] | keytouch-editor | [] [] [] | keytouch-keyboa... | [] [] [] | klavaro | [] [] | latrine | [] [] | ld | | leafpad | [] [] [] [] [] [] [] [] [] | libc | [] [] [] [] | libexif | [] [] () [] | libextractor | | libgnutls | [] [] | libgpewidget | [] [] [] | libgpg-error | [] [] | libgphoto2 | [] [] | libgphoto2_port | [] [] [] [] [] | libgsasl | [] [] [] [] [] | libiconv | [] [] [] [] [] | libidn | [] [] | lifelines | [] [] | liferea | [] [] [] [] [] () () [] | lilypond | [] | linkdr | [] [] [] | lordsawar | | lprng | [] | lynx | [] [] [] | m4 | [] [] [] [] [] | mailfromd | [] | mailutils | [] | make | [] [] [] [] | man-db | [] [] [] | man-db-manpages | [] [] [] | minicom | [] [] [] [] | mkisofs | [] [] [] | myserver | | nano | [] [] [] [] | opcodes | [] [] | parted | [] [] [] [] | pies | [] | popt | [] [] [] [] | psmisc | [] [] [] | pspp | [] [] | pwdutils | [] | radius | [] [] [] | recode | [] [] [] [] [] [] [] [] | rosegarden | () () | rpm | [] [] [] | rush | [] [] | sarg | | screem | | scrollkeeper | [] [] [] [] [] [] [] [] | sed | [] [] [] [] [] [] [] [] [] | sharutils | [] [] [] [] | shishi | [] | skencil | [] [] | solfege | [] [] [] [] | solfege-manual | [] [] [] | soundtracker | [] | sp | | sysstat | [] [] [] [] | tar | [] [] [] [] | texinfo | [] [] [] [] | tin | [] | unicode-han-tra... | | unicode-transla... | | util-linux-ng | [] [] [] [] [] | vice | [] | vmm | [] | vorbis-tools | [] [] | wastesedge | [] | wdiff | [] [] | wget | [] [] [] [] [] [] [] | wyslij-po | [] [] [] | xchat | [] [] [] [] [] [] [] [] [] | xdg-user-dirs | [] [] [] [] [] [] [] [] [] [] [] [] [] [] | xkeyboard-config | [] [] [] | +---------------------------------------------------+ nl nn or pa pl ps pt pt_BR ro ru rw sk sl sq sr 135 10 4 7 105 1 29 62 47 91 3 54 46 9 37 sv sw ta te tg th tr uk vi wa zh_CN zh_HK zh_TW +---------------------------------------------------+ a2ps | [] [] [] [] [] | 27 aegis | [] | 9 ant-phone | [] [] [] [] | 9 anubis | [] [] [] [] | 15 aspell | [] [] [] | 20 bash | [] [] [] | 12 bfd | [] | 6 bibshelf | [] [] [] | 16 binutils | [] [] | 8 bison | [] [] | 12 bison-runtime | [] [] [] [] [] [] | 29 bluez-pin | [] [] [] [] [] [] [] [] | 37 bombono-dvd | [] | 4 buzztard | [] | 7 cflow | [] [] [] | 9 clisp | | 10 coreutils | [] [] [] [] | 22 cpio | [] [] [] [] [] [] | 13 cppi | [] [] | 5 cpplib | [] [] [] [] [] [] | 14 cryptsetup | [] [] | 7 dfarc | [] | 9 dialog | [] [] [] [] [] [] [] | 30 dico | [] | 2 diffutils | [] [] [] [] [] [] | 30 dink | | 4 doodle | [] [] | 7 e2fsprogs | [] [] [] | 11 enscript | [] [] [] [] | 17 exif | [] [] [] | 16 fetchmail | [] [] [] | 17 findutils | [] [] [] [] [] | 20 flex | [] [] [] [] | 15 freedink | [] | 10 gas | [] | 4 gawk | [] [] [] [] | 18 gcal | [] [] | 5 gcc | [] [] [] | 7 gettext-examples | [] [] [] [] [] [] [] | 34 gettext-runtime | [] [] [] [] [] [] [] | 29 gettext-tools | [] [] [] [] [] [] | 22 gip | [] [] [] [] | 22 gjay | [] | 3 gliv | [] [] [] | 14 glunarclock | [] [] [] [] [] | 19 gnubiff | [] [] | 4 gnucash | () [] () [] () | 10 gnuedu | [] [] | 7 gnulib | [] [] [] [] | 16 gnunet | [] | 1 gnunet-gtk | [] [] [] | 5 gnutls | [] [] [] | 10 gold | [] | 4 gpe-aerial | [] [] [] | 18 gpe-beam | [] [] [] | 19 gpe-bluetooth | [] [] [] | 13 gpe-calendar | [] [] [] [] | 12 gpe-clock | [] [] [] [] [] | 28 gpe-conf | [] [] [] [] | 20 gpe-contacts | [] [] [] | 17 gpe-edit | [] [] [] | 12 gpe-filemanager | [] [] [] [] | 16 gpe-go | [] [] [] [] [] | 25 gpe-login | [] [] [] | 11 gpe-ownerinfo | [] [] [] [] [] | 25 gpe-package | [] [] [] | 13 gpe-sketchbook | [] [] [] | 20 gpe-su | [] [] [] [] [] | 30 gpe-taskmanager | [] [] [] [] [] | 29 gpe-timesheet | [] [] [] [] [] | 25 gpe-today | [] [] [] [] [] [] | 30 gpe-todo | [] [] [] [] | 17 gphoto2 | [] [] [] [] [] | 24 gprof | [] [] [] | 15 gpsdrive | [] [] [] | 11 gramadoir | [] [] [] | 11 grep | [] [] [] | 10 grub | [] [] [] | 14 gsasl | [] [] [] [] | 14 gss | [] [] [] | 11 gst-plugins-bad | [] [] [] [] | 26 gst-plugins-base | [] [] [] [] [] | 24 gst-plugins-good | [] [] [] [] | 24 gst-plugins-ugly | [] [] [] [] [] | 29 gstreamer | [] [] [] [] | 22 gtick | [] [] [] | 13 gtkam | [] [] [] | 20 gtkorphan | [] [] [] | 14 gtkspell | [] [] [] [] [] [] [] [] [] | 45 gutenprint | [] | 10 hello | [] [] [] [] [] [] | 21 help2man | [] [] | 7 hylafax | [] | 5 idutils | [] [] [] [] | 17 indent | [] [] [] [] [] [] | 30 iso_15924 | () [] () [] [] | 16 iso_3166 | [] [] () [] [] () [] [] [] () | 53 iso_3166_2 | () [] () [] | 9 iso_4217 | [] () [] [] () [] [] | 26 iso_639 | [] [] [] () [] () [] [] [] [] | 38 iso_639_3 | [] () | 8 jwhois | [] [] [] [] [] | 16 kbd | [] [] [] [] [] | 15 keytouch | [] [] [] | 16 keytouch-editor | [] [] [] | 14 keytouch-keyboa... | [] [] [] | 14 klavaro | [] | 11 latrine | [] [] [] | 10 ld | [] [] [] [] | 11 leafpad | [] [] [] [] [] [] | 33 libc | [] [] [] [] [] | 21 libexif | [] () | 7 libextractor | [] | 1 libgnutls | [] [] [] | 9 libgpewidget | [] [] [] | 14 libgpg-error | [] [] [] | 9 libgphoto2 | [] [] | 8 libgphoto2_port | [] [] [] [] | 14 libgsasl | [] [] [] | 13 libiconv | [] [] [] [] | 21 libidn | () [] [] | 11 lifelines | [] | 4 liferea | [] [] [] | 21 lilypond | [] | 7 linkdr | [] [] [] [] [] | 17 lordsawar | | 1 lprng | [] | 3 lynx | [] [] [] [] | 17 m4 | [] [] [] [] | 19 mailfromd | [] [] | 3 mailutils | [] | 5 make | [] [] [] [] | 21 man-db | [] [] [] | 8 man-db-manpages | | 4 minicom | [] [] | 16 mkisofs | [] [] | 9 myserver | | 0 nano | [] [] [] [] | 21 opcodes | [] [] [] | 11 parted | [] [] [] [] [] | 15 pies | [] [] | 3 popt | [] [] [] [] [] [] | 27 psmisc | [] [] | 11 pspp | | 4 pwdutils | [] [] | 6 radius | [] [] | 9 recode | [] [] [] [] | 28 rosegarden | () | 0 rpm | [] [] [] | 11 rush | [] [] | 4 sarg | | 1 screem | [] | 3 scrollkeeper | [] [] [] [] [] | 27 sed | [] [] [] [] [] | 30 sharutils | [] [] [] [] [] | 22 shishi | [] | 3 skencil | [] [] | 7 solfege | [] [] [] [] | 16 solfege-manual | [] | 8 soundtracker | [] [] [] | 9 sp | [] | 3 sysstat | [] [] | 15 tar | [] [] [] [] [] [] | 23 texinfo | [] [] [] [] [] | 17 tin | | 4 unicode-han-tra... | | 0 unicode-transla... | | 2 util-linux-ng | [] [] [] [] | 20 vice | () () | 1 vmm | [] | 4 vorbis-tools | [] | 6 wastesedge | | 2 wdiff | [] [] | 7 wget | [] [] [] [] [] | 26 wyslij-po | [] [] | 8 xchat | [] [] [] [] [] [] | 36 xdg-user-dirs | [] [] [] [] [] [] [] [] [] [] | 63 xkeyboard-config | [] [] [] | 22 +---------------------------------------------------+ 85 teams sv sw ta te tg th tr uk vi wa zh_CN zh_HK zh_TW 178 domains 119 1 3 3 0 10 65 51 155 17 98 7 41 2618 Some counters in the preceding matrix are higher than the number of visible blocks let us expect. This is because a few extra PO files are used for implementing regional variants of languages, or language dialects. For a PO file in the matrix above to be effective, the package to which it applies should also have been internationalized and distributed as such by its maintainer. There might be an observable lag between the mere existence a PO file and its wide availability in a distribution. If June 2010 seems to be old, you may fetch a more recent copy of this `ABOUT-NLS' file on most GNU archive sites. The most up-to-date matrix with full percentage details can be found at `http://translationproject.org/extra/matrix.html'. 1.5 Using `gettext' in new packages =================================== If you are writing a freely available program and want to internationalize it you are welcome to use GNU `gettext' in your package. Of course you have to respect the GNU Library General Public License which covers the use of the GNU `gettext' library. This means in particular that even non-free programs can use `libintl' as a shared library, whereas only free software can use `libintl' as a static library or use modified versions of `libintl'. Once the sources are changed appropriately and the setup can handle the use of `gettext' the only thing missing are the translations. The Free Translation Project is also available for packages which are not developed inside the GNU project. Therefore the information given above applies also for every other Free Software Project. Contact `coordinator@translationproject.org' to make the `.pot' files available to the translation teams. libbytesize-2.2/HACKING.md000066400000000000000000000022071361502636100152740ustar00rootroot00000000000000CODING STYLE ============ - Please follow the coding style already used. - Spaces, not tabs, are used (except for Makefiles). MAKING RELEASES =============== - [ ] ``sudo git clean -xdf`` - [ ] ``./autogen.sh && ./configure`` - [ ] ``make bumpver`` - [ ] Add a new entry to the *NEWS.rst* file (full list of changes should be generated with ``make shortlog``). - [ ] Regenerate the bscalc.man manpage by installing bscalc and then running ``help2man -N bscalc > PATH_TO_LIBBYTESIZE/tools/bscalc.man``. - [ ] Commit all the changes as *New version - $VERSION*. - [ ] ``make release`` (requires a GPG key to sign the tag) - [ ] ``git push && git push --tags`` - [ ] Edit the new release (for the new tag) at GitHub and: - [ ] add some detailed information about it (from the *NEWS.rst*) file to it, - [ ] upload the tarball created above (``make release``) to the release. - [ ] Update the documentation by rsyncing the contents of the *docs/html* folder elsewhere, switching to the *gh-pages* branch, rsyncing the contents back and commiting it as an update of the docs for the new release. libbytesize-2.2/LICENSE000066400000000000000000000635201361502636100147200ustar00rootroot00000000000000 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!libbytesize-2.2/Makefile.am000066400000000000000000000103021361502636100157350ustar00rootroot00000000000000ACLOCAL_AMFLAGS = -I m4 DISTCHECK_CONFIGURE_FLAGS = --enable-introspection SUBDIRS = . po src dist tests if WITH_GTK_DOC SUBDIRS += docs endif if WITH_TOOLS SUBDIRS += tools endif dist_noinst_DATA = LICENSE README.md MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess config.sub \ configure depcomp install-sh ltmain.sh missing py-compile compile ar-lib \ m4/*.m4 LIBDIRS = src/.libs PYTHONDIR = src/python TEST_PYTHON ?= $(PYTHON) ZANATA_PULL_ARGS = --transdir ./po/ ZANATA_PUSH_ARGS = --srcdir ./po/ --push-type source --force TEST_DEPENDENCIES = $(shell rpm --specfile dist/libbytesize.spec --requires | cut -d' ' -f1 | grep -v ^libbytesize) TEST_DEPENDENCIES += gmp gmp-devel TEST_DEPENDENCIES += mpfr mpfr-devel TEST_DEPENDENCIES += pcre2 pcre2-devel # If translations are present, run tests on the .po files before tarring them # up to remove any .po files with errors. Use a weird looking loop since shell # doesn't have a good way to test for a wildcard. dist-hook: for p in $(distdir)/po/*.po ; do \ if [ -e "$$p" ]; then \ PYTHONPATH=$(srcdir)/translation-canary python3 -m translation_canary.translated \ --release $(distdir)/po ; \ fi ; \ break ; \ done run-ipython: all LD_LIBRARY_PATH=${LIBDIRS} PYTHONPATH=$(PYTHONDIR) ipython3 check-requires: @echo "*** Checking if the dependencies required for testing and analysis are available ***" @status=0 ; \ for pkg in $(TEST_DEPENDENCIES) ; do \ test_output="$$(rpm -q --whatprovides "$$pkg")" ; \ if [ $$? != 0 ]; then \ echo "$$test_output" ; \ status=1 ; \ fi ; \ done ; \ exit $$status install-requires: @echo "*** Installing the dependencies required for testing and analysis ***" dnf install -y $(TEST_DEPENDENCIES) test: $(MAKE) check ci: $(MAKE) distcheck; \ status="$$?" ; \ find . -name 'test-suite.log' -exec cat '{}' \; ; \ test "$$status" = "0" po-pull: @which zanata >/dev/null 2>&1 || ( echo "You need to install Zanata client to download translation files"; exit 1 ) zanata pull $(ZANATA_PULL_ARGS) tag: @TAG="$(PACKAGE_VERSION)" ; \ git tag -a -s -m "Tag as $$TAG" -f "$$TAG" && \ echo "Tagged as $$TAG" rpmlog: @cl=`grep -n %changelog dist/libbytesize.spec.in |cut -d : -f 1` ; \ version_release=`tail --lines=+$$(($$cl + 1)) dist/libbytesize.spec.in|head -1|cut -d- -f2-3|sed 's/ //g'|sed -r 's/-[0-9]+//'` ; \ git log --no-merges --pretty="format:- %s (%ae)" "$$version_release.." |sed -e 's/@.*)/)/' ; \ echo shortlog: git shortlog -r --no-merges --format="- %s" -w76,0,2 $$(git tag -l | grep '^[0-9]' | tail -n 1)..HEAD | sed 's/"):$"/"):\n"/g' bumpver: @VERSION=`echo $(PACKAGE_VERSION)|sed -r 's/(.*)\.([0-9]+)/\1/'` ; \ SUBVERSION=`echo $(PACKAGE_VERSION)|sed -r 's/.*\.([0-9]+)/\1/'` ; \ NEWSUBVERSION=$$(($$SUBVERSION + 1)) ; \ DATELINE="* `date "+%a %b %d %Y"` `git config user.name` <`git config user.email`> - $$VERSION.$$NEWSUBVERSION-1" ; \ cl=`grep -n %changelog dist/libbytesize.spec.in |cut -d : -f 1` ; \ tail --lines=+$$(($$cl + 1)) dist/libbytesize.spec.in > speclog ; \ (head -n $$cl dist/libbytesize.spec.in ; echo "$$DATELINE" ; make --quiet rpmlog 2>/dev/null ; echo ""; cat speclog) > dist/libbytesize.spec.in.new ; \ mv dist/libbytesize.spec.in.new dist/libbytesize.spec.in ; rm -f speclog ; \ sed -ri "s/(AC_INIT\(\[$(PACKAGE_NAME)\], \[)[0-9]+\.[0-9]+(\],.*)/\1$$VERSION.$$NEWSUBVERSION\2/" configure.ac ; \ sed -ri "s/Version:(\\s+)[-0-9.]+/Version:\\1$$VERSION.$$NEWSUBVERSION/" dist/libbytesize.spec.in ; $(MAKE) -C po/ $(PACKAGE_NAME).pot-update archive: po-pull $(MAKE) distcheck local: all [ -f ./po/en_US.po ] || msginit -i ./po/$(PACKAGE_NAME).pot -o ./po/en_US.po --no-translator $(MAKE) dist srpm: local rpmbuild -ts --nodeps $(PACKAGE_NAME)-$(PACKAGE_VERSION).tar.gz rm -f $(PACKAGE_NAME)-$(PACKAGE_VERSION).tar.gz rpm: local rpmbuild -tb --nodeps $(PACKAGE_NAME)-$(PACKAGE_VERSION).tar.gz rm -f $(PACKAGE_NAME)-$(PACKAGE_VERSION).tar.gz release: tag $(MAKE) archive $(MAKE) -C po/ $(PACKAGE_NAME).pot-update zanata push $(ZANATA_PUSH_ARGS) EXTRA_DIST = config.rpath # Include the xgettext wrapper so pot-update can be run from the source distribution # This is needed for make distcheck. EXTRA_DIST += $(srcdir)/translation-canary/xgettext_werror.sh libbytesize-2.2/NEWS.rst000066400000000000000000000124471361502636100152230ustar00rootroot00000000000000Libbytesize 2.2 --------------- Giulio Benetti (1): - src/gettext: fix warning if gettext is already present Tim Biermann (1): - fix build on shells where test == fails Vojtech Trefny (2): - Add POT file to git and do not rebuild it during every build - New version - 2.2 Vratislav Podzimek (2): - Update README.md - Require the same version of python3-bytesize in libbytesize-tools Libbytesize 2.1 --------------- New minor release of the libbytesize library. There are only two bugfixes in this release. **Full list of changes** Hongxu Jia (1): - fix out of tree build failure Vojtech Trefny (1): - Fix return value for round_to_nearest when using Size Libbytesize 2.0 --------------- New major release of the libbytesize library. There are no API or ABI changes but we made some changes in dependencies and behavior. **Notable changes** - New bytesize calculator `bssize` has been added. - Code has been ported from PCRE to PCRE2. - Python 2 support has been removed. **Full list of changes** Vojtech Trefny (5): - Run all libbytesize tests from one script - Add all "public" python API symbols to __init__.py - Allow running tests using installed library - Remove Python 2 support - Port to pcre2 Vratislav Podzimek (10): - Add support for floor division by a non-integer number in Python - Add a simple bytesize calculator tool - Add tools to autotools and packaging - Exit with 1 from configure if there were failures - Add a summary to the end of ./configure output - Only support modulo between two Size instances - Fix parsing of exponential representations of real numbers - Add the '--version' option to bs_calc.py - Add a man page for the bscalc tool - Assume the given expression is in bytes if no unit is given Libbytesize 1.4 --------------- New minor release of the libbytesize library. There are only small changes in this release. **Full list of changes** Vojtech Trefny (6): - Use new ldconfig_scriptlets macro in spec - Do not use rpm to check for Zanata client - Fix licence header for "gettext.h" - Do not try to run python2 tests without python2 support - Make sure the test script fails if one of the test runs fail - Squashed 'translation-canary/' changes from 840c2d6..fccbb1b Thanks to all our contributors. Vojtech Trefny, 2018-08-02 Libbytesize 1.3 --------------- New minor release of the libbytesize library. There are only small changes in this release. Most notable change is new configure option `--without-python2` that allows building libbytesize without Python 2 support. **Full list of changes** Vojtech Trefny (5): - Do not segfault when trying to bs_size_free NULL - Fix links for documentation and GH project - Add gcc to BuildRequires - Sync spec with downstream - Allow building libbytesize without Python 2 support Vratislav Podzimek (1): - Add a HACKING.rst file Thanks to all our contributors. Vojtech Trefny, 2018-04-19 Libbytesize 1.2 --------------- New minor release of the libbytesize library. There are only small changes in this release. **Full list of changes** Vratislav Podzimek (4): - Do not lie about tag creation - Do not require the glib-2.0 pkgconfig package - Use only version as a tag of the last release Thanks to all our contributors. Vratislav Podzimek, 2017-09-29 Libbytesize 1.1 --------------- New minor release of the libbytesize library. There are only small changes in this release and one important bug fix. **Notable changes** - Fixed parsing size strings with translated units (e.g. "10 Gio" in French). **Full list of changes** Vojtech Trefny (3): - Use only one git tag for new releases - Fix source and url in spec file - Add NEWS.rst file Vratislav Podzimek (4): - Add two temporary test files to .gitignore - Actually translate the units when expected - Fix the shortlog target - Sync spec with downstream Thanks to all our contributors. Vratislav Podzimek, 2017-09-21 Libbytesize 1.0 --------------- New major release of the libbytesize library. There are only small changes in this release, mostly bug fixes. The version bump is intended as a statement of "finishing" work on this library. The API is now stable and we don't plan to change it or add new major features. Future changes will probably include only bug fixes. **Full list of changes** Vojtech Trefny (1): - Make more space for CI status image Vratislav Podzimek (4): - Properly support 64bit operands - Remove extra 'is' in two docstrings - Include limits.h to make sure ULONG_MAX is defined - New version - 1.0 Thanks to all our contributors. Vratislav Podzimek, 2017-09-14 Libbytesize 0.11 ---------------- New minor release of the libbytesize library. Most changes in this release are related to fixing new issues and bugs. **Full list of changes** Kai Lüke (1): - Allow non-source directory builds Vojtech Trefny (7): - Do not try to run translation tests on CentOS/RHEL 7 - Fix library name in acinclude.m4 - Fix checking for available locales - Check for requires in generated spec file, not in the template - Remove "glibc-all-langpacks" from test dependencies - Fix README file name - Do not check for test dependencies for every test run Vratislav Podzimek (4): - Skip tests if they require unavailable locales - Add a build status image to the README.md - Reserve more space for the CI status - New version - 0.11 Thanks to all our contributors. Vratislav Podzimek, 2017-06-14 libbytesize-2.2/README.md000066400000000000000000000030031361502636100151600ustar00rootroot00000000000000### CI status CI status ### Introduction The goal of this project is to provide a tiny library that would facilitate the common operations with sizes in bytes. Many projects need to work with sizes in bytes (be it sizes of storage space, memory,...) and all of them need to deal with the same issues like: * How to get a human-readable string for the given size? * How to store the given size so that no significant information is lost? * If we store the size in bytes, what if the given size gets over the ``MAXUINT64`` value? * How to interpret sizes entered by users according to their locale and typing conventions? * How to deal with the decimal/binary units (*MB* vs. *MiB*) ambiguity? Some projects have all the above questions/concerns addressed well, some have them addressed partially some simply don't care. However, having (partial) solutions implemented in multiple places every time with a different set of bugs, differences in behaviour and this or that missing is a waste of time and effort. We need a generally usable solution that could be used by every project that needs to deal with sizes in bytes. Since the goal is to provide a solution as much generally usable as possible the implementation has to be small, fast and written in a language that can be easily interfaced from other languages. The current obvious choice is the *C* language with thin bindings for other languages. libbytesize-2.2/acinclude.m4000066400000000000000000000055451361502636100161070ustar00rootroot00000000000000dnl autoconf macros for libbytesize dnl dnl Copyright (C) 2014 Red Hat, Inc. dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU Lesser General Public License as published dnl by the Free Software Foundation; either version 2.1 of the License, or dnl (at your option) 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 Lesser General Public License for more details. dnl dnl You should have received a copy of the GNU Lesser General Public License dnl along with this program. If not, see . dnl dnl THIS IS A MODIFIED VERSION OF THE ANACONDA'S acinclude.m4 FILE. dnl dnl Author: David Shea dnl Vratislav Podzimek dnl LIBBYTESIZE_SOFT_FAILURE(MESSAGE) dnl dnl Store a message that in some contexts could be considered indicative dnl of a failure, but in other contexts could be indicative of who cares. dnl dnl Any message sent to this macro will be stored, and they can all be dnl displayed at the end of configure using the LIBBYTESIZE_FAILURES macro. AC_DEFUN([LIBBYTESIZE_SOFT_FAILURE], [dnl AS_IF([test x"$libbytesize_failure_messages" = x], [libbytesize_failure_messages="[$1]"], [libbytesize_failure_messages="$libbytesize_failure_messages [$1]" ])])dnl dnl LIBBYTESIZE_PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES) dnl dnl Check whether a module is available, using pkg-config. Instead of failing dnl if a module is not found, store the failure in a message that can be dnl printed using the LIBBYTESIZE_FAILURES macro. dnl dnl The syntax and behavior of VARIABLE-PREFIX and MODULES is the same as for dnl PKG_CHECK_MODULES. AC_DEFUN([LIBBYTESIZE_PKG_CHECK_MODULES], [dnl PKG_CHECK_MODULES([$1], [$2], [], [LIBBYTESIZE_SOFT_FAILURE($[$1]_PKG_ERRORS)]) ])dnl dnl LIBBYTESIZE_PKG_CHECK_EXISTS(MODULES) dnl dnl Check whether a module exists, using pkg-config. Instead of failing dnl if a module is not found, store the failure in a message that can be dnl printed using the LIBBYTESIZE_FAILURES macro. dnl dnl The syntax and behavior of MODULES is the same as for dnl PKG_CHECK_EXISTS. AC_DEFUN([LIBBYTESIZE_PKG_CHECK_EXISTS], [dnl PKG_CHECK_EXISTS([$1], [], [LIBBYTESIZE_SOFT_FAILURE([Check for $1 failed])]) ])dnl dnl LIBBYTESIZE_FAILURES dnl dnl Print the failure messages collected by LIBBYTESIZE_SOFT_FAILURE and dnl LIBBYTESIZE_PKG_CHECK_MODULES AC_DEFUN([LIBBYTESIZE_FAILURES], [dnl AS_IF([test x"$libbytesize_failure_messages" = x], [], [dnl echo "" echo "*** Libbytesize encountered the following issues during configuration:" echo "$libbytesize_failure_messages" echo "" echo "*** Libbytesize will not successfully build without these missing dependencies" exit 1 ])])dnl libbytesize-2.2/autogen.sh000077500000000000000000000006571361502636100157160ustar00rootroot00000000000000#!/bin/bash -e test -n "$srcdir" || srcdir=`dirname "$0"` test -n "$srcdir" || srcdir=. pushd $srcdir (test -f configure.ac) || { echo "*** ERROR: Directory "\`$srcdir\'" does not look like the top-level project directory ***" exit 1 } PKG_NAME=`autoconf --trace 'AC_INIT:$1' configure.ac` aclocal --install || exit 1 autoreconf --verbose --force --install -Wno-portability || exit 1 rm -rf autom4te.cache popd libbytesize-2.2/config.rpath000077500000000000000000000444351361502636100162270ustar00rootroot00000000000000#! /bin/sh # Output a system dependent set of variables, describing how to set the # run time search path of shared libraries in an executable. # # Copyright 1996-2014 Free Software Foundation, Inc. # Taken from GNU libtool, 2001 # Originally by Gordon Matzigkeit , 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # # The first argument passed to this file is the canonical host specification, # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld # should be set by the caller. # # The set of defined variables is at the end of this script. # Known limitations: # - On IRIX 6.5 with CC="cc", the run time search patch must not be longer # than 256 bytes, otherwise the compiler driver will dump core. The only # known workaround is to choose shorter directory names for the build # directory and/or the installation directory. # All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a shrext=.so host="$1" host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` # Code taken from libtool.m4's _LT_CC_BASENAME. for cc_temp in $CC""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'` # Code taken from libtool.m4's _LT_COMPILER_PIC. wl= if test "$GCC" = yes; then wl='-Wl,' else case "$host_os" in aix*) wl='-Wl,' ;; mingw* | cygwin* | pw32* | os2* | cegcc*) ;; hpux9* | hpux10* | hpux11*) wl='-Wl,' ;; irix5* | irix6* | nonstopux*) wl='-Wl,' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in ecc*) wl='-Wl,' ;; icc* | ifort*) wl='-Wl,' ;; lf95*) wl='-Wl,' ;; nagfor*) wl='-Wl,-Wl,,' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) wl='-Wl,' ;; ccc*) wl='-Wl,' ;; xl* | bgxl* | bgf* | mpixl*) wl='-Wl,' ;; como) wl='-lopt=' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ F* | *Sun*Fortran*) wl= ;; *Sun\ C*) wl='-Wl,' ;; esac ;; esac ;; newsos6) ;; *nto* | *qnx*) ;; osf3* | osf4* | osf5*) wl='-Wl,' ;; rdos*) ;; solaris*) case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) wl='-Qoption ld ' ;; *) wl='-Wl,' ;; esac ;; sunos4*) wl='-Qoption ld ' ;; sysv4 | sysv4.2uw2* | sysv4.3*) wl='-Wl,' ;; sysv4*MP*) ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) wl='-Wl,' ;; unicos*) wl='-Wl,' ;; uts4*) ;; esac fi # Code taken from libtool.m4's _LT_LINKER_SHLIBS. hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_direct=no hardcode_minus_L=no case "$host_os" in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac ld_shlibs=yes if test "$with_gnu_ld" = yes; then # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. # Unlike libtool, we use -rpath here, not --rpath, since the documented # option of GNU ld is called -rpath, not --rpath. hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' case "$host_os" in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no fi ;; amigaos*) case "$host_cpu" in powerpc) ;; m68k) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then : else ld_shlibs=no fi ;; haiku*) ;; interix[3-9]*) hardcode_direct=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; netbsd*) ;; solaris*) if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then ld_shlibs=no elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' else ld_shlibs=no fi ;; esac ;; sunos4*) hardcode_direct=yes ;; *) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then : else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then hardcode_libdir_flag_spec= fi else case "$host_os" in aix3*) # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac fi hardcode_direct=yes hardcode_libdir_separator=':' if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && \ strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac fi # Begin _LT_AC_SYS_LIBPATH_AIX. echo 'int main () { return 0; }' > conftest.c ${CC} ${LDFLAGS} conftest.c -o conftest aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` fi if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib" fi rm -f conftest.c conftest # End _LT_AC_SYS_LIBPATH_AIX. if test "$aix_use_runtimelinking" = yes; then hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' else hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" fi fi ;; amigaos*) case "$host_cpu" in powerpc) ;; m68k) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec=' ' libext=lib ;; darwin* | rhapsody*) hardcode_direct=no if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then : else ld_shlibs=no fi ;; dgux*) hardcode_libdir_flag_spec='-L$libdir' ;; freebsd2.2*) hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes ;; freebsd2*) hardcode_direct=yes hardcode_minus_L=yes ;; freebsd* | dragonfly*) hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes ;; hpux9*) hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; hpux10*) if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no ;; *) hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; netbsd*) hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes ;; newsos6) hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then hardcode_libdir_flag_spec='${wl}-rpath,$libdir' else case "$host_os" in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) hardcode_libdir_flag_spec='-R$libdir' ;; *) hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; osf3*) hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) if test "$GCC" = yes; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else # Both cc and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi hardcode_libdir_separator=: ;; solaris*) hardcode_libdir_flag_spec='-R$libdir' ;; sunos4*) hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes ;; sysv4) case $host_vendor in sni) hardcode_direct=yes # is this really true??? ;; siemens) hardcode_direct=no ;; motorola) hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac ;; sysv4.3*) ;; sysv4*MP*) if test -d /usr/nec; then ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) ;; sysv5* | sco3.2v5* | sco5v6*) hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' hardcode_libdir_separator=':' ;; uts4*) hardcode_libdir_flag_spec='-L$libdir' ;; *) ld_shlibs=no ;; esac fi # Check dynamic linker characteristics # Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER. # Unlike libtool.m4, here we don't care about _all_ names of the library, but # only about the one the linker finds when passed -lNAME. This is the last # element of library_names_spec in libtool.m4, or possibly two of them if the # linker has special search rules. library_names_spec= # the last element of library_names_spec in libtool.m4 libname_spec='lib$name' case "$host_os" in aix3*) library_names_spec='$libname.a' ;; aix[4-9]*) library_names_spec='$libname$shrext' ;; amigaos*) case "$host_cpu" in powerpc*) library_names_spec='$libname$shrext' ;; m68k) library_names_spec='$libname.a' ;; esac ;; beos*) library_names_spec='$libname$shrext' ;; bsdi[45]*) library_names_spec='$libname$shrext' ;; cygwin* | mingw* | pw32* | cegcc*) shrext=.dll library_names_spec='$libname.dll.a $libname.lib' ;; darwin* | rhapsody*) shrext=.dylib library_names_spec='$libname$shrext' ;; dgux*) library_names_spec='$libname$shrext' ;; freebsd* | dragonfly*) case "$host_os" in freebsd[123]*) library_names_spec='$libname$shrext$versuffix' ;; *) library_names_spec='$libname$shrext' ;; esac ;; gnu*) library_names_spec='$libname$shrext' ;; haiku*) library_names_spec='$libname$shrext' ;; hpux9* | hpux10* | hpux11*) case $host_cpu in ia64*) shrext=.so ;; hppa*64*) shrext=.sl ;; *) shrext=.sl ;; esac library_names_spec='$libname$shrext' ;; interix[3-9]*) library_names_spec='$libname$shrext' ;; irix5* | irix6* | nonstopux*) library_names_spec='$libname$shrext' case "$host_os" in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;; *) libsuff= shlibsuff= ;; esac ;; esac ;; linux*oldld* | linux*aout* | linux*coff*) ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) library_names_spec='$libname$shrext' ;; knetbsd*-gnu) library_names_spec='$libname$shrext' ;; netbsd*) library_names_spec='$libname$shrext' ;; newsos6) library_names_spec='$libname$shrext' ;; *nto* | *qnx*) library_names_spec='$libname$shrext' ;; openbsd*) library_names_spec='$libname$shrext$versuffix' ;; os2*) libname_spec='$name' shrext=.dll library_names_spec='$libname.a' ;; osf3* | osf4* | osf5*) library_names_spec='$libname$shrext' ;; rdos*) ;; solaris*) library_names_spec='$libname$shrext' ;; sunos4*) library_names_spec='$libname$shrext$versuffix' ;; sysv4 | sysv4.3*) library_names_spec='$libname$shrext' ;; sysv4*MP*) library_names_spec='$libname$shrext' ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) library_names_spec='$libname$shrext' ;; tpf*) library_names_spec='$libname$shrext' ;; uts4*) library_names_spec='$libname$shrext' ;; esac sed_quote_subst='s/\(["`$\\]\)/\\\1/g' escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` shlibext=`echo "$shrext" | sed -e 's,^\.,,'` escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <@]), [], [with_python3=check]) AC_SUBST(WITH_PYTHON3, 0) if test "x$with_python3" != "xno"; then AC_PATH_PROG([python3], [python3], [no]) AS_IF([test "x$python3" == "xno"], [if test "x$with_python3" = "xyes"; then LIBBYTESIZE_SOFT_FAILURE([Python3 support requested, but python3 is not available]) fi], [AC_SUBST(WITH_PYTHON3, 1) with_python3=yes]) fi AM_CONDITIONAL(WITH_PYTHON3, test "x$with_python3" != "xno" -a "x$python3" != "xno") AC_ARG_WITH([gtk-doc], AS_HELP_STRING([--with-gtk-doc], [generate documentation with gtk-doc @<:@default=check@:>@]), [], [with_gtk_doc=check]) AC_SUBST(WITH_GTK_DOC, 0) if test "x$with_gtk_doc" != "xno"; then AC_PATH_PROG([gtkdoc_scan], [gtkdoc-scan], [no]) AS_IF([test "x$gtkdoc_scan" == "xno"], [if test "x$with_gtk_doc" = "xyes"; then LIBBYTESIZE_SOFT_FAILURE([Building documentation with gtk-doc requested, but not available]) fi], [AC_SUBST(WITH_GTK_DOC, 1)]) fi AM_CONDITIONAL(WITH_GTK_DOC, test "x$with_gtk_doc" != "xno" -a "x$gtkdoc_scan" != "xno") AC_ARG_WITH([tools], AS_HELP_STRING([--with-tools], [build tools @<:@default=yes@:>@ (requires python3 bindings)]), [], [with_tools=yes]) AC_SUBST([WITH_TOOLS], [0]) AM_CONDITIONAL(WITH_TOOLS, test "x$with_tools" != "xno") AS_IF([test "x$with_tools" != "xno"], [AC_SUBST([WITH_TOOLS], [1])], []) AS_IF([test "x$with_tools" != "xno" && test "x$with_python3" != "xyes"], [LIBBYTESIZE_SOFT_FAILURE([Tools require Python3 bindings])], []) AC_OUTPUT dnl ========================================================================== echo " libbytesize $VERSION ==================== prefix: ${prefix} libdir: ${libdir} libexecdir: ${libexecdir} bindir: ${bindir} sbindir: ${sbindir} datadir: ${datadir} sysconfdir: ${sysconfdir} localstatedir: ${localstatedir} docdir: ${docdir} compiler: ${CC} cflags: ${CFLAGS} cppflags: ${CPPFLAGS} ldflags: ${LDFLAGS} Python 3 bindings: ${with_python3} tools: ${with_tools} " LIBBYTESIZE_FAILURES libbytesize-2.2/dist/000077500000000000000000000000001361502636100146505ustar00rootroot00000000000000libbytesize-2.2/dist/Makefile.am000066400000000000000000000001311361502636100166770ustar00rootroot00000000000000dist_noinst_DATA = libbytesize.spec MAINTAINERCLEANFILES = Makefile.in libbytesize.spec libbytesize-2.2/dist/libbytesize.spec.in000066400000000000000000000342201361502636100204570ustar00rootroot00000000000000%define realname bytesize %define with_python3 @WITH_PYTHON3@ %define with_gtk_doc @WITH_GTK_DOC@ %define with_tools @WITH_TOOLS@ %if (! 0%{?fedora} && 0%{?rhel} <= 7) || %{with_python3} == 0 %define with_python3 0 %define python3_opts --without-python3 %define with_tools 0 %endif %if %{with_tools} != 1 %define tools_opts --without-tools %endif %define configure_opts %{?python3_opts} %{?tools_opts} Name: libbytesize Version: 2.2 Release: 1%{?dist} Summary: A library for working with sizes in bytes License: LGPLv2+ URL: https://github.com/storaged-project/libbytesize Source0: https://github.com/storaged-project/libbytesize/releases/download/%{version}-%{release}/%{name}-%{version}.tar.gz BuildRequires: gcc BuildRequires: gmp-devel BuildRequires: mpfr-devel BuildRequires: pcre2-devel BuildRequires: gettext-devel %if %{with_python3} BuildRequires: python3-devel %endif %if %{with_gtk_doc} BuildRequires: gtk-doc %endif %description The libbytesize is a C library that facilitates work with sizes in bytes. Be it parsing the input from users or producing a nice human readable representation of a size in bytes this library takes localization into account. It also provides support for sizes bigger than MAXUINT64. %package devel Summary: Development files for libbytesize Requires: %{name}%{?_isa} = %{version}-%{release} %description devel This package contains header files and pkg-config files needed for development with the libbytesize library. %if %{with_python3} %package -n python3-%{realname} Summary: Python 3 bindings for libbytesize Requires: %{name}%{?_isa} = %{version}-%{release} Requires: python3-six %description -n python3-%{realname} This package contains Python 3 bindings for libbytesize making the use of the library from Python 3 easier and more convenient. %endif %if %{with_tools} %package tools Summary: Various nice tools based on libbytesize Requires: python3-%{realname} = %{version}-%{release} %description tools Various nice tools based on libbytesize, in particular the calculator for doing calculations with storage sizes. %endif %prep %setup -q -n %{name}-%{version} %build %configure %{?configure_opts} %{__make} %{?_smp_mflags} %install %{make_install} find %{buildroot} -type f -name "*.la" | xargs %{__rm} %find_lang %{name} %ldconfig_scriptlets %files -f %{name}.lang %doc README.md %{!?_licensedir:%global license %%doc} %license LICENSE %{_libdir}/libbytesize.so.* %files devel %{_libdir}/libbytesize.so %dir %{_includedir}/bytesize %{_includedir}/bytesize/bs_size.h %{_libdir}/pkgconfig/bytesize.pc %if %{with_gtk_doc} %{_datadir}/gtk-doc/html/libbytesize %endif %if %{with_python3} %files -n python3-%{realname} %dir %{python3_sitearch}/bytesize %{python3_sitearch}/bytesize/* %{python3_sitearch}/bytesize/__pycache__/* %endif %if %{with_tools} %files tools %{_bindir}/bscalc %{_mandir}/man1/bscalc.1* %endif %changelog * Thu Jan 30 2020 Vojtech Trefny - 2.2-1 - Require the same version of python3-bytesize in libbytesize-tools (v.podzimek) - src/gettext: fix warning if gettext is already present (giulio.benetti) - Update README.md (vpodzime) - fix build on shells where test == fails (tbier) - Add POT file to git and do not rebuild it during every build (vtrefny) * Wed Jul 03 2019 Vojtech Trefny - 2.1-1 - fix out of tree build failure (hongxu.jia) - Fix return value for round_to_nearest when using Size (vtrefny) * Thu Apr 25 2019 Vojtech Trefny - 2.0-1 - Assume the given expression is in bytes if no unit is given (v.podzimek) - Add a man page for the bscalc tool (v.podzimek) - Add the '--version' option to bs_calc.py (v.podzimek) - Fix parsing of exponential representations of real numbers (v.podzimek) - Only support modulo between two Size instances (v.podzimek) - Add a summary to the end of ./configure output (v.podzimek) - Exit with 1 from configure if there were failures (v.podzimek) - Add tools to autotools and packaging (v.podzimek) - Add a simple bytesize calculator tool (v.podzimek) - Add support for floor division by a non-integer number in Python (v.podzimek) - Port to pcre2 (vtrefny) - Remove Python 2 support (vtrefny) - Allow running tests using installed library (vtrefny) - Add all "public" python API symbols to __init__.py (vtrefny) - Run all libbytesize tests from one script (vtrefny) * Thu Aug 02 2018 Vojtech Trefny - 1.4-1 - Squashed 'translation-canary/' changes from 840c2d6..fccbb1b (vtrefny) - Make sure the test script fails if one of the test runs fail (vtrefny) - Do not try to run python2 tests without python2 support (vtrefny) - Fix licence header for "gettext.h" (vtrefny) - Do not use rpm to check for Zanata client (vtrefny) - Use new ldconfig_scriptlets macro in spec (vtrefny) * Thu Apr 19 2018 Vojtech Trefny - 1.3-1 - Allow building libbytesize without Python 2 support (vtrefny) - Sync spec with downstream (vtrefny) - Add gcc to BuildRequires (vtrefny) - Fix links for documentation and GH project (vtrefny) - Add a HACKING.rst file (vpodzime) - Do not segfault when trying to bs_size_free NULL (vtrefny) * Wed Feb 21 2018 Vojtech Trefny - 1.2-4 - Add gcc to BuildRequires (vtrefny) * Wed Feb 07 2018 Fedora Release Engineering - 1.2-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild * Fri Jan 05 2018 Iryna Shcherbina - 1.2-2 - Update Python 2 dependency declarations to new packaging standards (See https://fedoraproject.org/wiki/FinalizingFedoraSwitchtoPython3) * Fri Sep 29 2017 Vratislav Podzimek - 1.2-1 - Use only version as a tag of the last release (vpodzime) - Do not require the glib-2.0 pkgconfig package (vpodzime) - Do not lie about tag creation (vpodzime) * Thu Sep 28 2017 Troy Dawson - 1.1-2 - Cleanup spec file conditionals * Thu Sep 21 2017 Vratislav Podzimek - 1.1-1 - Add NEWS.rst file (vtrefny) - Fix source and url in spec file (vtrefny) - Use only one git tag for new releases (vtrefny) - Actually translate the units when expected (vpodzime) - Add two temporary test files to .gitignore (vpodzime) * Thu Sep 14 2017 Vratislav Podzimek - 1.0-1 - Make more space for CI status image (vtrefny) - Include limits.h to make sure ULONG_MAX is defined (vpodzime) - Remove extra 'is' in two docstrings (vpodzime) - Properly support 64bit operands (vpodzime) * Sat Aug 19 2017 Zbigniew Jędrzejewski-Szmek - 0.11-4 - Python 2 binary package renamed to python2-libbytesize See https://fedoraproject.org/wiki/FinalizingFedoraSwitchtoPython3 * Thu Aug 03 2017 Fedora Release Engineering - 0.11-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild * Wed Jul 26 2017 Fedora Release Engineering - 0.11-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild * Wed Jun 14 2017 Vratislav Podzimek - 0.11-1 - Fix README file name (vtrefny) - Add a build status image to the README.md (vpodzime) - Remove "glibc-all-langpacks" from test dependencies (vtrefny) - Check for requires in generated spec file, not in the template (vtrefny) - Fix checking for available locales (vtrefny) - Fix library name in acinclude.m4 (vtrefny) - Do not try to run translation tests on CentOS/RHEL 7 (vtrefny) - Skip tests if they require unavailable locales (vpodzime) * Wed Apr 19 2017 Vratislav Podzimek - 0.10-1 - Fix installation without specifying --exec-prefix (martin) - Sync the spec file with downstream (vpodzime) * Fri Feb 10 2017 Fedora Release Engineering - 0.9-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild * Wed Jan 11 2017 Vratislav Podzimek - 0.9-1 - Allow the Size python class to be easily imported (vpodzime) - Make sure pyexecdir is defined (vpodzime) - Do not run Python 3 tests without python3 (vpodzime) - Disable python3 on RHEL (vpodzime) - Reflect the configuration in the spec file template (vpodzime) - Make documentation generation conditional (vpodzime) - Make python3 support conditional (vpodzime) - Require lower version of libpcre (vpodzime) - Sync the spec file with downstream (vpodzime) * Wed Dec 21 2016 Adam Williamson - 0.8-2 - Rebuild for Python 3.6, again * Fri Dec 16 2016 Vratislav Podzimek - 0.8-1 - Add a docstring to python bindings (vpodzime) - Neutralize None as an operand for math operations (vpodzime) - Add targets for checking and installing test requirements (vpodzime) - Fix 'make local' (vtrefny) - Make the python packages own their package directories (vpodzime) - Don't compare translated and untranslated representations (vpodzime) - replace_char_with_str: Fix the character count. (dshea) - Ditch autopoint. (dshea) * Mon Dec 12 2016 Charalampos Stratakis - 0.7-4 - Rebuild for Python 3.6 * Tue Sep 20 2016 Vratislav Podzimek - 0.7-3 - Prevent ignored exceptions in __del__ from happening (vpodzime) * Tue Jul 19 2016 Fedora Release Engineering - 0.7-2 - https://fedoraproject.org/wiki/Changes/Automatic_Provides_for_Python_RPM_Packages * Tue May 17 2016 Vratislav Podzimek - 0.7-1 - Re-run autogen.sh and configure before updating the .pot file (vpodzime) - Change where tests on translated strings are run. (dshea) - Squashed 'translation-canary/' changes from d6c0708..840c2d6 (dshea) - Make sure we get the tests result report in 'make ci' (vpodzime) - Add a new generic error code/enum for failures (vpodzime) - Do not ignore the return value from asprintf() (vpodzime) - Beware of the radix char when converting to Decimal (#1325705) (vpodzime) * Fri May 6 2016 Vratislav Podzimek - 0.6-2 - Beware of unsigned long int on 32bit arches (#1333149) (vpodzime) * Tue May 03 2016 Vratislav Podzimek - 0.6-1 - Add support for the ROUND_HALF_UP rounding mode (vpodzime) - Make sure we return the right radix char in human_readable() (vpodzime) - Allocate enough memory for char->str replacements (vpodzime) * Tue Apr 26 2016 Vratislav Podzimek - 0.5-1 - Create both libbytesize-$version and $version tags (vpodzime) - Update the .pot file with the new version (vpodzime) - Improve how we create changelog (vpodzime) - Try harder when getting OverflowError in division (#1326897) (vpodzime) - Neutralize the radix char before passing string to MPFR (#1326108) (vpodzime) - Run tests with en_US and fr_FR locales (vpodzime) - Run the tests with both python2 and python3 again (vpodzime) - Do not run the same tests 3 times as part of the 'ci' target (vpodzime) - Don't fail if just the best-effort cleanup fails (vpodzime) - Throw away the new .pot file when just running tests (vpodzime) - Make sure we return one of -1, 0, 1 from cmp functions (#1326113) (vpodzime) - Use cmp_bytes(size, bytes) when comparing to 0 (vpodzime) - Ignore all .po~ files (vpodzime) - Add translator comments (dshea) - Integrate translation-canary into the build. (dshea) - Run the translation-canary tests from make check. (dshea) - Squashed 'translation-canary/' content from commit d6c0708 (dshea) - Make 'make check' work. (dshea) - Remove files from po/ we don't need to track (vpodzime) - Ignore the compiled translation files (vpodzime) - Distribute and package the translations (vpodzime) - Add the necessary pieces for getting translations (vpodzime) * Thu Apr 14 2016 Vratislav Podzimek - 0.4-3 - Only require -lgmp and -lmpfr for static linking (vpodzime) * Fri Mar 11 2016 Vratislav Podzimek - 0.4-2 - Do not try to delete the C struct twice (vpodzime) * Wed Mar 09 2016 Vratislav Podzimek - 0.4-1 - Add the __init__.py file to provide a proper package (vpodzime) - Merge pull request #7 from vpodzime/master-decimal_locale (vpodzime) - Make sure we pass a locale-agnostic string to Decimal() (vpodzime) - Adapt the package description to no longer using GI (vpodzime) - Make Size instances hashable (vpodzime) - Sync the spec file with downstream (vpodzime) * Wed Mar 9 2016 Vratislav Podzimek - 0.3-3 - Make sure we pass a locale-agnostic string to Decimal() (vpodzime) * Mon Mar 7 2016 Vratislav Podzimek - 0.3-2 - Make Size instances hashable (vpodzime) * Fri Feb 26 2016 Vratislav Podzimek - 0.3-1 - Packaging changes related to getting rid of GLib/GObject (vpodzime) - Adapt the python bindings and tests (vpodzime) - Get rid of GObject and GLib (vpodzime) - Define the __divmod__ method even for not dividing by Size (vpodzime) * Thu Feb 04 2016 Fedora Release Engineering - 0.2-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild * Tue Nov 10 2015 Fedora Release Engineering - 0.2-2 - Rebuilt for https://fedoraproject.org/wiki/Changes/python3.5 * Fri Oct 23 2015 Vratislav Podzimek - 0.2-1 - Distribute the tests for overrides (vpodzime) - Fix the rpmlog target (vpodzime) - Respect the signs when doing division (vpodzime) - Add two more internal methods that may be required (vpodzime) - Do not pass negative numbers as guint64 when comparing with negative ints (vpodzime) - Round toward zero when converting bytes from float to int (vpodzime) - Make sure we return Size if doing operations with big integers (vpodzime) - Implement the __divmod__() method (vpodzime) - Do not try to convert negative int to an unsigned int when multiplying (vpodzime) - Fix and test the __deepcopy__ method (vpodzime) - Implement the evaluation of Size instance as a bool value (vpodzime) - Fix some issues in comparison functions and add tests (vpodzime) - Add a function for getting string representation of a unit (vpodzime) - Hook the overrides tests to the 'test' target (vpodzime) - Merge pull request #4 from japokorn/master-tests_03_python_override (vpodzime) - Added tests for Python override (japokorn) - Make sure our tests don't get broken by installed overrides (vpodzime) * Wed Oct 07 2015 Vratislav Podzimek - 0.1-1 - Initial release libbytesize-2.2/docs/000077500000000000000000000000001361502636100146355ustar00rootroot00000000000000libbytesize-2.2/docs/Makefile.am000066400000000000000000000031751361502636100166770ustar00rootroot00000000000000all-local: html-doc.stamp html-doc.stamp: ${srcdir}/libbytesize-docs.xml ${srcdir}/libbytesize-sections.txt ${srcdir}/../src/bs_size.c ${srcdir}/../src/bs_size.h touch ${builddir}/html-doc.stamp test ${builddir} = ${srcdir} || cp ${srcdir}/libbytesize-sections.txt ${srcdir}/libbytesize-docs.xml ${builddir} gtkdoc-scan --rebuild-types --module=libbytesize --source-dir=${srcdir}/../src/ gtkdoc-mkdb --module=libbytesize --output-format=xml --source-dir=${srcdir}/../src/ --source-suffixes=c,h test -d ${builddir}/html || mkdir ${builddir}/html (cd ${builddir}/html; gtkdoc-mkhtml libbytesize ${builddir}/../libbytesize-docs.xml) gtkdoc-fixxref --module=libbytesize --module-dir=html --html-dir=/usr/share/gtk-doc/html clean-local: -rm -rf ${builddir}/html -rm -rf ${builddir}/xml test ! -f ${builddir}/html-doc.stamp || rm ${builddir}/html-doc.stamp test ${builddir} = ${srcdir} || rm -f ${builddir}/libbytesize-sections.txt ${builddir}/libbytesize-docs.xml install-data-local: test -d ${DESTDIR}${datadir}/gtk-doc/html/libbytesize || mkdir -p ${DESTDIR}${datadir}/gtk-doc/html/libbytesize install -m0644 ${builddir}/html/* ${DESTDIR}${datadir}/gtk-doc/html/libbytesize/ uninstall-local: -rm -rf ${DESTDIR}${datadir}/gtk-doc/html/libbytesize/ dist_noinst_DATA = ${srcdir}/libbytesize-sections.txt ${srcdir}/libbytesize-docs.xml CLEANFILES = html.stamp sgml.stamp \ libbytesize-decl-list.txt \ libbytesize-decl.txt \ libbytesize-decl.txt.bak \ libbytesize-overrides.txt \ libbytesize-undeclared.txt \ libbytesize-undocumented.txt \ libbytesize-unused.txt \ libbytesize.types MAINTAINERCLEANFILES = Makefile.in libbytesize-docs.xml libbytesize-2.2/docs/libbytesize-docs.xml.in000066400000000000000000000030001361502636100212300ustar00rootroot00000000000000 ]> libbytesize Reference Manual for libbytesize @VERSION@. The latest version of this documentation can be found on-line at http://storaged.org/libbytesize. libbytesize Reference Manual Bindings Currently there are only Python bindings (working with both Python 2 and Python 3). The bindings are not documented here (yet), but it should be easy to directly check the sources. The bindings are located in the src/python directory in the source tree. API Index Index of deprecated API libbytesize-2.2/docs/libbytesize-sections.txt000066400000000000000000000012641361502636100215530ustar00rootroot00000000000000
bs_size BSSize BSErrorCode BSError BSBunit BSDunit BSRoundDir BSUnit BS_FLOAT_PREC_BITS bs_size_new bs_size_new_from_bytes bs_size_new_from_str bs_size_new_from_size bs_size_free bs_clear_error bs_size_get_bytes bs_size_sgn bs_size_get_bytes_str bs_size_convert_to bs_size_human_readable bs_size_add bs_size_grow bs_size_add_bytes bs_size_grow_bytes bs_size_sub bs_size_shrink bs_size_sub_bytes bs_size_shrink_bytes bs_size_mul_int bs_size_grow_mul_int bs_size_mul_float_str bs_size_grow_mul_float_str bs_size_div bs_size_div_int bs_size_shrink_div_int bs_size_true_div bs_size_true_div_int bs_size_mod bs_size_round_to_nearest bs_size_cmp bs_size_cmp_bytes
libbytesize-2.2/po/000077500000000000000000000000001361502636100143235ustar00rootroot00000000000000libbytesize-2.2/po/Makefile.am000066400000000000000000000204261361502636100163630ustar00rootroot00000000000000# po/Makefile.am for anaconda # # Based loosely on Makefiles generated by gettext # # Copyright (C) 2016 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. # # 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 Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # # Author: David Shea # This file is intended to replace everything that gettextize or autopoint # installs. It has a lot less weird crud and tries to cooperate with # automake at least a little bit. # # To use it: # - Edit COPYRIGHT_HOLDER and MSGID_BUGS_ADDRESS below # # - Add the file types you're interested in to POTFILE_SUFFIXES. This replaces # the old POTFILES.in since the list of files you want to select for # translation is invariably all of them. # # - Add po/Makefile to AC_CONFIG_FILES (there may be po/Makefile.in if # switching from gettextize, replace that) # # - Get rid of AM_GNU_GETTEXT and AM_GNU_GETTEXT_VERSION. You might want to # add checks for xgettext, msgmerge, msgfmt, and msgcat. Up to you. # # - Add the following to .gitignore: # po/*.mo # po/*.po # po/*.mpo # po/*.pot # # - Remove everything in the po/ directory from source control except this # file. # # The idea is something like this: # From a clean project, you do the automake stuff and download a bunch of # .po files from the external translation site. These are the "source" files. # # From the source tree we create a template file, .pot, of all the # translatable strings. This file is not saved or distributed because there's # really no reason to do that if translations are not part of the source # tree. The file is pushed to the translators when creating a new release, # and it is used during the build, and that's it. # # The .po files might not match the .pot file, because this is the nature of # linear time and translations being a separate task. Maybe the translator # last touched the .po file yesterday. Maybe three years ago. To get the # translations in sync with the source, which usually means untranslating # some strings, we run msgmerge on all of the source files. The merged files # are saved in builddir as .mpo, which is a non-standard file extension # I just made up. # # The merged .po files are then compiled into .mo files, which are what # get installed to /usr/share/locale. # Variables used in xgettext arguments COPYRIGHT_HOLDER = Red Hat, Inc. MSGID_BUGS_ADDRESS = vtrefny@redhat.com # What kind of files are we looking for? POTFILE_SUFFIXES = c # Below this line is the part that shouldn't need to be changed for other # projects # Turn POTFILE_SUFFIXES into a list of files POTFILE_INPUT = $(foreach s,$(POTFILE_SUFFIXES),\ $(shell find $(top_srcdir)/ -type d -name .git -prune -o -type f -name '*.$(s)' -print)) # The template file, generated by from all files with translatable strings. POTFILE = $(PACKAGE).pot # The translation files, provided by translators, pulled down from Zanata. # Use whatever we got from Zanata, or nothing at all if no translations were # pulled. POFILES = $(wildcard $(srcdir)/*.po) # The translations files after they have been merged with the latest copy of # the .pot file. These are written to $(builddir) as .mpo. MERGED_POFILES = $(patsubst %.po,%.mpo,$(notdir $(POFILES))) # The MO files, which are the binary data built from the .po files. MOFILES = $(patsubst %.mpo,%.mo,$(MERGED_POFILES)) # Special weirdness to auto-generate sr@latin.po if sr.po is present MERGED_POFILES += $(if $(shell [ -f sr.po ] && echo y),sr@latin.mpo,) sr@latin.mpo: $(srcdir)/sr.po $(AM_V_GEN)$(MSGFILTER) -i $(srcdir)/sr.po -o $@ recode-sr-latin # The gettext programs and arguments # xgettext eXtracts strings from translatable files and generates the template # (.pot) file. We use a wrapper from translation-canary in order to catch # warnings about strings that may not be translatable, and all the keyword # arguments define the various functions that are used to mark a string as # translatable XGETTEXT = $(top_srcdir)/translation-canary/xgettext_werror.sh XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ --keyword=P_:1,2 \ --keyword=C_:1c,2 --keyword=CN_:1c,2 --keyword=CP_:1c,2,3 \ --add-comments=TRANSLATORS: \ --from-code=UTF-8 --package-name=$(PACKAGE) \ --package-version=$(PACKAGE_VERSION) \ --copyright-holder="$(COPYRIGHT_HOLDER)" \ --msgid-bugs-address="$(MSGID_BUGS_ADDRESS)" # msgfmt compiles a .po file into a .mo file # Do not include --check in the options, since those checks are more # conveniently done by translation-canary MSGFMT = msgfmt MSGFMT_OPTIONS = # msgmerge merges changes in the template (.pot) file back into the translation # (.po) file MSGMERGE = msgmerge MSGMERGE_OPTIONS = # msgfilter applies a filter to a .po file. We use this to automatically # transliterate Serbian from Cyrillic (sr) to Latin (sr@latin). MSGFILTER = msgfilter # msgcat cats multiple .po (or .pot) files together. We use this to generate # the .pot file from multiple parts. MSGCAT = msgcat # Automake magic for verbose/non-verbose build output GETTEXT_V_EXTRACT = $(GETTEXT_V_EXTRACT_$(V)) GETTEXT_V_EXTRACT_ = $(GETTEXT_V_EXTRACT_$(AM_DEFAULT_VERBOSITY)) GETTEXT_V_EXTRACT_0 = @echo " EXTRACT " $@; GETTEXT_V_FORMAT = $(GETTEXT_V_FORMAT_$(V)) GETTEXT_V_FORMAT_ = $(GETTEXT_V_FORMAT_$(AM_DEFAULT_VERBOSITY)) GETTEXT_V_FORMAT_0 = @echo " FORMAT " $@; GETTEXT_V_MERGE = $(GETTEXT_V_MERGE_$(V)) GETTEXT_V_MERGE_ = $(GETTEXT_V_MERGE_$(AM_DEFAULT_VERBOSITY)) GETTEXT_V_MERGE_0 = @echo " MERGE " $@; # If make was run with V=1, add verbose options to msgfmt MSGFMT_V_OPTIONS = $(MSGFMT_V_OPTIONS_$(V)) MSGFMT_V_OPTIONS_ = $(MSGFMT_V_OPTIONS_$(AM_DEFAULT_VERBOSITY)) MSGFMT_V_OPTIONS_0 = $(MSGFMT_OPTIONS) MSGFMT_V_OPTIONS_1 = $(MSGFMT_OPTIONS) --statistics --verbose # Same with msgmerge MSGMERGE_V_OPTIONS = $(MSGMERGE_V_OPTIONS_$(V)) MSGMERGE_V_OPTIONS_ = $(MSGMERGE_V_OPTIONS_$(AM_DEFAULT_VERBOSITY)) MSGMERGE_V_OPTIONS_0 = $(MSGMERGE_OPTIONS) --quiet MSGMERGE_V_OPTIONS_1 = $(MSGMERGE_OPTIONS) --verbose # Actually do stuff: # .po files get distributed but not installed dist_noinst_DATA = $(POFILES) $(POTFILE) # Build the .mo files but don't actually do anything with them. The real # install part is in the install-data-local target below. Build the .pot file # as well, even if there are no .mo files to build, so it can be tested. nodist_noinst_DATA = $(MOFILES) # How to build the .pot file. This needs to be regenerated if anything that # goes into it has changed. $(POTFILE): $(POTFILE_INPUT) $(GETTEXT_V_EXTRACT)$(XGETTEXT) $(XGETTEXT_OPTIONS) --directory=$(top_srcdir) -o $@ \ $(patsubst $(top_srcdir)/%,%,$(POTFILE_INPUT)) # Force a rebuild of the .pot file. Useful if something got removed, for # example. $(PACKAGE).pot-update: @rm -f $(POTFILE) @$(MAKE) $(POTFILE) # How to build the merged .mpo files from the .po files $(MERGED_POFILES): $(POFILES) .po.mpo: $(GETTEXT_V_MERGE)$(MSGMERGE) $(MSGMERGE_V_OPTIONS) -o $@ $< $(top_srcdir)/po/$(POTFILE) # How to build the .mo files from the .mpo files $(MOFILES): $(MERGED_POFILES) $(POTFILE) .mpo.mo: $(GETTEXT_V_FORMAT)$(MSGFMT) $(MSGFMT_V_OPTIONS) -o $@ $< # Install the .mo files. # .mo files get installed as $datadir/locale//LC_MESSAGES/.po # which doesn't really fit well with the way make or automake do things but # that is the world we live in localedir = $(datadir)/locale install-data-local: @for mo in $(MOFILES) ; do \ lang="$$(basename "$$mo" .mo)" ; \ $(MKDIR_P) $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES || exit $$? ; \ $(INSTALL_DATA) "$$mo" "$(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(PACKAGE).mo" || exit $$? ; \ done uninstall-local: @for mo in $(MOFILES) ; do \ lang="$$(basename "$$mo" .mo)" ; \ rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(PACKAGE).mo ; \ done CLEANFILES = $(MERGED_POFILES) $(MOFILES) libbytesize-2.2/po/libbytesize.pot000066400000000000000000000043011361502636100173720ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Red Hat, Inc. # This file is distributed under the same license as the libbytesize package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: libbytesize 2.2\n" "Report-Msgid-Bugs-To: vtrefny@redhat.com\n" "POT-Creation-Date: 2020-01-30 14:55+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #. TRANSLATORS: 'B' for bytes #: src/bs_size.c:52 src/bs_size.c:73 msgid "B" msgstr "" #. TRANSLATORS: abbreviation for kibibyte, 2**10 bytes #: src/bs_size.c:54 msgid "KiB" msgstr "" #. TRANSLATORS: abbreviation for mebibyte, 2**20 bytes #: src/bs_size.c:56 msgid "MiB" msgstr "" #. TRANSLATORS: abbreviation for gibibyte, 2**30 bytes #: src/bs_size.c:58 msgid "GiB" msgstr "" #. TRANSLATORS: abbreviation for tebibyte, 2**40 bytes #: src/bs_size.c:60 msgid "TiB" msgstr "" #. TRANSLATORS: abbreviation for pebibyte, 2**50 bytes #: src/bs_size.c:62 msgid "PiB" msgstr "" #. TRANSLATORS: abbreviation for exbibyte, 2**60 bytes #: src/bs_size.c:64 msgid "EiB" msgstr "" #. TRANSLATORS: abbreviation for zebibyte, 2**70 bytes #: src/bs_size.c:66 msgid "ZiB" msgstr "" #. TRANSLATORS: abbreviation for yobibyte, 2**80 bytes #: src/bs_size.c:68 msgid "YiB" msgstr "" #. TRANSLATORS: abbreviation for kilobyte, 10**3 bytes #: src/bs_size.c:75 msgid "KB" msgstr "" #. TRANSLATORS: abbreviation for megabyte, 10**6 bytes #: src/bs_size.c:77 msgid "MB" msgstr "" #. TRANSLATORS: abbreviation for gigabyte, 10**9 bytes #: src/bs_size.c:79 msgid "GB" msgstr "" #. TRANSLATORS: abbreviation for terabyte, 10**12 bytes #: src/bs_size.c:81 msgid "TB" msgstr "" #. TRANSLATORS: abbreviation for petabyte, 10**15 bytes #: src/bs_size.c:83 msgid "PB" msgstr "" #. TRANSLATORS: abbreviation for exabyte, 10**18 bytes #: src/bs_size.c:85 msgid "EB" msgstr "" #. TRANSLATORS: abbreviation for zettabyte, 10**21 bytes #: src/bs_size.c:87 msgid "ZB" msgstr "" #. TRANSLATORS: abbreviation for yottabyte, 10**24 bytes #: src/bs_size.c:89 msgid "YB" msgstr "" libbytesize-2.2/src/000077500000000000000000000000001361502636100144745ustar00rootroot00000000000000libbytesize-2.2/src/Makefile.am000066400000000000000000000011351361502636100165300ustar00rootroot00000000000000AM_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" -DDEFAULT_TEXT_DOMAIN=\"libbytesize\" LDADD = $(LIBINTL) lib_LTLIBRARIES = libbytesize.la libbytesize_la_CFLAGS = -Wall -Wextra -Werror -Wno-overflow -D_GNU_SOURCE libbytesize_la_LIBADD = -lgmp -lmpfr $(PCRE2_LIBS) libbytesize_la_LDFLAGS = -version-info 1:0:0 libbytesize_la_SOURCES = bs_size.c bs_size.h gettext.h noinst_dist_SOURCES = gettext.h libincludedir = $(includedir)/bytesize libinclude_HEADERS = bs_size.h pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = ${builddir}/bytesize.pc SUBDIRS = python MAINTAINERCLEANFILES = Makefile.in bytesize.pc libbytesize-2.2/src/bs_size.c000066400000000000000000001115441361502636100163040ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include /* set code unit width to 8 so we can use generic macros like 'pcre2_compile' * instead of 'pcre2_compile_8' */ #define PCRE2_CODE_UNIT_WIDTH 8 #include #include "bs_size.h" #include "gettext.h" #define _(String) gettext (String) #define N_(String) String #define ERROR_BUFFER_LEN 256 /** * SECTION: bs_size * @title: BSSize * @short_description: a class facilitating work with sizes in bytes * @include: bs_size.h * * #BSSize is a type that facilitates work with sizes in bytes by providing * functions/methods that are required for parsing users input when entering * size, showing size in nice human-readable format, storing sizes bigger than * %UINT64_MAX and doing calculations with sizes without loss of * precision/information. The class is able to hold negative sizes and do * operations on/with them, but some of the (division and multiplication) * operations simply ignore the signs of the operands (check the documentation). * * The reason why some functions take or return a float as a string instead of a * float directly is because a string "0.3" can be translated into 0.3 with * appropriate precision while 0.3 as float is probably something like * 0.294343... with unknown precision. * */ /*************** * STATIC DATA * ***************/ static char const * const b_units[BS_BUNIT_UNDEF] = { /* TRANSLATORS: 'B' for bytes */ N_("B"), /* TRANSLATORS: abbreviation for kibibyte, 2**10 bytes */ N_("KiB"), /* TRANSLATORS: abbreviation for mebibyte, 2**20 bytes */ N_("MiB"), /* TRANSLATORS: abbreviation for gibibyte, 2**30 bytes */ N_("GiB"), /* TRANSLATORS: abbreviation for tebibyte, 2**40 bytes */ N_("TiB"), /* TRANSLATORS: abbreviation for pebibyte, 2**50 bytes */ N_("PiB"), /* TRANSLATORS: abbreviation for exbibyte, 2**60 bytes */ N_("EiB"), /* TRANSLATORS: abbreviation for zebibyte, 2**70 bytes */ N_("ZiB"), /* TRANSLATORS: abbreviation for yobibyte, 2**80 bytes */ N_("YiB") }; static char const * const d_units[BS_DUNIT_UNDEF] = { /* TRANSLATORS: 'B' for bytes */ N_("B"), /* TRANSLATORS: abbreviation for kilobyte, 10**3 bytes */ N_("KB"), /* TRANSLATORS: abbreviation for megabyte, 10**6 bytes */ N_("MB"), /* TRANSLATORS: abbreviation for gigabyte, 10**9 bytes */ N_("GB"), /* TRANSLATORS: abbreviation for terabyte, 10**12 bytes */ N_("TB"), /* TRANSLATORS: abbreviation for petabyte, 10**15 bytes */ N_("PB"), /* TRANSLATORS: abbreviation for exabyte, 10**18 bytes */ N_("EB"), /* TRANSLATORS: abbreviation for zettabyte, 10**21 bytes */ N_("ZB"), /* TRANSLATORS: abbreviation for yottabyte, 10**24 bytes */ N_("YB") }; /**************************** * STRUCT DEFINITIONS * ****************************/ /** * BSSize: * * The BSSize struct contains only private fields and should not be directly * accessed. */ struct _BSSize { mpz_t bytes; }; /******************** * HELPER FUNCTIONS * ********************/ static void bs_size_init (BSSize size) { /* let's start with 64 bits of space */ mpz_init2 (size->bytes, (mp_bitcnt_t) 64); } static char *strdup_printf (const char *fmt, ...) { int num = 0; char *ret = NULL; va_list ap; va_start (ap, fmt); num = vasprintf (&ret, fmt, ap); va_end (ap); if (num <= 0) /* make sure we return NULL on error */ ret = NULL; return ret; } /** * replace_char_with_str: (skip) * * Replaces all apperances of @char in @str with @new. */ static char *replace_char_with_str (const char *str, char orig, const char *new) { uint64_t offset = 0; uint64_t i = 0; uint64_t j = 0; char *ret = NULL; const char *next = NULL; uint64_t count = 0; if (!str) return NULL; next = str; for (next=strchr (next, orig); next; count++, next=strchr (++next, orig)); /* allocate space for the string [strlen(str)] with the char replaced by the string [strlen(new) - 1] $count times and a \0 byte at the end [ + 1] */ ret = malloc (sizeof(char) * (strlen(str) + (strlen(new) - 1) * count + 1)); for (i=0; str[i]; i++) { if (str[i] == orig) for (j=0; new[j]; j++) { ret[i+offset] = new[j]; if (new[j+1]) /* something more to copy over */ offset++; } else ret[i+offset] = str[i]; } ret[i+offset] = '\0'; return ret; } /** * replace_str_with_str: (skip) * * Replaces the first appearance of @orig in @str with @new. */ static char *replace_str_with_str (const char *str, const char *orig, const char *new) { char *pos = NULL; int str_len = 0; int orig_len = 0; int new_len = 0; char *ret = NULL; int ret_size = 0; char *dest = NULL; pos = strstr (str, orig); if (!pos) /* nothing to do, just return a copy */ return strdup (str); str_len = strlen (str); orig_len = strlen (orig); new_len = strlen (new); ret_size = str_len + new_len - orig_len + 1; ret = malloc (sizeof(char) * ret_size); memset (ret, 0, ret_size); memcpy (ret, str, pos - str); dest = ret + (pos - str); memcpy (dest, new, new_len); dest = dest + new_len; memcpy (dest, pos + orig_len, str_len - (pos - str) - orig_len); return ret; } /** * strstrip: (skip) * * Strips leading and trailing whitespace from the string (**IN-PLACE**) */ static void strstrip(char *str) { int i = 0; int begin = 0; int end = strlen(str) - 1; while (isspace(str[begin])) begin++; while ((end >= begin) && isspace(str[end])) end--; for (i=begin; i <= end; i++) str[i - begin] = str[i]; str[i-begin] = '\0'; } static bool multiply_size_by_unit (mpfr_t size, char *unit_str) { BSBunit bunit = BS_BUNIT_UNDEF; BSDunit dunit = BS_DUNIT_UNDEF; uint64_t pwr = 0; mpfr_t dec_mul; size_t unit_str_len = 0; unit_str_len = strlen (unit_str); for (bunit=BS_BUNIT_B; bunit < BS_BUNIT_UNDEF; bunit++) if (strncasecmp (unit_str, b_units[bunit-BS_BUNIT_B], unit_str_len) == 0) { pwr = (uint64_t) bunit - BS_BUNIT_B; mpfr_mul_2exp (size, size, 10 * pwr, MPFR_RNDN); return true; } mpfr_init2 (dec_mul, BS_FLOAT_PREC_BITS); mpfr_set_ui (dec_mul, 1000, MPFR_RNDN); for (dunit=BS_DUNIT_B; dunit < BS_DUNIT_UNDEF; dunit++) if (strncasecmp (unit_str, d_units[dunit-BS_DUNIT_B], unit_str_len) == 0) { pwr = (uint64_t) (dunit - BS_DUNIT_B); mpfr_pow_ui (dec_mul, dec_mul, pwr, MPFR_RNDN); mpfr_mul (size, size, dec_mul, MPFR_RNDN); mpfr_clear (dec_mul); return true; } /* not found among the binary and decimal units, let's try their translated verions */ for (bunit=BS_BUNIT_B; bunit < BS_BUNIT_UNDEF; bunit++) if (strncasecmp (unit_str, _(b_units[bunit-BS_BUNIT_B]), unit_str_len) == 0) { pwr = (uint64_t) bunit - BS_BUNIT_B; mpfr_mul_2exp (size, size, 10 * pwr, MPFR_RNDN); return true; } mpfr_init2 (dec_mul, BS_FLOAT_PREC_BITS); mpfr_set_ui (dec_mul, 1000, MPFR_RNDN); for (dunit=BS_DUNIT_B; dunit < BS_DUNIT_UNDEF; dunit++) if (strncasecmp (unit_str, _(d_units[dunit-BS_DUNIT_B]), unit_str_len) == 0) { pwr = (uint64_t) (dunit - BS_DUNIT_B); mpfr_pow_ui (dec_mul, dec_mul, pwr, MPFR_RNDN); mpfr_mul (size, size, dec_mul, MPFR_RNDN); mpfr_clear (dec_mul); return true; } return false; } /** * set_error: (skip) * * Sets @error to @code and @msg (if not %NULL). **TAKES OVER @msg.** */ static void set_error (BSError **error, BSErrorCode code, char *msg) { *error = (BSError *) malloc (sizeof(BSError)); (*error)->code = code; (*error)->msg = msg; return; } typedef void (*MpzOp) (mpz_t ROP, const mpz_t OP1, unsigned long int OP2); static void do_64bit_add_sub (MpzOp op, mpz_t rop, const mpz_t op1, uint64_t op2) { uint64_t i = 0; uint64_t div = 0; uint64_t mod = 0; /* small enough to just work */ if (op2 < (uint64_t) ULONG_MAX) { op (rop, op1, (unsigned long int) op2); return; } mpz_set (rop, op1); div = op2 / (uint64_t) ULONG_MAX; mod = op2 % (uint64_t) ULONG_MAX; for (i=0; i < div; i++) op (rop, rop, (unsigned long int) ULONG_MAX); op (rop, rop, (unsigned long int) mod); } static void mul_64bit (mpz_t rop, const mpz_t op1, uint64_t op2) { uint64_t i = 0; uint64_t div = 0; uint64_t mod = 0; mpz_t aux; mpz_t res; /* small enough to just work */ if (op2 < (uint64_t) ULONG_MAX) { mpz_mul_ui (rop, op1, (unsigned long int) op2); return; } mpz_init2 (aux, (mp_bitcnt_t) 64); mpz_init2 (res, (mp_bitcnt_t) 64); mpz_set_ui (res, 0); div = op2 / (uint64_t) ULONG_MAX; mod = op2 % (uint64_t) ULONG_MAX; for (i=0; i < div; i++) { mpz_mul_ui (aux, op1, (unsigned long int) ULONG_MAX); mpz_add (res, res, aux); } mpz_mul_ui (aux, op1, (unsigned long int) mod); mpz_add (res, res, aux); mpz_set (rop, res); mpz_clear (aux); mpz_clear (res); } /*************** * DESTRUCTORS * * *************/ /** * bs_size_free: * * Clears @size and frees the allocated resources. */ void bs_size_free (BSSize size) { if (size) { mpz_clear (size->bytes); free (size); } return; } /** * bs_clear_error: * * Clears @error and frees the allocated resources. */ void bs_clear_error (BSError **error) { if (error && *error) { free ((*error)->msg); free (*error); *error = NULL; } return; } /**************** * CONSTRUCTORS * ****************/ /** * bs_size_new: (constructor) * * Creates a new #BSSize instance initialized to 0. * * Returns: a new #BSSize initialized to 0. */ BSSize bs_size_new (void) { BSSize ret = (BSSize) malloc (sizeof(struct _BSSize)); bs_size_init (ret); return ret; } /** * bs_size_new_from_bytes: (constructor) * @bytes: number of bytes * @sgn: sign of the size -- if being -1, the size is initialized to * -@bytes, other values are ignored * * Creates a new #BSSize instance. * * Returns: a new #BSSize */ BSSize bs_size_new_from_bytes (uint64_t bytes, int sgn) { char *num_str = NULL; BSSize ret = bs_size_new (); int ok = 0; ok = asprintf (&num_str, "%"PRIu64, bytes); if (ok == -1) /* probably cannot allocate memory, there's nothing more we can do */ return ret; mpz_set_str (ret->bytes, num_str, 10); free (num_str); if (sgn == -1) mpz_neg (ret->bytes, ret->bytes); return ret; } /** * bs_size_new_from_str: (constructor) * @size_str: string representing the size as a number and an optional unit * (e.g. "1 GiB") * * Creates a new #BSSize instance. * * Returns: a new #BSSize */ BSSize bs_size_new_from_str (const char *size_str, BSError **error) { char const * const pattern = "^\\s* # white space \n" \ "(?P # the numeric part consists of three parts, below \n" \ " (-|\\+)? # optional sign character \n" \ " (?P([0-9\\.%s]+)) # base \n" \ " (?P(e|E)(-|\\+)?[0-9]+)?) # exponent \n" \ "\\s* # white space \n" \ "(?P[^\\s]*)\\s*$ # unit specification"; char *real_pattern = NULL; pcre2_code *regex = NULL; int errorcode = 0; PCRE2_SIZE erroffset; int str_len = 0; pcre2_match_data *match_data = NULL; int str_count = 0; char *num_str = NULL; const char *radix_char = NULL; char *loc_size_str = NULL; mpf_t parsed_size; mpfr_t size; int status = 0; char *unit_str = NULL; BSSize ret = NULL; PCRE2_UCHAR *substring = NULL; PCRE2_SIZE substring_len = 0; PCRE2_UCHAR error_buffer[ERROR_BUFFER_LEN]; radix_char = nl_langinfo (RADIXCHAR); if (strncmp (radix_char, ".", 1) != 0) real_pattern = strdup_printf (pattern, radix_char); else real_pattern = strdup_printf (pattern, ""); regex = pcre2_compile ((PCRE2_SPTR) real_pattern, PCRE2_ZERO_TERMINATED, PCRE2_EXTENDED, &errorcode, &erroffset, NULL); free (real_pattern); if (!regex) { status = pcre2_get_error_message (errorcode, error_buffer, ERROR_BUFFER_LEN); switch (status) { case PCRE2_ERROR_BADDATA: // unknown/invalid error code set_error (error, BS_ERROR_INVALID_SPEC, strdup_printf ("Failed to compile pattern at offset %d: Unknown error.", erroffset)); break; case PCRE2_ERROR_NOMEMORY: // error buffer is too short set_error (error, BS_ERROR_INVALID_SPEC, strdup_printf ("Failed to compile pattern at offset %d: %s (truncated)", erroffset, error_buffer)); break; default: set_error (error, BS_ERROR_INVALID_SPEC, strdup_printf ("Failed to compile pattern at offset %d: %s", erroffset, error_buffer)); break; } return NULL; } loc_size_str = replace_char_with_str (size_str, '.', radix_char); str_len = strlen (loc_size_str); match_data = pcre2_match_data_create_from_pattern (regex, NULL); str_count = pcre2_match (regex, (PCRE2_SPTR) loc_size_str, str_len, 0, 0, match_data, NULL); if (str_count < 0) { set_error (error, BS_ERROR_INVALID_SPEC, strdup_printf ("Failed to parse size spec: %s", size_str)); pcre2_match_data_free (match_data); pcre2_code_free (regex); free (loc_size_str); return NULL; } status = pcre2_substring_get_byname (match_data, (PCRE2_SPTR) "numeric", &substring, &substring_len); if (status < 0) { set_error (error, BS_ERROR_INVALID_SPEC, strdup_printf ("Failed to parse size spec: %s", size_str)); pcre2_match_data_free (match_data); pcre2_code_free (regex); free (loc_size_str); return NULL; } num_str = strndup ((const char*) substring, substring_len); /* parse the number using GMP because it knows how to handle localization much better than MPFR */ mpf_init2 (parsed_size, BS_FLOAT_PREC_BITS); status = mpf_set_str (parsed_size, *num_str == '+' ? num_str+1 : num_str, 10); free (num_str); if (status != 0) { set_error (error, BS_ERROR_INVALID_SPEC, strdup_printf ("Failed to parse size spec: %s", size_str)); pcre2_match_data_free (match_data); pcre2_code_free (regex); free (loc_size_str); mpf_clear (parsed_size); return NULL; } /* but use MPFR from now on because GMP thinks 0.1*1000 = 99 */ mpfr_init2 (size, BS_FLOAT_PREC_BITS); mpfr_set_f (size, parsed_size, MPFR_RNDN); mpf_clear (parsed_size); status = pcre2_substring_get_byname (match_data, (PCRE2_SPTR) "rest", &substring, &substring_len); unit_str = strndup ((const char*) substring, substring_len); if ((status >= 0) && strncmp (unit_str, "", 1) != 0) { strstrip (unit_str); if (!multiply_size_by_unit (size, unit_str)) { set_error (error, BS_ERROR_INVALID_SPEC, strdup_printf ("Failed to recognize unit from the spec: %s", size_str)); free (unit_str); pcre2_match_data_free (match_data); pcre2_code_free (regex); free (loc_size_str); mpfr_clear (size); return NULL; } } free (unit_str); pcre2_match_data_free (match_data); pcre2_code_free (regex); ret = bs_size_new (); mpfr_get_z (ret->bytes, size, MPFR_RNDZ); free (loc_size_str); mpfr_clear (size); return ret; } /** * bs_size_new_from_size: (constructor) * @size: the size to create a new instance from (a copy of) * * Creates a new instance of #BSSize. * * Returns: (transfer full): a new #BSSize instance which is copy of @size. */ BSSize bs_size_new_from_size (const BSSize size) { BSSize ret = NULL; ret = bs_size_new (); mpz_set (ret->bytes, size->bytes); return ret; } /***************** * QUERY METHODS * *****************/ /** * bs_size_get_bytes: * @sgn: (allow-none) (out): sign of the @size - -1, 0 or 1 for negative, zero or positive * size respectively * * Get the number of bytes of the @size. * * Returns: the @size in a number of bytes */ uint64_t bs_size_get_bytes (const BSSize size, int *sgn, BSError **error) { char *num_str = NULL; mpz_t max; uint64_t ret = 0; int ok = 0; mpz_init2 (max, (mp_bitcnt_t) 64); ok = asprintf (&num_str, "%"PRIu64, UINT64_MAX); if (ok == -1) { /* we probably cannot allocate memory so we are doomed */ set_error (error, BS_ERROR_FAIL, strdup("Failed to allocate memory")); mpz_clear (max); return 0; } mpz_set_str (max, num_str, 10); free (num_str); if (mpz_cmp (size->bytes, max) > 0) { set_error (error, BS_ERROR_OVER, strdup("The size is too big, cannot be returned as a 64bit number of bytes")); return 0; } mpz_clear (max); if (sgn) *sgn = mpz_sgn (size->bytes); if (mpz_cmp_ui (size->bytes, UINT64_MAX) <= 0) return (uint64_t) mpz_get_ui (size->bytes); else { num_str = bs_size_get_bytes_str (size); ret = strtoull (num_str, NULL, 10); free (num_str); return ret; } } /** * bs_size_sgn: * * Get the sign of the size. * * Returns: -1, 0 or 1 if @size is negative, zero or positive, respectively */ int bs_size_sgn (const BSSize size) { return mpz_sgn (size->bytes); } /** * bs_size_get_bytes_str: * * Get the number of bytes in @size as a string. This way, the caller doesn't * have to care about the limitations of some particular integer type. * * Returns: (transfer full): the string representing the @size as a number of bytes. */ char* bs_size_get_bytes_str (const BSSize size) { return mpz_get_str (NULL, 10, size->bytes); } /** * bs_size_convert_to: * @unit: the unit to convert @size to * * Get the @size converted to @unit as a string representing a floating-point * number. * * Returns: (transfer full): a string representing the floating-point number * that equals to @size converted to @unit */ char* bs_size_convert_to (const BSSize size, BSUnit unit, BSError **error) { BSBunit b_unit = BS_BUNIT_B; BSDunit d_unit = BS_DUNIT_B; mpf_t divisor; mpf_t result; bool found_match = false; char *ret = NULL; mpf_init2 (divisor, BS_FLOAT_PREC_BITS); for (b_unit = BS_BUNIT_B; !found_match && b_unit != BS_BUNIT_UNDEF; b_unit++) { if (unit.bunit == b_unit) { found_match = true; mpf_set_ui (divisor, 1); mpf_mul_2exp (divisor, divisor, 10 * (b_unit - BS_BUNIT_B)); } } for (d_unit = BS_DUNIT_B; !found_match && d_unit != BS_DUNIT_UNDEF; d_unit++) { if (unit.dunit == d_unit) { found_match = true; mpf_set_ui (divisor, 1000); mpf_pow_ui (divisor, divisor, (d_unit - BS_DUNIT_B)); } } if (!found_match) { set_error (error, BS_ERROR_INVALID_SPEC, "Invalid unit spec given"); mpf_clear (divisor); return NULL; } mpf_init2 (result, BS_FLOAT_PREC_BITS); mpf_set_z (result, size->bytes); mpf_div (result, result, divisor); gmp_asprintf (&ret, "%.*Fg", BS_FLOAT_PREC_BITS/3, result); mpf_clears (divisor, result, NULL); return ret; } /** * bs_size_human_readable: * @min_unit: the smallest unit the returned representation should use * @max_places: maximum number of decimal places the representation should use * @xlate: whether to try to translate the representation or not * * Get a human-readable representation of @size. * * Returns: (transfer full): a string which is human-readable representation of * @size according to the restrictions given by the * other parameters */ char* bs_size_human_readable (const BSSize size, BSBunit min_unit, int max_places, bool xlate) { mpf_t cur_val; char *num_str = NULL; char *ret = NULL; int len = 0; char *zero = NULL; char *radix_char = NULL; int sign = 0; char *loc_num_str = NULL; bool at_radix = false; mpf_init2 (cur_val, BS_FLOAT_PREC_BITS); mpf_set_z (cur_val, size->bytes); if (min_unit == BS_BUNIT_UNDEF) min_unit = BS_BUNIT_B; sign = mpf_sgn (cur_val); mpf_abs (cur_val, cur_val); mpf_div_2exp (cur_val, cur_val, 10 * (min_unit - BS_BUNIT_B)); while ((mpf_cmp_ui (cur_val, 1024) > 0) && min_unit != BS_BUNIT_YiB) { mpf_div_2exp (cur_val, cur_val, 10); min_unit++; } if (sign == -1) mpf_neg (cur_val, cur_val); len = gmp_asprintf (&num_str, "%.*Ff", max_places >= 0 ? max_places : BS_FLOAT_PREC_BITS, cur_val); mpf_clear (cur_val); /* should use the proper radix char according to @xlate */ radix_char = nl_langinfo (RADIXCHAR); if (!xlate) { loc_num_str = replace_str_with_str (num_str, radix_char, "."); free (num_str); radix_char = "."; } else loc_num_str = num_str; /* remove trailing zeros and the radix char */ /* if max_places == 0, there can't be anything trailing */ if (max_places != 0) { zero = loc_num_str + (len - 1); while ((zero != loc_num_str) && ((*zero == '0') || (*zero == *radix_char)) && !at_radix) { at_radix = *zero == *radix_char; zero--; } zero[1] = '\0'; } ret = strdup_printf ("%s %s", loc_num_str, xlate ? _(b_units[min_unit - BS_BUNIT_B]) : b_units[min_unit - BS_BUNIT_B]); free (loc_num_str); return ret; } /*************** * ARITHMETIC * ***************/ /** * bs_size_add: * * Add two sizes. * * Returns: (transfer full): a new instance of #BSSize which is a sum of @size1 and @size2 */ BSSize bs_size_add (const BSSize size1, const BSSize size2) { BSSize ret = bs_size_new (); mpz_add (ret->bytes, size1->bytes, size2->bytes); return ret; } /** * bs_size_grow: * * Grows @size1 by @size2. IOW, adds @size2 to @size1 in-place (modifying * @size1). * * Basically an in-place variant of bs_size_add(). * * Returns: (transfer none): @size1 modified by adding @size2 to it */ BSSize bs_size_grow (BSSize size1, const BSSize size2) { mpz_add (size1->bytes, size1->bytes, size2->bytes); return size1; } /** * bs_size_add_bytes: * * Add @bytes to the @size. To add a negative number of bytes use * bs_size_sub_bytes(). * * Returns: (transfer full): a new instance of #BSSize which is a sum of @size and @bytes */ BSSize bs_size_add_bytes (const BSSize size, uint64_t bytes) { BSSize ret = bs_size_new (); do_64bit_add_sub (mpz_add_ui, ret->bytes, size->bytes, bytes); return ret; } /** * bs_size_grow_bytes: * * Grows @size by @bytes. IOW, adds @bytes to @size in-place (modifying @size). * * Basically an in-place variant of bs_size_add_bytes(). * * Returns: (transfer none): @size modified by adding @bytes to it */ BSSize bs_size_grow_bytes (BSSize size, const uint64_t bytes) { do_64bit_add_sub (mpz_add_ui, size->bytes, size->bytes, bytes); return size; } /** * bs_size_sub: * * Subtract @size2 from @size1. * * Returns: (transfer full): a new instance of #BSSize which is equals to @size1 - @size2 */ BSSize bs_size_sub (const BSSize size1, const BSSize size2) { BSSize ret = bs_size_new (); mpz_sub (ret->bytes, size1->bytes, size2->bytes); return ret; } /** * bs_size_shrink: * * Shrinks @size1 by @size2. IOW, subtracts @size2 from @size1 in-place * (modifying @size1). * * Basically an in-place variant of bs_size_sub(). * * Returns: (transfer none): @size1 modified by subtracting @size2 from it */ BSSize bs_size_shrink (BSSize size1, const BSSize size2) { mpz_sub (size1->bytes, size1->bytes, size2->bytes); return size1; } /** * bs_size_sub_bytes: * * Subtract @bytes from the @size. To subtract a negative number of bytes use * bs_size_add_bytes(). * * Returns: (transfer full): a new instance of #BSSize which equals to @size - @bytes */ BSSize bs_size_sub_bytes (const BSSize size, uint64_t bytes) { BSSize ret = bs_size_new (); do_64bit_add_sub (mpz_sub_ui, ret->bytes, size->bytes, bytes); return ret; } /** * bs_size_shrink_bytes: * * Shrinks @size by @bytes. IOW, subtracts @bytes from @size in-place * (modifying @size). To shrink by a negative number of bytes use * bs_size_grow_bytes(). * * Basically an in-place variant of bs_size_sub_bytes(). * * Returns: (transfer none): @size modified by subtracting @bytes from it */ BSSize bs_size_shrink_bytes (BSSize size, uint64_t bytes) { do_64bit_add_sub (mpz_sub_ui, size->bytes, size->bytes, bytes); return size; } /** * bs_size_mul_int: * * Multiply @size by @times. * * Returns: (transfer full): a new instance of #BSSize which equals to @size * @times */ BSSize bs_size_mul_int (const BSSize size, uint64_t times) { BSSize ret = bs_size_new (); mul_64bit (ret->bytes, size->bytes, times); return ret; } /** * bs_size_grow_mul_int: * * Grow @size @times times. IOW, multiply @size by @times in-place. * * Basically an in-place variant of bs_size_mul_int(). * * Returns: (transfer none): @size modified by growing it @times times */ BSSize bs_size_grow_mul_int (BSSize size, uint64_t times) { mul_64bit (size->bytes, size->bytes, times); return size; } /** * bs_size_mul_float_str: * * Multiply @size by the floating-point number @float_str represents. * * Returns: (transfer full): a new #BSSize instance which equals to * @size * @times_str * */ BSSize bs_size_mul_float_str (const BSSize size, const char *float_str, BSError **error) { mpf_t op1, op2; int status = 0; BSSize ret = NULL; const char *radix_char = NULL; char *loc_float_str = NULL; radix_char = nl_langinfo (RADIXCHAR); mpf_init2 (op1, BS_FLOAT_PREC_BITS); mpf_init2 (op2, BS_FLOAT_PREC_BITS); mpf_set_z (op1, size->bytes); loc_float_str = replace_char_with_str (float_str, '.', radix_char); status = mpf_set_str (op2, loc_float_str, 10); if (status != 0) { set_error (error, BS_ERROR_INVALID_SPEC, strdup_printf ("'%s' is not a valid floating point number string", loc_float_str)); free (loc_float_str); mpf_clears (op1, op2, NULL); return NULL; } free (loc_float_str); mpf_mul (op1, op1, op2); ret = bs_size_new (); mpz_set_f (ret->bytes, op1); mpf_clears (op1, op2, NULL); return ret; } /** * bs_size_grow_mul_float_str: * * Grow @size by the floating-point number @float_str represents times. IOW, * multiply @size by @float_str in-place. * * Basically an in-place variant of bs_size_grow_mul_float_str(). * * Returns: (transfer none): @size modified by growing it @float_str times. */ BSSize bs_size_grow_mul_float_str (BSSize size, const char *float_str, BSError **error) { mpf_t op1, op2; int status = 0; const char *radix_char = NULL; char *loc_float_str = NULL; radix_char = nl_langinfo (RADIXCHAR); mpf_init2 (op1, BS_FLOAT_PREC_BITS); mpf_init2 (op2, BS_FLOAT_PREC_BITS); mpf_set_z (op1, size->bytes); loc_float_str = replace_char_with_str (float_str, '.', radix_char); status = mpf_set_str (op2, loc_float_str, 10); if (status != 0) { set_error (error, BS_ERROR_INVALID_SPEC, strdup_printf ("'%s' is not a valid floating point number string", loc_float_str)); free (loc_float_str); mpf_clears (op1, op2, NULL); return NULL; } free (loc_float_str); mpf_mul (op1, op1, op2); mpz_set_f (size->bytes, op1); mpf_clears (op1, op2, NULL); return size; } /** * bs_size_div: * @sgn: (allow-none) (out): sign of the result * * Divide @size1 by @size2. Gives the answer to the question "How many times * does @size2 fit in @size1?". * * Returns: integer number x so that x * @size1 < @size2 and (x+1) * @size1 > @size2 * (IOW, @size1 / @size2 using integer division) */ uint64_t bs_size_div (const BSSize size1, const BSSize size2, int *sgn, BSError **error) { mpz_t result; uint64_t ret = 0; if (mpz_cmp_ui (size2->bytes, 0) == 0) { set_error (error, BS_ERROR_ZERO_DIV, strdup_printf ("Division by zero")); return 0; } if (sgn) *sgn = mpz_sgn (size1->bytes) * mpz_sgn (size2->bytes); mpz_init (result); mpz_tdiv_q (result, size1->bytes, size2->bytes); if (mpz_cmp_ui (result, UINT64_MAX) > 0) { set_error (error, BS_ERROR_OVER, strdup_printf ("The size is too big, cannot be returned as a 64bit number")); mpz_clear (result); return 0; } ret = (uint64_t) mpz_get_ui (result); mpz_clear (result); return ret; } /** * bs_size_div_int: * * Divide @size by @divisor. Gives the answer to the question "What is the size * of each chunk if @size is split into a @divisor number of pieces?" * * Note: Due to the limitations of the current implementation the maximum value * @divisor is ULONG_MAX (which can differ from UINT64_MAX). An error * (BS_ERROR_OVER) is returned if overflow happens. * * Returns: (transfer full): a #BSSize instance x so that x * @divisor = @size, * rounded to a number of bytes */ BSSize bs_size_div_int (const BSSize size, uint64_t divisor, BSError **error) { BSSize ret = NULL; if (divisor == 0) { set_error (error, BS_ERROR_ZERO_DIV, strdup_printf ("Division by zero")); return NULL; } else if (divisor > ULONG_MAX) { set_error (error, BS_ERROR_OVER, strdup_printf ("Divisor too big, must be less or equal to %lu", ULONG_MAX)); return NULL; } ret = bs_size_new (); mpz_tdiv_q_ui (ret->bytes, size->bytes, divisor); return ret; } /** * bs_size_shrink_div_int: * * Shrink @size by dividing by @divisor. IOW, divide @size by @divisor in-place. * * Basically an in-place variant of bs_size_div_int(). * * Note: Due to the limitations of the current implementation the maximum value * @divisor is ULONG_MAX (which can differ from UINT64_MAX). An error * (BS_ERROR_OVER) is returned if overflow happens. * * Returns: (transfer none): @size modified by division by @divisor */ BSSize bs_size_shrink_div_int (BSSize size, uint64_t divisor, BSError **error) { if (divisor == 0) { set_error (error, BS_ERROR_ZERO_DIV, strdup_printf ("Division by zero")); return NULL; } else if (divisor > ULONG_MAX) { set_error (error, BS_ERROR_OVER, strdup_printf ("Divisor too big, must be less or equal to %lu", ULONG_MAX)); return NULL; } mpz_tdiv_q_ui (size->bytes, size->bytes, divisor); return size; } /** * bs_size_true_div: * * Divides @size1 by @size2. * * Returns: (transfer full): a string representing the floating-point number * that equals to @size1 / @size2 */ char* bs_size_true_div (const BSSize size1, const BSSize size2, BSError **error) { mpf_t op1; mpf_t op2; char *ret = NULL; if (mpz_cmp_ui (size2->bytes, 0) == 0) { set_error (error, BS_ERROR_ZERO_DIV, strdup_printf("Division by zero")); return 0; } mpf_init2 (op1, BS_FLOAT_PREC_BITS); mpf_init2 (op2, BS_FLOAT_PREC_BITS); mpf_set_z (op1, size1->bytes); mpf_set_z (op2, size2->bytes); mpf_div (op1, op1, op2); gmp_asprintf (&ret, "%.*Fg", BS_FLOAT_PREC_BITS/3, op1); mpf_clears (op1, op2, NULL); return ret; } /** * bs_size_true_div_int: * * Divides @size by @divisor. * * Note: Due to the limitations of the current implementation the maximum value * @divisor is ULONG_MAX (which can differ from UINT64_MAX). An error * (BS_ERROR_OVER) is returned if overflow happens. * * Returns: (transfer full): a string representing the floating-point number * that equals to @size / @divisor */ char* bs_size_true_div_int (const BSSize size, uint64_t divisor, BSError **error) { mpf_t op1; char *ret = NULL; if (divisor == 0) { set_error (error, BS_ERROR_ZERO_DIV, strdup_printf ("Division by zero")); return 0; } else if (divisor > ULONG_MAX) { set_error (error, BS_ERROR_OVER, strdup_printf ("Divisor too big, must be less or equal to %lu", ULONG_MAX)); return NULL; } mpf_init2 (op1, BS_FLOAT_PREC_BITS); mpf_set_z (op1, size->bytes); mpf_div_ui (op1, op1, divisor); gmp_asprintf (&ret, "%.*Fg", BS_FLOAT_PREC_BITS/3, op1); mpf_clear (op1); return ret; } /** * bs_size_mod: * * Gives @size1 modulo @size2 (i.e. the remainder of integer division @size1 / * @size2). Gives the answer to the question "If I split @size1 into chunks of * size @size2, what will be the remainder?" * **This function ignores the signs of the sizes.** * * Returns: (transfer full): a #BSSize instance that is a remainder of * @size1 / @size2 using integer division */ BSSize bs_size_mod (const BSSize size1, const BSSize size2, BSError **error) { mpz_t aux; BSSize ret = NULL; if (mpz_cmp_ui (size2->bytes, 0) == 0) { set_error (error, BS_ERROR_ZERO_DIV, strdup_printf ("Division by zero")); return 0; } mpz_init (aux); mpz_set (aux, size1->bytes); if (mpz_sgn (size1->bytes) == -1) /* negative @size1, get the absolute value so that we get results matching the specification/documentation of this function */ mpz_neg (aux, aux); ret = bs_size_new (); mpz_mod (ret->bytes, aux, size2->bytes); return ret; } /** * bs_size_round_to_nearest: * @round_to: to a multiple of what to round @size * @dir: %BS_ROUND_DIR_UP to round up (to the nearest multiple of @round_to * bigger than @size) or %BS_ROUND_DIR_DOWN to round down (to the * nearest multiple of @round_to smaller than @size) * * Round @size to the nearest multiple of @round_to according to the direction * given by @dir. * * Returns: (transfer full): a new instance of #BSSize that is @size rounded to * a multiple of @round_to according to @dir */ BSSize bs_size_round_to_nearest (const BSSize size, const BSSize round_to, BSRoundDir dir, BSError **error) { BSSize ret = NULL; mpz_t q; mpz_t aux_size; if (mpz_cmp_ui (round_to->bytes, 0) == 0) { set_error (error, BS_ERROR_ZERO_DIV, strdup_printf ("Division by zero")); return NULL; } mpz_init (q); if (dir == BS_ROUND_DIR_UP) { mpz_cdiv_q (q, size->bytes, round_to->bytes); } else if (dir == BS_ROUND_DIR_HALF_UP) { /* round half up == add half of what to round to and round down */ mpz_init (aux_size); mpz_fdiv_q_ui (aux_size, round_to->bytes, 2); mpz_add (aux_size, aux_size, size->bytes); mpz_fdiv_q (q, aux_size, round_to->bytes); mpz_clear (aux_size); } else mpz_fdiv_q (q, size->bytes, round_to->bytes); ret = bs_size_new (); mpz_mul (ret->bytes, q, round_to->bytes); mpz_clear (q); return ret; } /*************** * COMPARISONS * ***************/ /** * bs_size_cmp: * @abs: whether to compare absolute values of @size1 and @size2 instead * * Compare @size1 and @size2. This function behaves like the standard *cmp*() * functions. * * Returns: -1, 0, or 1 if @size1 is smaller, equal to or bigger than * @size2 respectively comparing absolute values if @abs is %true */ int bs_size_cmp (const BSSize size1, const BSSize size2, bool abs) { int ret = 0; if (abs) ret = mpz_cmpabs (size1->bytes, size2->bytes); else ret = mpz_cmp (size1->bytes, size2->bytes); /* make sure we don't return things like 2 or -2 (which GMP can give us) */ if (ret > 0) ret = 1; else if (ret < 0) ret = -1; return ret; } /** * bs_size_cmp_bytes: * @abs: whether to compare absolute values of @size and @bytes instead. * * Compare @size and @bytes, i.e. the number of bytes @size has with * @bytes. This function behaves like the standard *cmp*() functions. * * Returns: -1, 0, or 1 if @size is smaller, equal to or bigger than * @bytes respectively comparing absolute values if @abs is %true */ int bs_size_cmp_bytes (const BSSize size, uint64_t bytes, bool abs) { int ret = 0; if (abs) ret = mpz_cmpabs_ui (size->bytes, bytes); else ret = mpz_cmp_ui (size->bytes, bytes); /* make sure we don't return things like 2 or -2 (which GMP can give us) */ if (ret > 0) ret = 1; else if (ret < 0) ret = -1; return ret; } libbytesize-2.2/src/bs_size.h000066400000000000000000000100111361502636100162740ustar00rootroot00000000000000#ifndef _BS_SIZE_H #define _BS_SIZE_H #include #include /** * BSSize: * An opaque type representing a size in bytes. */ typedef struct _BSSize * BSSize; /** * BSErrorCode: * * @BS_ERROR_INVALID_SPEC: invalid size or unit spec provided * @BS_ERROR_OVER: a value is over the limits imposed by a type * @BS_ERROR_ZERO_DIV: an attempt to do division by zero * * Error codes that identify various errors that can occur while working with * #BSSize instances. */ typedef enum { BS_ERROR_INVALID_SPEC, BS_ERROR_OVER, BS_ERROR_ZERO_DIV, BS_ERROR_FAIL } BSErrorCode; /** * BSError: * * @code: error code * @msg: optional error message */ typedef struct _BSError { BSErrorCode code; char *msg; } BSError; /** * BSBunit: * * Binary units (multiples of 1024) of size in bytes. */ typedef enum { BS_BUNIT_B = 0, BS_BUNIT_KiB, BS_BUNIT_MiB, BS_BUNIT_GiB, BS_BUNIT_TiB, BS_BUNIT_PiB, BS_BUNIT_EiB, BS_BUNIT_ZiB, BS_BUNIT_YiB, BS_BUNIT_UNDEF, } BSBunit; /** * BSDunit: * * Decimal units (multiples of 1000) of size in bytes. */ typedef enum { BS_DUNIT_B = 20, BS_DUNIT_KB, BS_DUNIT_MB, BS_DUNIT_GB, BS_DUNIT_TB, BS_DUNIT_PB, BS_DUNIT_EB, BS_DUNIT_ZB, BS_DUNIT_YB, BS_DUNIT_UNDEF, } BSDunit; /** * BSRoundDir: * * Rounding direction for rounding operations. */ typedef enum { BS_ROUND_DIR_UP = 0, BS_ROUND_DIR_DOWN = 1, BS_ROUND_DIR_HALF_UP = 2 } BSRoundDir; /** * BSUnit: * @bunit: a binary unit * @dunit: a decimal unit * * Generic unit fo size in bytes. */ typedef union { BSBunit bunit; BSDunit dunit; } BSUnit; /* use 256 bits of precision for floating point numbets, that should be more than enough */ /** * BS_FLOAT_PREC_BITS: * * Precision (in bits) of floating-point numbers used internally. */ #define BS_FLOAT_PREC_BITS 256 /* Constructors */ BSSize bs_size_new (void); BSSize bs_size_new_from_bytes (uint64_t bytes, int sgn); BSSize bs_size_new_from_str (const char *size_str, BSError **error); BSSize bs_size_new_from_size (const BSSize size); /* Destructors */ void bs_size_free (BSSize size); void bs_clear_error (BSError **error); /* Query functions */ uint64_t bs_size_get_bytes (const BSSize size, int *sgn, BSError **error); int bs_size_sgn (const BSSize size); char* bs_size_get_bytes_str (const BSSize size); char* bs_size_convert_to (const BSSize size, BSUnit unit, BSError **error); char* bs_size_human_readable (const BSSize size, BSBunit min_unit, int max_places, bool xlate); /* Arithmetic */ BSSize bs_size_add (const BSSize size1, const BSSize size2); BSSize bs_size_grow (BSSize size1, const BSSize size2); BSSize bs_size_add_bytes (const BSSize size, uint64_t bytes); BSSize bs_size_grow_bytes (BSSize size, uint64_t bytes); BSSize bs_size_sub (const BSSize size1, const BSSize size2); BSSize bs_size_shrink (BSSize size1, const BSSize size2); BSSize bs_size_sub_bytes (const BSSize size, uint64_t bytes); BSSize bs_size_shrink_bytes (BSSize size, uint64_t bytes); BSSize bs_size_mul_int (const BSSize size, uint64_t times); BSSize bs_size_grow_mul_int (BSSize size, uint64_t times); BSSize bs_size_mul_float_str (const BSSize size, const char *float_str, BSError **error); BSSize bs_size_grow_mul_float_str (BSSize size, const char *float_str, BSError **error); uint64_t bs_size_div (const BSSize size1, const BSSize size2, int *sgn, BSError **error); BSSize bs_size_div_int (const BSSize size, uint64_t divisor, BSError **error); BSSize bs_size_shrink_div_int (BSSize size, uint64_t shrink_divisor, BSError **error); char* bs_size_true_div (const BSSize size1, const BSSize size2, BSError **error); char* bs_size_true_div_int (const BSSize size, uint64_t divisor, BSError **error); BSSize bs_size_mod (const BSSize size1, const BSSize size2, BSError **error); BSSize bs_size_round_to_nearest (const BSSize size, const BSSize round_to, BSRoundDir dir, BSError **error); /* Comparisons */ int bs_size_cmp (const BSSize size1, const BSSize size2, bool abs); int bs_size_cmp_bytes (const BSSize size1, uint64_t bytes, bool abs); #endif /* _BS_SIZE_H */ libbytesize-2.2/src/bytesize.pc.in000066400000000000000000000004501361502636100172620ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ includedir=@includedir@ libdir=@libdir@ Name: ByteSize Description: Library for working with sizes in bytes URL: https://github.com/storaged-project/libbytesize Version: 0.1.0 Cflags: -I${includedir}/bytesize Libs: -lbytesize Libs.private: -lgmp -lmpfr libbytesize-2.2/src/gettext.h000066400000000000000000000234671361502636100163450ustar00rootroot00000000000000/* Convenience header for conditional use of GNU . Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2015 Free Software Foundation, 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, 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ #ifndef _LIBGETTEXT_H #define _LIBGETTEXT_H 1 /* NLS can be disabled through the configure --disable-nls option. */ #if ENABLE_NLS /* Get declarations of GNU message catalog functions. */ # include /* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by the gettext() and ngettext() macros. This is an alternative to calling textdomain(), and is useful for libraries. */ # ifdef DEFAULT_TEXT_DOMAIN # undef gettext # define gettext(Msgid) \ dgettext (DEFAULT_TEXT_DOMAIN, Msgid) # undef ngettext # define ngettext(Msgid1, Msgid2, N) \ dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N) # endif #else /* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which chokes if dcgettext is defined as a macro. So include it now, to make later inclusions of a NOP. We don't include as well because people using "gettext.h" will not include , and also including would fail on SunOS 4, whereas is OK. */ #if defined(__sun) # include #endif /* Many header files from the libstdc++ coming with g++ 3.3 or newer include , which chokes if dcgettext is defined as a macro. So include it now, to make later inclusions of a NOP. */ #if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3) # include # if (__GLIBC__ >= 2 && !defined __UCLIBC__) || _GLIBCXX_HAVE_LIBINTL_H # include # endif #endif /* Disabled NLS. The casts to 'const char *' serve the purpose of producing warnings for invalid uses of the value returned from these functions. On pre-ANSI systems without 'const', the config.h file is supposed to contain "#define const". */ # undef gettext # define gettext(Msgid) ((const char *) (Msgid)) # undef dgettext # define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid)) # undef dcgettext # define dcgettext(Domainname, Msgid, Category) \ ((void) (Category), dgettext (Domainname, Msgid)) # undef ngettext # define ngettext(Msgid1, Msgid2, N) \ ((N) == 1 \ ? ((void) (Msgid2), (const char *) (Msgid1)) \ : ((void) (Msgid1), (const char *) (Msgid2))) # undef dngettext # define dngettext(Domainname, Msgid1, Msgid2, N) \ ((void) (Domainname), ngettext (Msgid1, Msgid2, N)) # undef dcngettext # define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ ((void) (Category), dngettext (Domainname, Msgid1, Msgid2, N)) # undef textdomain # define textdomain(Domainname) ((const char *) (Domainname)) # undef bindtextdomain # define bindtextdomain(Domainname, Dirname) \ ((void) (Domainname), (const char *) (Dirname)) # undef bind_textdomain_codeset # define bind_textdomain_codeset(Domainname, Codeset) \ ((void) (Domainname), (const char *) (Codeset)) #endif /* Prefer gnulib's setlocale override over libintl's setlocale override. */ #ifdef GNULIB_defined_setlocale # undef setlocale # define setlocale rpl_setlocale #endif /* A pseudo function call that serves as a marker for the automated extraction of messages, but does not call gettext(). The run-time translation is done at a different place in the code. The argument, String, should be a literal string. Concatenated strings and other string expressions won't work. The macro's expansion is not parenthesized, so that it is suitable as initializer for static 'char[]' or 'const char[]' variables. */ #undef gettext_noop #define gettext_noop(String) String /* The separator between msgctxt and msgid in a .mo file. */ #define GETTEXT_CONTEXT_GLUE "\004" /* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be short and rarely need to change. The letter 'p' stands for 'particular' or 'special'. */ #ifdef DEFAULT_TEXT_DOMAIN # define pgettext(Msgctxt, Msgid) \ pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) #else # define pgettext(Msgctxt, Msgid) \ pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) #endif #define dpgettext(Domainname, Msgctxt, Msgid) \ pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) #define dcpgettext(Domainname, Msgctxt, Msgid, Category) \ pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category) #ifdef DEFAULT_TEXT_DOMAIN # define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) #else # define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) #endif #define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) #define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \ npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category) #ifdef __GNUC__ __inline #else #ifdef __cplusplus inline #endif #endif static const char * pgettext_aux (const char *domain, const char *msg_ctxt_id, const char *msgid, int category) { const char *translation = dcgettext (domain, msg_ctxt_id, category); if (translation == msg_ctxt_id) return msgid; else return translation; } #ifdef __GNUC__ __inline #else #ifdef __cplusplus inline #endif #endif static const char * npgettext_aux (const char *domain, const char *msg_ctxt_id, const char *msgid, const char *msgid_plural, unsigned long int n, int category) { const char *translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); if (translation == msg_ctxt_id || translation == msgid_plural) return (n == 1 ? msgid : msgid_plural); else return translation; } /* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID can be arbitrary expressions. But for string literals these macros are less efficient than those above. */ #include #if (((__GNUC__ >= 3 || __GNUG__ >= 2) && !defined __STRICT_ANSI__) \ /* || __STDC_VERSION__ >= 199901L */ ) # define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 1 #else # define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 0 #endif #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS #include #endif #define pgettext_expr(Msgctxt, Msgid) \ dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES) #define dpgettext_expr(Domainname, Msgctxt, Msgid) \ dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES) #ifdef __GNUC__ __inline #else #ifdef __cplusplus inline #endif #endif static const char * dcpgettext_expr (const char *domain, const char *msgctxt, const char *msgid, int category) { size_t msgctxt_len = strlen (msgctxt) + 1; size_t msgid_len = strlen (msgid) + 1; const char *translation; #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS char msg_ctxt_id[msgctxt_len + msgid_len]; #else char buf[1024]; char *msg_ctxt_id = (msgctxt_len + msgid_len <= sizeof (buf) ? buf : (char *) malloc (msgctxt_len + msgid_len)); if (msg_ctxt_id != NULL) #endif { memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); msg_ctxt_id[msgctxt_len - 1] = '\004'; memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); translation = dcgettext (domain, msg_ctxt_id, category); #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS if (msg_ctxt_id != buf) free (msg_ctxt_id); #endif if (translation != msg_ctxt_id) return translation; } return msgid; } #define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \ dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) #define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) #ifdef __GNUC__ __inline #else #ifdef __cplusplus inline #endif #endif static const char * dcnpgettext_expr (const char *domain, const char *msgctxt, const char *msgid, const char *msgid_plural, unsigned long int n, int category) { size_t msgctxt_len = strlen (msgctxt) + 1; size_t msgid_len = strlen (msgid) + 1; const char *translation; #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS char msg_ctxt_id[msgctxt_len + msgid_len]; #else char buf[1024]; char *msg_ctxt_id = (msgctxt_len + msgid_len <= sizeof (buf) ? buf : (char *) malloc (msgctxt_len + msgid_len)); if (msg_ctxt_id != NULL) #endif { memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); msg_ctxt_id[msgctxt_len - 1] = '\004'; memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS if (msg_ctxt_id != buf) free (msg_ctxt_id); #endif if (!(translation == msg_ctxt_id || translation == msgid_plural)) return translation; } return (n == 1 ? msgid : msgid_plural); } #endif /* _LIBGETTEXT_H */ libbytesize-2.2/src/python/000077500000000000000000000000001361502636100160155ustar00rootroot00000000000000libbytesize-2.2/src/python/Makefile.am000066400000000000000000000004311361502636100200470ustar00rootroot00000000000000if WITH_PYTHON3 py3libdir = $(shell python3 -c "import distutils.sysconfig; print(distutils.sysconfig.get_python_lib(1,0,prefix='${exec_prefix}'))") py3bytesizedir = $(py3libdir)/bytesize dist_py3bytesize_DATA = bytesize.py __init__.py endif MAINTAINERCLEANFILES = Makefile.in libbytesize-2.2/src/python/__init__.py000066400000000000000000000004111361502636100201220ustar00rootroot00000000000000from .bytesize import Size from .bytesize import B, KiB, MiB, GiB, TiB, PiB, EiB, ZiB, YiB, KB, MB, GB, TB, PB, EB, ZB, YB from .bytesize import ROUND_UP, ROUND_DOWN, ROUND_HALF_UP from .bytesize import SizeError, InvalidSpecError, OverflowError, ZeroDivisionError libbytesize-2.2/src/python/bytesize.py000066400000000000000000000520611361502636100202310ustar00rootroot00000000000000import ctypes from ctypes import POINTER, byref import six from decimal import Decimal import locale import gettext _ = lambda x: gettext.translation("libbytesize", fallback=True).gettext(x) if x != "" else "" """ Python bindings for the libbytesize library and it's BSSize "class". These bindings provide a real Python class :class:`Size` which wraps the libbytesize functionality and provides all the features one would expect from a numeric type in Python. .. note:: ``None`` is treated as ``Size(0)`` in mathematical operations. """ c_bytesize = ctypes.CDLL("libbytesize.so.1") B = 0 KiB = 1 MiB = 2 GiB = 3 TiB = 4 PiB = 5 EiB = 6 ZiB = 7 YiB = 8 KB = 21 MB = 22 GB = 23 TB = 24 PB = 25 EB = 26 ZB = 27 YB = 28 ROUND_UP = 0 ROUND_DOWN = 1 ROUND_HALF_UP = 2 MAXUINT64 = 2**64 - 1 unit_strs = { "B": B, "KiB": KiB, "MiB": MiB, "GiB": GiB, "TiB": TiB, "PiB": PiB, "EiB": EiB, "ZiB": ZiB, "YiB": YiB, "KB": KB, "MB": MB, "GB": GB, "TB": TB, "PB": PB, "EB": EB, "ZB": ZB, "YB": YB, } def unit_str(unit, xlate=False): for (u_str, u) in unit_strs.items(): if u == unit: return _(u_str) if xlate else u_str class SizeErrorStruct(ctypes.Structure): _fields_ = [("code", ctypes.c_int), ("msg", ctypes.c_char_p)] class SizeError(Exception): pass class InvalidSpecError(SizeError): pass class OverflowError(SizeError): pass class ZeroDivisionError(SizeError): pass _error_code_clss = (InvalidSpecError, OverflowError, ZeroDivisionError) def get_error(err): if not err: return None if six.PY3: msg = str(err.contents.msg, "utf-8") else: msg = err.contents.msg ex = _error_code_clss[err.contents.code](msg) c_bytesize.bs_clear_error(byref(err)) raise ex class SizeStruct(ctypes.Structure): @classmethod def new(cls): return c_bytesize.bs_size_new().contents @classmethod def new_from_bytes(cls, byts, sgn): return c_bytesize.bs_size_new_from_bytes(byts, sgn).contents @classmethod def new_from_str(cls, s): err = POINTER(SizeErrorStruct)() if six.PY3: s = bytes(s, "utf-8") ret = c_bytesize.bs_size_new_from_str(s, byref(err)) get_error(err) return ret.contents @classmethod def new_from_size(cls, sz): return c_bytesize.bs_size_new_from_size(sz).contents def __del__(self): # XXX: For some reason c_bytesize may be None here (probably when python # cleans up after itself) and loading it again doesn't work at that # stage. Let's just prevent ignored exceptions from happening. if c_bytesize: c_bytesize.bs_size_free(self) def get_bytes(self): sgn = ctypes.c_int(0) err = POINTER(SizeErrorStruct)() ret = c_bytesize.bs_size_get_bytes(self, byref(sgn), byref(err)) get_error(err) return (ret, sgn.value) def get_bytes_str(self): if six.PY3: return str(c_bytesize.bs_size_get_bytes_str(self), "utf-8") else: return c_bytesize.bs_size_get_bytes_str(self) def add(self, sz): return c_bytesize.bs_size_add(self, sz).contents def add_bytes(self, b): return c_bytesize.bs_size_add_bytes(self, b).contents def grow(self, sz): c_bytesize.bs_size_grow(self, sz) return self def grow_bytes(self, b): c_bytesize.bs_size_grow_bytes(self, b) return self def sub(self, sz): return c_bytesize.bs_size_sub(self, sz).contents def sub_bytes(self, b): return c_bytesize.bs_size_sub_bytes(self, b).contents def shrink(self, sz): c_bytesize.bs_size_shrink(self, sz) return self def shrink_bytes(self, b): c_bytesize.bs_size_shrink_bytes(self, b) return self def cmp(self, sz, ign_sgn): return c_bytesize.bs_size_cmp(self, sz, ign_sgn) def cmp_bytes(self, b, ign_sgn): return c_bytesize.bs_size_cmp_bytes(self, b, ign_sgn) def convert_to(self, unit): err = POINTER(SizeErrorStruct)() ret = c_bytesize.bs_size_convert_to(self, unit, byref(err)) get_error(err) if six.PY3: ret = str(ret, "utf-8") return ret def div(self, sz): sgn = ctypes.c_int(0) err = POINTER(SizeErrorStruct)() ret = c_bytesize.bs_size_div(self, sz, byref(sgn), byref(err)) get_error(err) return (ret, sgn.value) def div_int(self, div): err = POINTER(SizeErrorStruct)() ret = c_bytesize.bs_size_div_int(self, div, byref(err)) get_error(err) return ret.contents def shrink_div_int(self, div): err = POINTER(SizeErrorStruct)() c_bytesize.bs_size_shrink_div_int(self, div, byref(err)) get_error(err) return self def human_readable(self, min_unit, max_places, xlate): if six.PY3: return str(c_bytesize.bs_size_human_readable(self, min_unit, max_places, xlate), "utf-8") else: return c_bytesize.bs_size_human_readable(self, min_unit, max_places, xlate) def sgn(self): return c_bytesize.bs_size_sgn(self) def true_div(self, sz): err = POINTER(SizeErrorStruct)() ret = c_bytesize.bs_size_true_div(self, sz, byref(err)) get_error(err) if six.PY3: ret = str(ret, "utf-8") return ret def true_div_int(self, div): err = POINTER(SizeErrorStruct)() ret = c_bytesize.bs_size_true_div_int(self, div, byref(err)) get_error(err) if six.PY3: ret = str(ret, "utf-8") return ret def mod(self, sz): err = POINTER(SizeErrorStruct)() ret = c_bytesize.bs_size_mod(self, sz, byref(err)) get_error(err) return ret.contents def mul_float_str(self, fl_str): err = POINTER(SizeErrorStruct)() if six.PY3: fl_str = bytes(fl_str, "utf-8") ret = c_bytesize.bs_size_mul_float_str(self, fl_str, byref(err)) get_error(err) return ret.contents def grow_mul_float_str(self, fl_str): err = POINTER(SizeErrorStruct)() if six.PY3: fl_str = bytes(fl_str, "utf-8") c_bytesize.bs_size_grow_mul_float_str(self, fl_str, byref(err)) get_error(err) return self def mul_int(self, i): err = POINTER(SizeErrorStruct)() ret = c_bytesize.bs_size_mul_int(self, i) get_error(err) return ret.contents def grow_mul_int(self, i): err = POINTER(SizeErrorStruct)() c_bytesize.bs_size_grow_mul_int(self, i) get_error(err) return self def round_to_nearest(self, sz, dir): err = POINTER(SizeErrorStruct)() ret = c_bytesize.bs_size_round_to_nearest(self, sz, dir, byref(err)) get_error(err) return ret.contents def __repr__(self): return "Size (%s)" % self.human_readable(B, -1, False) ## Constructors c_bytesize.bs_size_new.restype = POINTER(SizeStruct) c_bytesize.bs_size_new.argtypes = [] c_bytesize.bs_size_new_from_bytes.restype = POINTER(SizeStruct) c_bytesize.bs_size_new_from_bytes.argtypes = [ctypes.c_ulonglong, ctypes.c_int] c_bytesize.bs_size_new_from_str.restype = POINTER(SizeStruct) c_bytesize.bs_size_new_from_str.argtypes = [ctypes.c_char_p, POINTER(POINTER(SizeErrorStruct))] c_bytesize.bs_size_new_from_size.restype = POINTER(SizeStruct) c_bytesize.bs_size_new_from_size.argtypes = [POINTER(SizeStruct)] ## Destructors c_bytesize.bs_size_free.restype = None c_bytesize.bs_size_free.argtypes = [POINTER(SizeStruct)] c_bytesize.bs_clear_error.restype = None c_bytesize.bs_clear_error.argtypes = [POINTER(POINTER(SizeErrorStruct))] ## Query methods c_bytesize.bs_size_get_bytes.restype = ctypes.c_ulonglong c_bytesize.bs_size_get_bytes.argtypes = [POINTER(SizeStruct), POINTER(ctypes.c_int), POINTER(POINTER(SizeErrorStruct))] c_bytesize.bs_size_sgn.restype = ctypes.c_int c_bytesize.bs_size_sgn.argtypes = [POINTER(SizeStruct)] c_bytesize.bs_size_get_bytes_str.restype = ctypes.c_char_p c_bytesize.bs_size_get_bytes_str.argtypes = [POINTER(SizeStruct)] c_bytesize.bs_size_convert_to.restype = ctypes.c_char_p c_bytesize.bs_size_convert_to.argtypes = [POINTER(SizeStruct), ctypes.c_int, POINTER(POINTER(SizeErrorStruct))] c_bytesize.bs_size_human_readable.restype = ctypes.c_char_p c_bytesize.bs_size_human_readable.argtypes = [POINTER(SizeStruct), ctypes.c_int, ctypes.c_int, ctypes.c_bool] ## Arithmetic c_bytesize.bs_size_add.restype = POINTER(SizeStruct) c_bytesize.bs_size_add.argtypes = [POINTER(SizeStruct), POINTER(SizeStruct)] c_bytesize.bs_size_grow.restype = POINTER(SizeStruct) c_bytesize.bs_size_grow.argtypes = [POINTER(SizeStruct), POINTER(SizeStruct)] c_bytesize.bs_size_add_bytes.restype = POINTER(SizeStruct) c_bytesize.bs_size_add_bytes.argtypes = [POINTER(SizeStruct), ctypes.c_ulonglong] c_bytesize.bs_size_grow_bytes.restype = POINTER(SizeStruct) c_bytesize.bs_size_grow_bytes.argtypes = [POINTER(SizeStruct), ctypes.c_ulonglong] c_bytesize.bs_size_sub.restype = POINTER(SizeStruct) c_bytesize.bs_size_sub.argtypes = [POINTER(SizeStruct), POINTER(SizeStruct)] c_bytesize.bs_size_shrink.restype = POINTER(SizeStruct) c_bytesize.bs_size_shrink.argtypes = [POINTER(SizeStruct), POINTER(SizeStruct)] c_bytesize.bs_size_sub_bytes.restype = POINTER(SizeStruct) c_bytesize.bs_size_sub_bytes.argtypes = [POINTER(SizeStruct), ctypes.c_ulonglong] c_bytesize.bs_size_shrink_bytes.restype = POINTER(SizeStruct) c_bytesize.bs_size_shrink_bytes.argtypes = [POINTER(SizeStruct), ctypes.c_ulonglong] c_bytesize.bs_size_mul_int.restype = POINTER(SizeStruct) c_bytesize.bs_size_mul_int.argtypes = [POINTER(SizeStruct), ctypes.c_ulonglong] c_bytesize.bs_size_grow_mul_int.restype = POINTER(SizeStruct) c_bytesize.bs_size_grow_mul_int.argtypes = [POINTER(SizeStruct), ctypes.c_ulonglong] c_bytesize.bs_size_mul_float_str.restype = POINTER(SizeStruct) c_bytesize.bs_size_mul_float_str.argtypes = [POINTER(SizeStruct), ctypes.c_char_p, POINTER(POINTER(SizeErrorStruct))] c_bytesize.bs_size_grow_mul_float_str.restype = POINTER(SizeStruct) c_bytesize.bs_size_grow_mul_float_str.argtypes = [POINTER(SizeStruct), ctypes.c_char_p, POINTER(POINTER(SizeErrorStruct))] c_bytesize.bs_size_div.restype = ctypes.c_ulonglong c_bytesize.bs_size_div.argtypes = [POINTER(SizeStruct), POINTER(SizeStruct), POINTER(ctypes.c_int), POINTER(POINTER(SizeErrorStruct))] c_bytesize.bs_size_div_int.restype = POINTER(SizeStruct) c_bytesize.bs_size_div_int.argtypes = [POINTER(SizeStruct), ctypes.c_ulonglong, POINTER(POINTER(SizeErrorStruct))] c_bytesize.bs_size_shrink_div_int.restype = POINTER(SizeStruct) c_bytesize.bs_size_shrink_div_int.argtypes = [POINTER(SizeStruct), ctypes.c_ulonglong, POINTER(POINTER(SizeErrorStruct))] c_bytesize.bs_size_true_div.restype = ctypes.c_char_p c_bytesize.bs_size_true_div.argtypes = [POINTER(SizeStruct), POINTER(SizeStruct), POINTER(POINTER(SizeErrorStruct))] c_bytesize.bs_size_true_div_int.restype = ctypes.c_char_p c_bytesize.bs_size_true_div_int.argtypes = [POINTER(SizeStruct), ctypes.c_ulonglong, POINTER(POINTER(SizeErrorStruct))] c_bytesize.bs_size_mod.restype = POINTER(SizeStruct) c_bytesize.bs_size_mod.argtypes = [POINTER(SizeStruct), POINTER(SizeStruct), POINTER(POINTER(SizeErrorStruct))] c_bytesize.bs_size_round_to_nearest.restype = POINTER(SizeStruct) c_bytesize.bs_size_round_to_nearest.argtypes = [POINTER(SizeStruct), POINTER(SizeStruct), ctypes.c_int, POINTER(POINTER(SizeErrorStruct))] ## Comparisons c_bytesize.bs_size_cmp.restype = ctypes.c_int c_bytesize.bs_size_cmp.argtypes = [POINTER(SizeStruct), POINTER(SizeStruct), ctypes.c_bool] c_bytesize.bs_size_cmp_bytes.restype = ctypes.c_int c_bytesize.bs_size_cmp_bytes.argtypes = [POINTER(SizeStruct), ctypes.c_ulonglong, ctypes.c_bool] def _str_to_decimal(num_str): radix = locale.nl_langinfo(locale.RADIXCHAR) if radix != '.': num_str = num_str.replace(radix, '.') return Decimal(num_str) def neutralize_none_operand(fn): def fn_with_neutralization(sz, other): return fn(sz, Size(0) if other is None else other) return fn_with_neutralization class Size(object): def __init__(self, spec=None): self._c_size = None try: if isinstance(spec, six.string_types): self._c_size = SizeStruct.new_from_str(spec) elif isinstance(spec, six.integer_types): abs_val = abs(spec) if abs_val == spec: sgn = 1 else: sgn = -1 if abs_val <= MAXUINT64: self._c_size = SizeStruct.new_from_bytes(abs_val, sgn) else: self._c_size = SizeStruct.new_from_str(str(spec)) elif isinstance(spec, (Decimal, float)): self._c_size = SizeStruct.new_from_str(str(spec)) elif isinstance(spec, SizeStruct): self._c_size = SizeStruct.new_from_size(spec) elif isinstance(spec, Size): self._c_size = SizeStruct.new_from_size(spec._c_size) elif spec is None: self._c_size = SizeStruct.new() else: raise ValueError("Cannot construct new size from '%s'" % spec) except SizeError as e: raise ValueError(e) ## METHODS ## def get_bytes(self): try: val, sgn = self._c_size.get_bytes() return val * sgn except SizeError: return int(self._c_size.get_bytes_str()) def convert_to(self, unit): if isinstance(unit, six.string_types): real_unit = unit_strs.get(unit) if real_unit is None: raise ValueError("Invalid unit specification: '%s'" % unit) ret = self._c_size.convert_to(real_unit) else: ret = self._c_size.convert_to(unit) return _str_to_decimal(ret) def human_readable(self, min_unit=B, max_places=2, xlate=True): if isinstance(min_unit, six.string_types): if min_unit in unit_strs.keys(): min_unit = unit_strs[min_unit] else: raise ValueError("Invalid unit specification: '%s'" % min_unit) if not isinstance(max_places, six.integer_types): raise ValueError("max_places has to be an integer number") return self._c_size.human_readable(min_unit, max_places, xlate) def round_to_nearest(self, round_to, rounding): if isinstance(round_to, Size): return Size(self._c_size.round_to_nearest(round_to._c_size, rounding)) size = None # else try to create a SizeStruct instance from it for (unit_str, unit) in unit_strs.items(): if round_to in (unit.real, unit_str): size = SizeStruct.new_from_str("1 %s" % unit_str) break if size is not None: return Size(self._c_size.round_to_nearest(size, rounding)) else: raise ValueError("Invalid size specification: '%s'" % round_to) def cmp(self, other, abs_vals=False): if isinstance(other, six.integer_types): if (other < 0 and abs_vals): other = abs(other) if 0 <= other <= MAXUINT64: return self._c_size.cmp_bytes(other, abs_vals) else: other = SizeStruct.new_from_str(str(other)) elif isinstance(other, (Decimal, float)): other = SizeStruct.new_from_str(str(other)) elif isinstance(other, Size): other = other._c_size elif other is None: return 1 return self._c_size.cmp(other, abs_vals) ## INTERNAL METHODS ## def __eq__(self, other): return self.cmp(other, False) == 0 def __ne__(self, other): return self.cmp(other, False) != 0 def __lt__(self, other): return self.cmp(other, False) == -1 def __le__(self, other): return self.cmp(other, False) in (-1, 0) def __gt__(self, other): return self.cmp(other, False) == 1 def __ge__(self, other): return self.cmp(other, False) in (1, 0) def __bool__(self): return self.get_bytes() != 0 __nonzero__ = __bool__ def __abs__(self): return Size(abs(self.get_bytes())) def __neg__(self): return self.__mul__(-1) @neutralize_none_operand def __add__(self, other): if isinstance(other, six.integer_types): if other <= MAXUINT64: return Size(self._c_size.add_bytes(other)) else: other = SizeStruct.new_from_str(str(other)) elif isinstance(other, (Decimal, float)): other = SizeStruct.new_from_str(str(other)) elif isinstance(other, Size): other = other._c_size return Size(self._c_size.add(other)) # needed to make sum() work with Size arguments __radd__ = __add__ @neutralize_none_operand def __sub__(self, other): if isinstance(other, six.integer_types): if other <= MAXUINT64: return Size(self._c_size.sub_bytes(other)) else: other = SizeStruct.new_from_str(str(other)) elif isinstance(other, (Decimal, float)): other = SizeStruct.new_from_str(str(other)) elif isinstance(other, Size): other = other._c_size return Size(self._c_size.sub(other)) @neutralize_none_operand def __rsub__(self, other): other = SizeStruct.new_from_str(str(other)) return Size(SizeStruct.sub(other, self._c_size)) @neutralize_none_operand def __mul__(self, other): if isinstance(other, (Size, SizeStruct)): raise ValueError("Cannot multiply Size by Size. It just doesn't make sense.") elif isinstance(other, (Decimal, float)) or (isinstance(other, six.integer_types) and other > MAXUINT64 or other < 0): return Size(self._c_size.mul_float_str(str(other))) else: return Size(self._c_size.mul_int(other)) __rmul__ = __mul__ @neutralize_none_operand def __div__(self, other): if not six.PY2: raise AttributeError if isinstance(other, six.integer_types): if other <= MAXUINT64: return Size(self._c_size.div_int(other)) else: other = SizeStruct.new_from_str(str(other)) return Size(_str_to_decimal(self._c_size.true_div(other))) elif isinstance(other, (Decimal, float)): other = SizeStruct.new_from_str(str(other)) return Size(self._c_size.true_div(other)) else: return _str_to_decimal(self._c_size.true_div(other._c_size)) @neutralize_none_operand def __truediv__(self, other): if isinstance(other, six.integer_types): if other <= MAXUINT64: return Size(self._c_size.true_div_int(other)) else: other = SizeStruct.new_from_str(str(other)) return Size(self._c_size.true_div(other)) elif isinstance(other, (Decimal, float)): return Size(self._c_size.mul_float_str(str(Decimal(1)/Decimal(other)))) return _str_to_decimal(self._c_size.true_div(other._c_size)) def _safe_floordiv(self, other): try: val, sgn = self._c_size.div(other._c_size) return val * sgn except OverflowError: return int(float(self._c_size.true_div(other._c_size))) def _safe_floordiv_int(self, other): try: return Size(self._c_size.div_int(other)) except OverflowError: return Size(float(self._c_size.true_div_int(other))) @neutralize_none_operand def __floordiv__(self, other): if isinstance(other, (Decimal, float)): return Size(self._c_size.mul_float_str(str(Decimal(1)/Decimal(other)))) elif isinstance(other, six.integer_types): if other <= MAXUINT64: return self._safe_floordiv_int(other) else: other = SizeStruct.new_from_str(str(other)) return Size(self._safe_floordiv(other)) return self._safe_floordiv(other) @neutralize_none_operand def __mod__(self, other): if not isinstance(other, Size): raise ValueError("modulo operation only supported between two Size instances") return Size(self._c_size.mod(other._c_size)) @neutralize_none_operand def __divmod__(self, other): rdiv = self.__floordiv__(other) if not isinstance(other, Size): rmod = self.__mod__(rdiv) else: rmod = self.__mod__(other) return (rdiv, rmod) def __repr__(self): return "Size (%s)" % self.human_readable(B, -1, False) def __str__(self): return self.human_readable() def __int__(self): return self.get_bytes() def __float__(self): return float(self.get_bytes()) def __deepcopy__(self, memo_dict): return Size(self) # pickling support for Size # see https://docs.python.org/3/library/pickle.html#object.__reduce__ def __reduce__(self): return (self.__class__, (self.get_bytes(),)) def __hash__(self): return self.get_bytes() libbytesize-2.2/tests/000077500000000000000000000000001361502636100150475ustar00rootroot00000000000000libbytesize-2.2/tests/Makefile.am000066400000000000000000000010311361502636100170760ustar00rootroot00000000000000AM_TESTS_ENVIRONMENT = top_srcdir="$(top_srcdir)" top_builddir="$(top_builddir)" ; . $(srcdir)/testenv.sh ; dist_noinst_SCRIPTS = libbytesize_unittest.sh libbytesize_unittest.py lbs_py_override_unittest.py locale_utils.py testenv.sh canary_tests.sh TESTS = libbytesize_unittest.sh canary_tests.sh # Add the translation-canary source files to the tarball EXTRA_DIST = $(top_srcdir)/translation-canary/translation_canary/*.py \ $(top_srcdir)/translation-canary/translation_canary/*/*.py MAINTAINERCLEANFILES = Makefile.in libbytesize-2.2/tests/canary_tests.sh.in000066400000000000000000000014401361502636100205060ustar00rootroot00000000000000#!/bin/sh -e # Run the translation canary tests on the translatable strings if [ @WITH_PYTHON3@ != 1 ]; then echo "Cannot run translations tests without python3, skipping." exit 0 fi DISTRO=`busctl get-property org.freedesktop.hostname1 /org/freedesktop/hostname1 org.freedesktop.hostname1 OperatingSystemCPEName | cut -d ":" -f 3` if [ $DISTRO == "centos" -o $DISTRO == "enterprise_linux" ]; then echo "Cannot run translations tests on CentOS/RHEL 7, skipping." exit 0 fi # If not run from automake, fake it if [ -z "$top_srcdir" ]; then top_srcdir="$(dirname "$0")/.." fi PYTHONPATH="${PYTHONPATH}:${top_srcdir}/translation-canary" export PYTHONPATH # Run the translatable tests on the POT file python3 -m translation_canary.translatable "${top_srcdir}/po/libbytesize.pot" libbytesize-2.2/tests/lbs_py_override_unittest.py000077500000000000000000000211061361502636100225520ustar00rootroot00000000000000#!/usr/bin/python3 # -*- coding: utf-8 -*- import unittest import copy import locale from decimal import Decimal from locale_utils import get_avail_locales, requires_locales from bytesize import Size, ROUND_UP, ROUND_DOWN, KiB class SizeTestCase(unittest.TestCase): @classmethod def setUpClass(cls): unittest.TestCase.setUpClass() cls.avail_locales = get_avail_locales() @requires_locales({'en_US.utf8'}) def setUp(self): locale.setlocale(locale.LC_ALL,'en_US.utf8') self.addCleanup(self._clean_up) def _clean_up(self): locale.setlocale(locale.LC_ALL,'en_US.utf8') # test operator functions def testOperatorPlus(self): result = Size("1000 B") + Size("100 B") actual = result.get_bytes() expected = 1100 self.assertEqual(actual, expected) result = Size("1000 B") + 10 actual = result.get_bytes() expected = 1010 self.assertEqual(actual, expected) result = 10 + Size("1000 B") actual = result.get_bytes() expected = 1010 self.assertEqual(actual, expected) size1 = Size("100 B") size1 += Size("100 B") actual = size1.get_bytes() expected = 200 self.assertEqual(actual, expected) size1 = Size("100 B") size1 += 100 actual = size1.get_bytes() expected = 200 self.assertEqual(actual, expected) # TODO shouldn't be the result int? int1 = 10 int1 += Size("100 B") actual = int1.get_bytes() expected = 110 self.assertEqual(actual, expected) size1 = Size("100 B") + None self.assertEqual(size1.get_bytes(), 100) #enddef def testOperatorMinus(self): result = Size("1000 B") - Size("100 B") actual = result.get_bytes() expected = 900 self.assertEqual(actual, expected) result = Size("1000 B") - 10 actual = result.get_bytes() expected = 990 self.assertEqual(actual, expected) result = 10 - Size("100 B") actual = result.get_bytes() expected = -90 self.assertEqual(actual, expected) size1 = Size("100 B") size1 -= Size("10 B") actual = size1.get_bytes() expected = 90 self.assertEqual(actual, expected) size1 = Size("100 B") size1 -= 10 actual = size1.get_bytes() expected = 90 self.assertEqual(actual, expected) # TODO shouldn't be the result int? int1 = 1000 int1 -= Size("100 B") actual = int1.get_bytes() expected = 900 self.assertEqual(actual, expected) size1 = Size("100 B") - None self.assertEqual(size1.get_bytes(), 100) #enddef def testOperatorMul(self): result = Size("4 B") * 3 actual = result.get_bytes() expected = 12 self.assertEqual(actual, expected) result = 3 * Size("4 B") actual = result.get_bytes() expected = 12 self.assertEqual(actual, expected) size1 = Size("4 B") size1 *= 3 actual = size1.get_bytes() expected = 12 self.assertEqual(actual, expected) int1 = 4 int1 *= Size("3 B") actual = int1.get_bytes() expected = 12 self.assertEqual(actual, expected) #enddef def testOperatorDiv(self): actual = Size("100 B") / Size("10 B") expected = Decimal("10") self.assertEqual(actual, expected) actual = Size("120 B") / Size("100 B") expected = Decimal("1.2") self.assertEqual(actual, expected) actual = Size("120 B") // Size("100 B") expected = Decimal("1") self.assertEqual(actual, expected) actual = Size("128 EiB") // Size("64 EiB") expected = 2 self.assertEqual(actual, expected) actual = Size("100 B") / 10 expected = Decimal("10") self.assertEqual(actual, expected) actual = Size("120 B") / 100 expected = Decimal("1.2") self.assertEqual(actual, expected) actual = Size("128 EiB") // 2 expected = Size("64 EiB") self.assertEqual(actual, expected) result = Size("120 B") // 100 actual = result.get_bytes() expected = 1 self.assertEqual(actual, expected) size1 = Size("120 B") size1 /= Size("100 B") actual = size1 expected = Decimal("1.2") self.assertEqual(actual, expected) size1 = Size("120 B") size1 /= 100 actual = size1 expected = Decimal("1.2") self.assertEqual(actual, expected) size1 = Size("120 B") size1 //= Size("100 B") actual = size1 expected = Decimal("1") self.assertEqual(actual, expected) #enddef def testDivMod(self): size1 = Size("120 B") q, mod = divmod(size1, Size("100 B")) self.assertEqual(q, 1) self.assertEqual(mod, Size("20 B")) size1 = Size("250 MiB") q, mod = divmod(size1, Size("100 MiB")) self.assertEqual(q, 2) self.assertEqual(mod, Size("50 MiB")) size1 = Size("10 GiB") + Size("5 GiB") q, mod = divmod(size1, 7) self.assertEqual(q, 2300875337) self.assertEqual(mod, 1) def testEquality(self): size1 = Size("1 GiB") size2 = Size("2 GiB") self.assertTrue(size1 == size1) self.assertTrue(size2 == size2) self.assertFalse(size1 == size2) self.assertFalse(size2 == size1) self.assertFalse(size1 == None) self.assertFalse(size1 == 0) size3 = Size(0) self.assertTrue(size3 == 0) #enddef def testCompare(self): size1 = Size("1 GiB") size2 = Size("2 GiB") self.assertTrue(size2 > size1) self.assertFalse(size1 > size2) self.assertTrue(size2 >= size1) self.assertFalse(size1 >= size2) self.assertTrue(size1 >= size1) self.assertFalse(size2 < size1) self.assertTrue(size1 < size2) self.assertFalse(size2 <= size1) self.assertTrue(size1 <= size2) self.assertTrue(size1 <= size1) self.assertTrue(size1 > None) self.assertTrue(size1 >= None) self.assertFalse(size1 < None) self.assertFalse(size1 <= None) self.assertFalse(size1 == None) self.assertTrue(size1 != None) size3 = Size(0) self.assertTrue(size3 > None) self.assertFalse(size3 < None) self.assertTrue(size3 != None) #enddef def testBool(self): size1 = Size("1 GiB") size2 = Size(0) self.assertTrue(size1) self.assertFalse(size2) #enddef def testAbs(self): size1 = Size("1 GiB") self.assertEqual(size1, abs(size1)) size2 = Size("-2 GiB") self.assertEqual(size2, -1 * abs(size2)) def testNeg(self): size1 = Size("1 KiB") self.assertEqual(-1024, -size1) size1 = Size("-1 KiB") self.assertEqual(1024, -size1) def testDeepCopy(self): size1 = Size("1 GiB") size2 = copy.deepcopy(size1) self.assertIsNot(size1, size2) self.assertEqual(size1, size2) def testHashable(self): size = Size("1 KiB") hs = hash(size) self.assertIsNotNone(hs) size_set = set((Size("1 KiB"), Size("1 KiB"), Size("1 KiB"), Size("2 KiB"), Size(0))) self.assertEqual(len(size_set), 3) @requires_locales({'cs_CZ.UTF-8', 'ps_AF.UTF-8', 'en_US.UTF-8'}) def testConvertTo(self): size = Size("1.5 KiB") conv = size.convert_to("KiB") self.assertEqual(conv, Decimal("1.5")) locale.setlocale(locale.LC_ALL,'cs_CZ.UTF-8') size = Size("1.5 KiB") conv = size.convert_to("KiB") self.assertEqual(conv, Decimal("1.5")) # this persian locale uses a two-byte unicode character for the radix locale.setlocale(locale.LC_ALL, 'ps_AF.UTF-8') size = Size("1.5 KiB") conv = size.convert_to("KiB") self.assertEqual(conv, Decimal("1.5")) locale.setlocale(locale.LC_ALL,'en_US.UTF-8') def testRoundToNearest(self): size = Size("1.5 KiB") conv = size.round_to_nearest(Size("1 KiB"), rounding=ROUND_UP) self.assertEqual(conv, Size("2 KiB")) conv = size.round_to_nearest(KiB, rounding=ROUND_DOWN) self.assertEqual(conv, Size("1 KiB")) with self.assertRaises(ValueError): size.round_to_nearest(-1, rounding=ROUND_UP) #endclass # script entry point if __name__=='__main__': unittest.main() #endif libbytesize-2.2/tests/libbytesize_unittest.py000077500000000000000000000621611361502636100217160ustar00rootroot00000000000000#!/usr/bin/python3 # -*- coding: utf-8 -*- import locale import unittest import sys import ctypes from locale_utils import get_avail_locales, requires_locales from bytesize import KiB, GiB, ROUND_UP, ROUND_DOWN, ROUND_HALF_UP, OverflowError # SizeStruct is part of the 'private' API and needs to be imported differently # when running from locally build tree and when using installed library try: from bytesize import SizeStruct except ImportError: from bytesize.bytesize import SizeStruct DEFAULT_LOCALE = "en_US.utf8" class SizeTestCase(unittest.TestCase): @classmethod def setUpClass(cls): unittest.TestCase.setUpClass() cls.avail_locales = get_avail_locales() @requires_locales({DEFAULT_LOCALE}) def setUp(self): locale.setlocale(locale.LC_ALL, DEFAULT_LOCALE) self.addCleanup(self._clean_up) def _clean_up(self): locale.setlocale(locale.LC_ALL, DEFAULT_LOCALE) def testNew(self): actual = SizeStruct.new().get_bytes() expected = (0, 0) self.assertEqual(actual, expected) @requires_locales({'cs_CZ.UTF-8', 'ps_AF.UTF-8', 'en_US.UTF-8'}) def testNewFromStr(self): actual = SizeStruct.new_from_str('0 B').get_bytes() expected = (0, 0) self.assertEqual(actual, expected) actual = SizeStruct.new_from_str('1 KiB').get_bytes() expected = (1024, 1) self.assertEqual(actual, expected) actual = SizeStruct.new_from_str('1KB').get_bytes() expected = (1000, 1) self.assertEqual(actual, expected) actual = SizeStruct.new_from_str('1 MiB').get_bytes() expected = (1048576, 1) self.assertEqual(actual, expected) actual = SizeStruct.new_from_str(' 1 MiB').get_bytes() expected = (1048576, 1) self.assertEqual(actual, expected) actual = SizeStruct.new_from_str('1 MiB ').get_bytes() expected = (1048576, 1) self.assertEqual(actual, expected) actual = SizeStruct.new_from_str(' 1 MiB ').get_bytes() expected = (1048576, 1) self.assertEqual(actual, expected) actual = SizeStruct.new_from_str('-1.5 GiB').get_bytes() expected = (1610612736, -1) self.assertEqual(actual, expected) actual = SizeStruct.new_from_str('+1.5 GiB').get_bytes() expected = (1610612736, 1) self.assertEqual(actual, expected) locale.setlocale(locale.LC_ALL,'cs_CZ.UTF-8') actual = SizeStruct.new_from_str('1,5 KiB').get_bytes() expected = (1536, 1) self.assertEqual(actual, expected) actual = SizeStruct.new_from_str('-1,5 KiB').get_bytes() expected = (1536, -1) self.assertEqual(actual, expected) actual = SizeStruct.new_from_str('1.5 KiB').get_bytes() expected = (1536, 1) self.assertEqual(actual, expected) actual = SizeStruct.new_from_str('-1.5 KiB').get_bytes() expected = (1536, -1) self.assertEqual(actual, expected) actual = SizeStruct.new_from_str('1e-1 KB').get_bytes() expected = (100, 1) self.assertEqual(actual, expected) actual = SizeStruct.new_from_str('-1e-1 KB').get_bytes() expected = (100, -1) self.assertEqual(actual, expected) # this persian locale uses a two-byte unicode character for the radix locale.setlocale(locale.LC_ALL, 'ps_AF.UTF-8') actual = SizeStruct.new_from_str('1Ù«5 KiB').get_bytes() expected = (1536, 1) self.assertEqual(actual, expected) actual = SizeStruct.new_from_str('-1Ù«5 KiB').get_bytes() expected = (1536, -1) self.assertEqual(actual, expected) actual = SizeStruct.new_from_str('1.5 KiB').get_bytes() expected = (1536, 1) self.assertEqual(actual, expected) actual = SizeStruct.new_from_str('-1.5 KiB').get_bytes() expected = (1536, -1) self.assertEqual(actual, expected) locale.setlocale(locale.LC_ALL, DEFAULT_LOCALE) #enddef def testNewFromBytes(self): actual = SizeStruct.new_from_bytes(0, 0).get_bytes() expected = (0, 0) self.assertEqual(actual, expected) actual = SizeStruct.new_from_bytes(10, 1).get_bytes() expected = (10, 1) self.assertEqual(actual, expected) actual = SizeStruct.new_from_bytes(1024, -1).get_bytes() expected = (1024, -1) self.assertEqual(actual, expected) # now let's try something bigger than MAXUINT32 actual = SizeStruct.new_from_bytes(5718360*1024, 1).get_bytes() expected = (5718360*1024, 1) self.assertEqual(actual, expected) #enddef def testNewFromSizeStruct(self): tempSizeStruct = SizeStruct.new_from_bytes(17, 1) actual = SizeStruct.new_from_size(tempSizeStruct).get_bytes() expected = (17, 1) self.assertEqual(actual, expected) #enddef def testAdd(self): x = SizeStruct.new_from_bytes(8, 1) y = SizeStruct.new_from_bytes(16, 1) actual = x.add(y).get_bytes() expected = (24, 1) self.assertEqual(actual, expected) x = SizeStruct.new_from_bytes(8, -1) y = SizeStruct.new_from_bytes(16, 1) actual = x.add(y).get_bytes() expected = (8, 1) self.assertEqual(actual, expected) x = SizeStruct.new_from_bytes(8, -1) y = SizeStruct.new_from_bytes(16, -1) actual = x.add(y).get_bytes() expected = (24, -1) self.assertEqual(actual, expected) x = SizeStruct.new_from_bytes(0, 0) y = SizeStruct.new_from_bytes(16, -1) actual = x.add(y).get_bytes() expected = (16, -1) self.assertEqual(actual, expected) x = SizeStruct.new_from_bytes(0, 0) y = SizeStruct.new_from_bytes(0, 0) actual = x.add(y).get_bytes() expected = (0, 0) self.assertEqual(actual, expected) #enddef def testAddBytes(self): x = SizeStruct.new_from_bytes(8, 1) actual = x.add_bytes(16).get_bytes() expected = (24, 1) self.assertEqual(actual, expected) x = SizeStruct.new_from_bytes(8, -1) actual = x.add_bytes(8).get_bytes() expected = (0, 0) self.assertEqual(actual, expected) x = SizeStruct.new_from_bytes(8, -1) actual = x.add_bytes(0).get_bytes() expected = (8, -1) self.assertEqual(actual, expected) # try some big value (bigger than ULONG_MAX on 32bit arches) x = SizeStruct.new_from_bytes(0, 0) actual = x.add_bytes(2**36).get_bytes() expected = (2**36, 1) self.assertEqual(actual, expected) #enddef def testSub(self): x = SizeStruct.new_from_bytes(8, 1) y = SizeStruct.new_from_bytes(16, 1) actual = x.sub(y).get_bytes() expected = (8, -1) self.assertEqual(actual, expected) x = SizeStruct.new_from_bytes(8, -1) y = SizeStruct.new_from_bytes(16, 1) actual = x.sub(y).get_bytes() expected = (24, -1) self.assertEqual(actual, expected) x = SizeStruct.new_from_bytes(8, -1) y = SizeStruct.new_from_bytes(16, -1) actual = x.sub(y).get_bytes() expected = (8, 1) self.assertEqual(actual, expected) x = SizeStruct.new_from_bytes(0, 0) y = SizeStruct.new_from_bytes(16, -1) actual = x.sub(y).get_bytes() expected = (16, 1) self.assertEqual(actual, expected) x = SizeStruct.new_from_bytes(0, 0) y = SizeStruct.new_from_bytes(0, 0) actual = x.sub(y).get_bytes() expected = (0, 0) self.assertEqual(actual, expected) #enddef def testSubBytes(self): x = SizeStruct.new_from_bytes(8, 1) actual = x.sub_bytes(16).get_bytes() expected = (8, -1) self.assertEqual(actual, expected) x = SizeStruct.new_from_bytes(8, 1) actual = x.sub_bytes(8).get_bytes() expected = (0, 0) self.assertEqual(actual, expected) x = SizeStruct.new_from_bytes(8, -1) actual = x.sub_bytes(0).get_bytes() expected = (8, -1) self.assertEqual(actual, expected) # try some big value (bigger than ULONG_MAX on 32bit arches) x = SizeStruct.new_from_bytes(2**36 + 10, 1) actual = x.sub_bytes(2**36).get_bytes() expected = (10, 1) self.assertEqual(actual, expected) #enddef def testCmp(self): x = SizeStruct.new_from_str("1 KiB") y = SizeStruct.new_from_str("-1 KiB") # params: SizeStruct x, SizeStruct y, bool abs # result > 0 cmpResult = SizeStruct.cmp(x, y, False) self.assertGreater(cmpResult, 0) # result < 0 cmpResult = SizeStruct.cmp(y, x, False) self.assertLess(cmpResult, 0) # result == 0 cmpResult = SizeStruct.cmp(y, x, True) self.assertEqual(cmpResult, 0) #enddef def testCmpBytes(self): x = SizeStruct.new_from_str("1 KiB") # result > 0 y = 1023 cmpResult = SizeStruct.cmp_bytes(x, y, False) self.assertGreater(cmpResult, 0) # result < 0 y = 1025 cmpResult = SizeStruct.cmp_bytes(x, y, False) self.assertLess(cmpResult, 0) # result == 0 y = 1024 cmpResult = SizeStruct.cmp_bytes(x, y, False) self.assertEqual(cmpResult, 0) # test with abs == True x = SizeStruct.new_from_str("-1 KiB") # result > 0 y = 1023 cmpResult = SizeStruct.cmp_bytes(x, y, True) self.assertGreater(cmpResult, 0) # result < 0 y = 1025 cmpResult = SizeStruct.cmp_bytes(x, y, True) self.assertLess(cmpResult, 0) # result == 0 y = 1024 cmpResult = SizeStruct.cmp_bytes(x, y, True) self.assertEqual(cmpResult, 0) #enddef def testConvertTo(self): x = SizeStruct.new_from_str("1 KiB") x.convert_to(KiB) #enddef def testDiv(self): x = SizeStruct.new_from_str("1 KiB") y = SizeStruct.new_from_str("-0.1 KiB") divResult = x.div(y) self.assertEqual(divResult, (10, -1)) x = SizeStruct.new_from_str("1 MiB") y = SizeStruct.new_from_str("1 KiB") divResult = x.div(y) self.assertEqual(divResult, (1024, 1)) x = SizeStruct.new_from_str("1 GB") y = SizeStruct.new_from_str("0.7 GB") divResult = x.div(y) self.assertEqual(divResult, (1, 1)) x = SizeStruct.new_from_str("-1 KiB") y = SizeStruct.new_from_str("0.1 KiB") divResult = x.div(y) self.assertEqual(divResult, (10, -1)) #enddef def testDivInt(self): x = SizeStruct.new_from_str("1 MiB") y = 1024 divResult = x.div_int(y).get_bytes() self.assertEqual(divResult, (1024, 1)) x = SizeStruct.new_from_str("-1 MiB") y = 1077 divResult = x.div_int(y).get_bytes() self.assertEqual(divResult, (973, -1)) try: x = SizeStruct.new_from_bytes(2 * 2**36, 1) y = 2**36 res = x.div_int(y).get_bytes() self.assertEqual(res, (2, 1)) except OverflowError: # ULONG_MAX is the real limit for division, if it's smaller than # UINT64_MAX, an error is expected, otherwise it is a bug if ctypes.sizeof(ctypes.c_ulong) == 4: pass #enddef def testGetBytesStr(self): strSizeStruct = SizeStruct.new_from_str("-1 KiB").get_bytes_str() self.assertEqual(strSizeStruct, "-1024") #enddef @requires_locales({'cs_CZ.UTF-8'}) def testHumanReadable(self): strSizeStruct = SizeStruct.new_from_str("12 KiB").human_readable(KiB, 2, False) self.assertEqual(strSizeStruct, "12 KiB") strSizeStruct = SizeStruct.new_from_str("1 KB").human_readable(KiB, 2, False) self.assertEqual(strSizeStruct, "0.98 KiB") locale.setlocale(locale.LC_ALL, 'cs_CZ.UTF-8') strSizeStruct = SizeStruct.new_from_str("1 KB").human_readable(KiB, 2, True) self.assertEqual(strSizeStruct, "0,98 KiB") locale.setlocale(locale.LC_ALL, DEFAULT_LOCALE); strSizeStruct = SizeStruct.new_from_str("100 GiB").human_readable(KiB, 2, False) self.assertEqual(strSizeStruct, "100 GiB") strSizeStruct = SizeStruct.new_from_str("100.00 GiB").human_readable(KiB, 2, False) self.assertEqual(strSizeStruct, "100 GiB") strSizeStruct = SizeStruct.new_from_str("100 GiB").human_readable(KiB, 0, False) self.assertEqual(strSizeStruct, "100 GiB") # test that the result of human_readable() can be parsed back strSizeStruct = SizeStruct.new_from_str("100 GiB").human_readable(GiB, 0, False) self.assertEqual(SizeStruct.new_from_str(strSizeStruct).get_bytes(), (100 * 1024**3, 1)) # even if translated strSizeStruct = SizeStruct.new_from_str("100 GiB").human_readable(GiB, 0, True) self.assertEqual(SizeStruct.new_from_str(strSizeStruct).get_bytes(), (100 * 1024**3, 1)) #enddef def testSgn(self): sgn = SizeStruct.new_from_str("12 KiB").sgn() self.assertEqual(sgn, 1) sgn = SizeStruct.new_from_str("0 MB").sgn() self.assertEqual(sgn, 0) sgn = SizeStruct.new_from_str("-12 GiB").sgn() self.assertEqual(sgn, -1) #enddef def testTrueDiv(self): x = SizeStruct.new_from_str("1024 B") y = SizeStruct.new_from_str("-102.4 B") # rounds to whole bytes divResult = float(x.true_div(y)[:15].replace(locale.nl_langinfo(locale.RADIXCHAR), ".")) # just some number to cover accurancy and not cross max float range self.assertAlmostEqual(divResult, 1024.0/-102.0) x = SizeStruct.new_from_str("1 MiB") y = SizeStruct.new_from_str("1 KiB") divResult = float(x.true_div(y)[:15].replace(locale.nl_langinfo(locale.RADIXCHAR), ".")) # just some number to cover accurancy and not cross max float range self.assertAlmostEqual(divResult, 1024.0) #enddef def testMod(self): x = SizeStruct.new_from_str("1024 B") y = SizeStruct.new_from_str("1000 B") actual = x.mod(y).get_bytes() expected = (24, 1) self.assertEqual(actual, expected) # when modding the signs are ignored x = SizeStruct.new_from_str("1024 B") y = SizeStruct.new_from_str("-1000 B") actual = x.mod(y).get_bytes() expected = (24, 1) self.assertEqual(actual, expected) x = SizeStruct.new_from_str("-1024 B") y = SizeStruct.new_from_str("1000 B") actual = x.mod(y).get_bytes() expected = (24, 1) self.assertEqual(actual, expected) x = SizeStruct.new_from_str("-1024 B") y = SizeStruct.new_from_str("-1000 B") actual = x.mod(y).get_bytes() expected = (24, 1) self.assertEqual(actual, expected) x = SizeStruct.new_from_str("1024 B") y = SizeStruct.new_from_str("1024 B") actual = x.mod(y).get_bytes() expected = (0, 0) self.assertEqual(actual, expected) #enddef def testMulFloatStr(self): x = SizeStruct.new_from_str("8 B") actual = x.mul_float_str("1.51").get_bytes() self.assertEqual(actual, (12, 1)) x = SizeStruct.new_from_str("-8 B") actual = x.mul_float_str("1.51").get_bytes() self.assertEqual(actual, (12, -1)) x = SizeStruct.new_from_str("8 B") actual = x.mul_float_str("-1.51").get_bytes() self.assertEqual(actual, (12, -1)) #enddef def testMulInt(self): x = SizeStruct.new_from_str("8 B") y = 2 actual = x.mul_int(y).get_bytes() expected = (16, 1) self.assertEqual(actual, expected) x = SizeStruct.new_from_str("0 B") y = 1 actual = x.mul_int(y).get_bytes() expected = (0, 0) self.assertEqual(actual, expected) x = SizeStruct.new_from_str("10 B") y = 0 actual = x.mul_int(y).get_bytes() expected = (0, 0) self.assertEqual(actual, expected) x = SizeStruct.new_from_bytes(4, 1) y = 2**36 actual = x.mul_int(y).get_bytes() expected = (4 * 2**36, 1) self.assertEqual(actual, expected) #enddef def testRoundToNearest(self): x = SizeStruct.new_from_str("1500 B") roundTo = SizeStruct.new_from_str("1 KiB") actual = x.round_to_nearest(roundTo, ROUND_UP).get_bytes() expected = (2048, 1) self.assertEqual(actual, expected) x = SizeStruct.new_from_str("1500 B") roundTo = SizeStruct.new_from_str("1 KiB") actual = x.round_to_nearest(roundTo, ROUND_DOWN).get_bytes() expected = (1024, 1) self.assertEqual(actual, expected) x = SizeStruct.new_from_str("1500 B") roundTo = SizeStruct.new_from_str("10 KiB") actual = x.round_to_nearest(roundTo, ROUND_DOWN).get_bytes() expected = (0, 0) self.assertEqual(actual, expected) x = SizeStruct.new_from_str("1024 B") roundTo = SizeStruct.new_from_str("1 KiB") actual = x.round_to_nearest(roundTo, ROUND_DOWN).get_bytes() expected = (1024, 1) self.assertEqual(actual, expected) actual = x.round_to_nearest(roundTo, ROUND_UP).get_bytes() expected = (1024, 1) self.assertEqual(actual, expected) actual = x.round_to_nearest(roundTo, ROUND_HALF_UP).get_bytes() expected = (1024, 1) self.assertEqual(actual, expected) x = SizeStruct.new_from_str("1023 B") actual = x.round_to_nearest(roundTo, ROUND_DOWN).get_bytes() expected = (0, 0) self.assertEqual(actual, expected) actual = x.round_to_nearest(roundTo, ROUND_UP).get_bytes() expected = (1024, 1) self.assertEqual(actual, expected) actual = x.round_to_nearest(roundTo, ROUND_HALF_UP).get_bytes() expected = (1024, 1) self.assertEqual(actual, expected) x = SizeStruct.new_from_str("1025 B") actual = x.round_to_nearest(roundTo, ROUND_DOWN).get_bytes() expected = (1024, 1) self.assertEqual(actual, expected) actual = x.round_to_nearest(roundTo, ROUND_UP).get_bytes() expected = (2048, 1) self.assertEqual(actual, expected) actual = x.round_to_nearest(roundTo, ROUND_HALF_UP).get_bytes() expected = (1024, 1) self.assertEqual(actual, expected) x = SizeStruct.new_from_str("1535 B") actual = x.round_to_nearest(roundTo, ROUND_DOWN).get_bytes() expected = (1024, 1) self.assertEqual(actual, expected) actual = x.round_to_nearest(roundTo, ROUND_UP).get_bytes() expected = (2048, 1) self.assertEqual(actual, expected) actual = x.round_to_nearest(roundTo, ROUND_HALF_UP).get_bytes() expected = (1024, 1) self.assertEqual(actual, expected) x = SizeStruct.new_from_str("1536 B") actual = x.round_to_nearest(roundTo, ROUND_DOWN).get_bytes() expected = (1024, 1) self.assertEqual(actual, expected) actual = x.round_to_nearest(roundTo, ROUND_UP).get_bytes() expected = (2048, 1) self.assertEqual(actual, expected) actual = x.round_to_nearest(roundTo, ROUND_HALF_UP).get_bytes() expected = (2048, 1) self.assertEqual(actual, expected) # now check something bigger x = SizeStruct.new_from_str("575 GiB") roundTo = SizeStruct.new_from_str("128 GiB") actual = x.round_to_nearest(roundTo, ROUND_HALF_UP).get_bytes_str() expected = SizeStruct.new_from_str("512 GiB").get_bytes_str() self.assertEqual(actual, expected) x = SizeStruct.new_from_str("576 GiB") roundTo = SizeStruct.new_from_str("128 GiB") actual = x.round_to_nearest(roundTo, ROUND_HALF_UP).get_bytes_str() expected = SizeStruct.new_from_str("640 GiB").get_bytes_str() self.assertEqual(actual, expected) #enddef def testGrow(self): x = SizeStruct.new_from_bytes(16, 1) y = SizeStruct.new_from_bytes(8, 1) x.grow(y) actual = x.get_bytes() expected = (24, 1) self.assertEqual(actual, expected) #enddef def testGrowBytes(self): x = SizeStruct.new_from_bytes(16, 1) x.grow_bytes(8) actual = x.get_bytes() expected = (24, 1) self.assertEqual(actual, expected) x = SizeStruct.new_from_bytes(16, 1) x.grow_bytes(2**36) actual = x.get_bytes() expected = (16 + 2**36, 1) self.assertEqual(actual, expected) #enddef def testGrowMulFloatStr(self): x = SizeStruct.new_from_str("8 B") x.grow_mul_float_str("1.51") actual = x.get_bytes() self.assertEqual(actual, (12, 1)) x = SizeStruct.new_from_str("-8 B") x.grow_mul_float_str("1.51") actual = x.get_bytes() self.assertEqual(actual, (12, -1)) x = SizeStruct.new_from_str("8 B") x.grow_mul_float_str("-1.51") actual = x.get_bytes() self.assertEqual(actual, (12, -1)) #enddef def testGrowMulInt(self): x = SizeStruct.new_from_str("8 B") x.grow_mul_int(2) actual = x.get_bytes() expected = (16, 1) self.assertEqual(actual, expected) x = SizeStruct.new_from_str("0 B") x.grow_mul_int(1) actual = x.get_bytes() expected = (0, 0) self.assertEqual(actual, expected) x = SizeStruct.new_from_str("10 B") x.grow_mul_int(0) actual = x.get_bytes() expected = (0, 0) self.assertEqual(actual, expected) x = SizeStruct.new_from_bytes(4, 1) x.grow_mul_int(2**36) actual = x.get_bytes() expected = (4 * 2**36, 1) self.assertEqual(actual, expected) #enddef def testShrink(self): x = SizeStruct.new_from_bytes(16, 1) y = SizeStruct.new_from_bytes(8, 1) x.shrink(y) actual = x.get_bytes() expected = (8, 1) self.assertEqual(actual, expected) x = SizeStruct.new_from_bytes(8, 1) y = SizeStruct.new_from_bytes(16, 1) x.shrink(y) actual = x.get_bytes() expected = (8, -1) self.assertEqual(actual, expected) #enddef def testShrinkBytes(self): x = SizeStruct.new_from_str("8 B") x.shrink_bytes(2) actual = x.get_bytes() expected = (6, 1) self.assertEqual(actual, expected) x = SizeStruct.new_from_str("8 B") x.shrink_bytes(16) actual = x.get_bytes() expected = (8, -1) self.assertEqual(actual, expected) x = SizeStruct.new_from_str("-8 B") x.shrink_bytes(8) actual = x.get_bytes() expected = (16, -1) self.assertEqual(actual, expected) x = SizeStruct.new_from_bytes(2 * 2**36, 1) x.shrink_bytes(2**36) actual = x.get_bytes() expected = (2**36, 1) self.assertEqual(actual, expected) #enddef def testShrinkDivInt(self): x = SizeStruct.new_from_str("100 B") y = 11 x.shrink_div_int(y) actual = x.get_bytes() expected = (9, 1) self.assertEqual(actual, expected) x = SizeStruct.new_from_str("98 B") y = 11 x.shrink_div_int(y) actual = x.get_bytes() expected = (8, 1) self.assertEqual(actual, expected) x = SizeStruct.new_from_bytes(2 * 2**36, 1) y = 2**36 try: res = x.shrink_div_int(y).get_bytes() self.assertEqual(res, (2, 1)) except OverflowError: # ULONG_MAX is the real limit for division, if it's smaller than # UINT64_MAX, an error is expected, otherwise it is a bug if ctypes.sizeof(ctypes.c_ulong) == 4: pass #enddef def testTrueDivInt(self): x = SizeStruct.new_from_str("1000 B") y = 100 divResult = float(x.true_div_int(y)[:15]) # just some number to cover accuracy and not cross max float range self.assertAlmostEqual(divResult, 1000.0/100.0) x = SizeStruct.new_from_str("-1 MiB") y = 1024 divResult = float(x.true_div_int(y)[:15]) # just some number to cover accuracy and not cross max float range self.assertAlmostEqual(divResult, -1024.0) x = SizeStruct.new_from_str("0 MiB") y = 1024 divResult = float(x.true_div_int(y)[:15]) # just some number to cover accuracy and not cross max float range self.assertAlmostEqual(divResult, 0.0) x = SizeStruct.new_from_bytes(10 * 2**36, 1) y = 2**36 try: res = float(x.true_div_int(y)[:15]) self.assertAlmostEqual(res, 10.0) except OverflowError: # ULONG_MAX is the real limit for division, if it's smaller than # UINT64_MAX, an error is expected, otherwise it is a bug if ctypes.sizeof(ctypes.c_ulong) == 4: pass #enddef #endclass # script entry point if __name__=='__main__': if len(sys.argv) > 1: DEFAULT_LOCALE = sys.argv[1] # the unittest module would try to intepret the argument too, let's # remove it sys.argv = [sys.argv[0]] unittest.main() #endif libbytesize-2.2/tests/libbytesize_unittest.sh.in000066400000000000000000000006101361502636100222710ustar00rootroot00000000000000#!/bin/bash status=0 # If not run from automake, fake it if [ -z "$srcdir" ]; then srcdir="$(dirname "$0")" fi if [ @WITH_PYTHON3@ = 1 ]; then python3 ${srcdir}/libbytesize_unittest.py || status=1 python3 ${srcdir}/lbs_py_override_unittest.py || status=1 fi if [ @WITH_PYTHON3@ = 1 ]; then python3 ${srcdir}/libbytesize_unittest.py fr_FR.UTF8 || status=1 fi exit $status libbytesize-2.2/tests/locale_utils.py000066400000000000000000000016141361502636100201020ustar00rootroot00000000000000 import subprocess """Helper functions, decorators,... for working with locales""" def get_avail_locales(): return {loc.decode(errors="replace").strip() for loc in subprocess.check_output(["locale", "-a"]).split()} def requires_locales(locales): """A decorator factory to skip tests that require unavailable locales :param set locales: set of required locales **Requires the test to have the set of available locales defined as its ``avail_locales`` attribute.** """ canon_locales = {loc.replace("UTF-8", "utf8") for loc in locales} def decorator(test_method): def decorated(test, *args): missing = canon_locales - set(test.avail_locales) if missing: test.skipTest("requires missing locales: %s" % missing) else: return test_method(test, *args) return decorated return decorator libbytesize-2.2/tests/testenv.sh000066400000000000000000000010301361502636100170650ustar00rootroot00000000000000#!/bin/sh if [ -z "$top_srcdir" ]; then echo "*** top_srcdir must be set" fi # If no top_builddir is set, use top_srcdir : "${top_builddir:=$top_srcdir}" if [ -z "$PYTHONPATH" ]; then PYTHONPATH="${top_srcdir}/src/python" else PYTHONPATH="${PYTHONPATH}:${top_srcdir}/src/python" fi if [ -z "$LD_LIBRARY_PATH" ]; then LD_LIBRARY_PATH="${top_builddir}/src/.libs" else LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${top_builddir}/src/.libs" fi export PYTHONPATH export LD_LIBRARY_PATH export top_srcdir export top_builddir libbytesize-2.2/tools/000077500000000000000000000000001361502636100150455ustar00rootroot00000000000000libbytesize-2.2/tools/Makefile.am000066400000000000000000000003721361502636100171030ustar00rootroot00000000000000if WITH_TOOLS dist_noinst_SCRIPTS = bs_calc.py dist_man1_MANS = bscalc.man install-exec-local: install -d ${DESTDIR}${bindir} install -m0755 ${builddir}/bs_calc.py ${DESTDIR}${bindir}/bscalc uninstall-local: rm ${DESTDIR}${bindir}/bscalc endif libbytesize-2.2/tools/bs_calc.py.in000066400000000000000000000114621361502636100174160ustar00rootroot00000000000000#!/usr/bin/python3 import sys from argparse import ArgumentParser from decimal import Decimal, InvalidOperation from bytesize import Size, ZeroDivisionError b_units = ("B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB") d_units = ("KB", "MB", "GB", "TB", "PB", "EB") _WHITESPACE = {" ", "\t", "\n"} _OPERATORS = {"+", "-", "*", "/", "%", "(", ")"} # TODO: add divmod _DOUBLE_OPERATORS = {"/", "*"} # // and ** are valid operators too _EXP_OPERATORS = {"-", "+"} # 1e+2, 1e-2 def _get_operand(op_str): try: return int(op_str) except ValueError: try: return Decimal(op_str) except InvalidOperation: return Size(op_str) def _tokenize(expression): tokens = [] operand_str_start = -1 for i, char in enumerate(expression): if char in _WHITESPACE: continue elif char in _OPERATORS: if char in _EXP_OPERATORS and expression[i - 1] in ("e", "E"): continue if char in _DOUBLE_OPERATORS and expression[i - 1] == char: # see _DOUBLE_OPERATORS above tokens[-1] = tokens[-1] + char continue if operand_str_start != -1: op = _get_operand(expression[operand_str_start:i]) tokens.append(op) operand_str_start = -1 tokens.append(expression[i]) elif operand_str_start == -1: operand_str_start = i if operand_str_start != -1: op = _get_operand(expression[operand_str_start:]) tokens.append(op) return tokens def _tokens_to_eval_str(tokens): eval_tokens = [] for token in tokens: if isinstance(token, int): eval_tokens.append("%d" % token) elif isinstance(token, Decimal): eval_tokens.append("Decimal('%s')" % token) elif isinstance(token, Size): eval_tokens.append("Size(%d)" % token) else: eval_tokens.append(token) return " ".join(eval_tokens) def _print_result(result, args): # TODO: support configurable n_places (aligned printing is not so easy then) n_places = 2 if isinstance(result, Size): if args.unit is not None: value = result.convert_to(args.unit) if int(value) == value: print("%d %s" % (int(value), args.unit)) else: print(("%0." + str(n_places) + "f" + " %s") % (value, args.unit)) else: in_bytes = "%d B" % int(result) print(in_bytes) format_str = "%" + str(len(in_bytes) - n_places) + "." + str(n_places) + "f" for b_unit in b_units[1:]: converted = (format_str % result.convert_to(b_unit)) # don't print "0.00 CRAZY_BIG_UNIT" if converted.strip() not in ("0." + n_places * "0", "-0." + n_places * "0"): print("%s %s" % (converted, b_unit)) else: print(str(result)) def _main(): ap = ArgumentParser(epilog="Report issues at https://github.com/storaged-project/libbytesize/issues") ap.add_argument("--version", action="version", version="@VERSION@") ap.add_argument("-u", "--unit", choices=(b_units + d_units), help="Unit to show the result in") ap.add_argument("-b", "-B", dest="unit", const="B", help="Show result in bytes", action="store_const") for b_unit in b_units[1:]: ap.add_argument("-" + b_unit[0].lower(), "-" + b_unit[0], "--" + b_unit, dest="unit", const=b_unit, help="Show result in " + b_unit, action="store_const") for d_unit in d_units: ap.add_argument("--" + d_unit, dest="unit", const=d_unit, help="Show result in " + d_unit, action="store_const") ap.add_argument(metavar="EXPRESSION_PART", dest="expressions", nargs="+") args = ap.parse_args() try: tokens = _tokenize(" ".join(args.expressions)) except ValueError as e: print("Error while parsing expression: %s" % e) return 1 any_size = any(isinstance(token, Size) for token in tokens) eval_str = _tokens_to_eval_str(tokens) try: result = eval(eval_str) except (TypeError, ValueError, ZeroDivisionError) as e: print("Error during evaluation: %s" % e) return 1 except SyntaxError as e: print("Error during evaluation: %s" % e.msg) print(eval_str) print(" " * (e.offset - 1) + "^") return 1 # The given expression contained no Size, just numbers. By default we just # assume the whole expression was in bytes so let's convert the result # before printing it. if not any_size: result = Size(result) _print_result(result, args) return 0 if __name__ == "__main__": sys.exit(_main()) libbytesize-2.2/tools/bscalc.man000066400000000000000000000026461361502636100170010ustar00rootroot00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.11. .TH BSCALC "1" "January 2020" "bscalc 2.2" "User Commands" .SH NAME bscalc \- manual page for bscalc 2.2 .SH DESCRIPTION usage: bscalc [\-h] [\-\-version] .IP [\-u {B,KiB,MiB,GiB,TiB,PiB,EiB,KB,MB,GB,TB,PB,EB}] [\-b] [\-k] [\-m] [\-g] [\-t] [\-p] [\-e] [\-\-KB] [\-\-MB] [\-\-GB] [\-\-TB] [\-\-PB] [\-\-EB] EXPRESSION_PART [EXPRESSION_PART ...] .SS "positional arguments:" .IP EXPRESSION_PART .SS "optional arguments:" .TP \fB\-h\fR, \fB\-\-help\fR show this help message and exit .TP \fB\-\-version\fR show program's version number and exit .TP \fB\-u\fR {B,KiB,MiB,GiB,TiB,PiB,EiB,KB,MB,GB,TB,PB,EB}, \fB\-\-unit\fR {B,KiB,MiB,GiB,TiB,PiB,EiB,KB,MB,GB,TB,PB,EB} Unit to show the result in .TP \fB\-b\fR, \fB\-B\fR Show result in bytes .TP \fB\-k\fR, \fB\-K\fR, \fB\-\-KiB\fR Show result in KiB .TP \fB\-m\fR, \fB\-M\fR, \fB\-\-MiB\fR Show result in MiB .TP \fB\-g\fR, \fB\-G\fR, \fB\-\-GiB\fR Show result in GiB .TP \fB\-t\fR, \fB\-T\fR, \fB\-\-TiB\fR Show result in TiB .TP \fB\-p\fR, \fB\-P\fR, \fB\-\-PiB\fR Show result in PiB .TP \fB\-e\fR, \fB\-E\fR, \fB\-\-EiB\fR Show result in EiB .TP \fB\-\-KB\fR Show result in KB .TP \fB\-\-MB\fR Show result in MB .TP \fB\-\-GB\fR Show result in GB .TP \fB\-\-TB\fR Show result in TB .TP \fB\-\-PB\fR Show result in PB .TP \fB\-\-EB\fR Show result in EB .PP Report issues at https://github.com/storaged\-project/libbytesize/issues libbytesize-2.2/translation-canary/000077500000000000000000000000001361502636100175165ustar00rootroot00000000000000libbytesize-2.2/translation-canary/.gitignore000066400000000000000000000000511361502636100215020ustar00rootroot00000000000000__pycache__ *.pyc tests/pylint/.pylint.d libbytesize-2.2/translation-canary/COPYING000066400000000000000000000636421361502636100205640ustar00rootroot00000000000000 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! libbytesize-2.2/translation-canary/Makefile000066400000000000000000000004501361502636100211550ustar00rootroot00000000000000# This Makefile is just for running the tests all: @echo "nothing to build" check: PYTHONPATH=. tests/pylint/runpylint.py python3 -m unittest discover tests/unittests test-projects: PYTHONPATH=. tests/project-tests/test_projects.sh tests/project-tests/project_list.txt ci: $(MAKE) check libbytesize-2.2/translation-canary/README.rst000066400000000000000000000033441361502636100212110ustar00rootroot00000000000000translation-canary ------------- Translations can crash your program. Creating software for a wide audience means sending your strings away for translation, and giving up control of your strings means that strings with extralinguistic content can come back broken. No one is likely to even realize it until someone fires up your program in Hungarian and it crashes because Gtk bombed out on some busted markup, and the Hungarian speaker is sad, and you are sad, and everything is just the absolute worst. This is the canary in the translation coalmine. There are two parts to this project: translatable: This contains checks on the strings to be submitted for translation. This ensures that the content of the original strings marked for translation are suitable for translation. These tests are run on the POT file before uploading the POT or the updated PO files to the translators. translated: This contains checks on the strings returned from the translators. This ensures that the content of the translated strings won't break anything. These tests are run on the source directory before creating a release. Both translatable and translated are run by running the module (e.g., `python3 -m translation_canary.translatable`) with the input file(s) as the argument. In addition to the python modules, this project contains xgettext_werror.sh, a wrapper for xgettext that treats warnings as errors. xgettext will print warnings as it extracts translatable strings from source files, and these warnings should be addressed instead of silently ignored as they scroll by in the build output. To use the script in a package that uses the gettext template files from autopoint or gettextize, set XGETTEXT=/path/to/xgettext_werror.sh in Makevars. libbytesize-2.2/translation-canary/tests/000077500000000000000000000000001361502636100206605ustar00rootroot00000000000000libbytesize-2.2/translation-canary/tests/project-tests/000077500000000000000000000000001361502636100234665ustar00rootroot00000000000000libbytesize-2.2/translation-canary/tests/project-tests/project_list.txt000066400000000000000000000005741361502636100267360ustar00rootroot00000000000000anaconda f24-branch anaconda rhel6-branch anaconda rhel7-branch anaconda master blivet 2.0 blivet 1.20 blivet rhel6-branch blivet rhel7-branch blivet master blivet-gui f24-branch blivet-gui f23-branch initial-setup rhel7-branch initial-setup master pykickstart pykickstart-2 pykickstart rhel7-branch pykickstart master libbytesize master python-meh rhel7-branch python-meh master libbytesize-2.2/translation-canary/tests/project-tests/test_projects.sh000077500000000000000000000040041361502636100267130ustar00rootroot00000000000000#!/bin/sh # Copyright (C) 2016 Red Hat, Inc. # # This copyrighted material is made available to anyone wishing to use, # modify, copy, or redistribute it subject to the terms and conditions of # the GNU Lesser General Public License v.2, or (at your option) any later # version. This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY expressed or implied, including the implied # warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See # the GNU Lesser General Public License for more details. You should have # received a copy of the GNU Lesser General Public License along with this # program; if not, write to the Free Software Foundation, Inc., 51 Franklin # Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat trademarks # that are incorporated in the source code or documentation are not subject # to the GNU Lesser General Public License and may only be used or # replicated with the express permission of Red Hat, Inc. # # Red Hat Author(s): David Shea # Test a project's .po files if [ $# -ne 1 ]; then echo "Usage: test_projects.sh " exit 1 fi status=0 while read project_name branch ; do echo "Testing $project_name:$branch" podir="$(mktemp -d ${project_name}-${branch}.XXXXXX)" # The zanata output only matters if something goes wrong zanata_output="$(zanata pull --project-type gettext --project-id "$project_name" --project-version "$branch" --transdir "$podir" --url https://fedora.zanata.org/ 2>&1)" if [ $? -ne 0 ]; then echo "Zanata pull failed for $project_name:$branch" echo "$zanata_output" status=1 rm -rf "$podir" continue fi # Ignore the percent-translated warnings python3 -W ignore -m translation_canary.translated "$podir" if [ $? -ne 0 ]; then echo "Canary test failed for $project_name:$branch" status=1 else echo "Success: $project_name:$branch" fi rm -rf "$podir" done < "$1" exit "$status" libbytesize-2.2/translation-canary/tests/pylint/000077500000000000000000000000001361502636100221775ustar00rootroot00000000000000libbytesize-2.2/translation-canary/tests/pylint/runpylint.py000077500000000000000000000007361361502636100246260ustar00rootroot00000000000000#!/usr/bin/python3 import sys from pocketlint import PocketLintConfig, PocketLinter class TranslationCanaryLintConfig(PocketLintConfig): @property def disabledOptions(self): return [ "I0011", # Locally disabling %s ] @property def extraArgs(self): return ["--init-import", "y"] if __name__ == "__main__": conf = TranslationCanaryLintConfig() linter = PocketLinter(conf) rc = linter.run() sys.exit(rc) libbytesize-2.2/translation-canary/tests/unittests/000077500000000000000000000000001361502636100227225ustar00rootroot00000000000000libbytesize-2.2/translation-canary/tests/unittests/test_translatable.py000066400000000000000000000072311361502636100270120ustar00rootroot00000000000000# Copyright (C) 2015 Red Hat, Inc. # # This copyrighted material is made available to anyone wishing to use, # modify, copy, or redistribute it subject to the terms and conditions of # the GNU Lesser General Public License v.2, or (at your option) any later # version. This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY expressed or implied, including the implied # warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See # the GNU Lesser General Public License for more details. You should have # received a copy of the GNU Lesser General Public License along with this # program; if not, write to the Free Software Foundation, Inc., 51 Franklin # Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat trademarks # that are incorporated in the source code or documentation are not subject # to the GNU Lesser General Public License and may only be used or # replicated with the express permission of Red Hat, Inc. # # Red Hat Author(s): David Shea import unittest import unittest.mock from polib import POEntry, POFile import tempfile from translation_canary.translatable.test_markup import test_markup from translation_canary.translatable.test_comment import test_comment from translation_canary.translatable import testString, testPOT class TestMarkup(unittest.TestCase): def test_ok(self): # no markup test_markup(POEntry(msgid="test string")) # internal markup test_markup(POEntry(msgid="test string")) def test_unnecessary_markup(self): self.assertRaises(AssertionError, test_markup, POEntry(msgid="test string")) class TestComment(unittest.TestCase): def test_ok(self): # Perfectly fine string test_comment(POEntry(msgid="Hello, I am a test string")) # single-character string with a comment test_comment(POEntry(msgid="c", comment="TRANSLATORS: 'c' to continue")) def test_no_comment(self): self.assertRaises(AssertionError, test_comment, POEntry(msgid="c")) # Test the top-level functions # fake tests for testing with def _true_test(_s): pass def _false_test(_s): raise AssertionError("no good") def _picky_test(s): if s.msgstr.startswith("p"): raise AssertionError("I don't like this one") class TestTestString(unittest.TestCase): @unittest.mock.patch("translation_canary.translatable._tests", [_true_test]) def test_success(self): self.assertTrue(testString(POEntry())) @unittest.mock.patch("translation_canary.translatable._tests", [_false_test]) def test_failure(self): self.assertFalse(testString(POEntry())) @unittest.mock.patch("translation_canary.translatable._tests", [_picky_test]) class TestTestPOT(unittest.TestCase): def test_success(self): with tempfile.NamedTemporaryFile(suffix=".pot") as potfile: poobj = POFile() poobj.append(POEntry(msgstr="test string")) poobj.save(potfile.name) self.assertTrue(testPOT(potfile.name)) def test_some_failure(self): with tempfile.NamedTemporaryFile(suffix=".pot") as potfile: poobj = POFile() poobj.append(POEntry(msgstr="test string")) poobj.append(POEntry(msgstr="pest string")) poobj.save(potfile.name) self.assertFalse(testPOT(potfile.name)) def test_all_failure(self): with tempfile.NamedTemporaryFile(suffix=".pot") as potfile: poobj = POFile() poobj.append(POEntry(msgstr="pest string")) poobj.append(POEntry(msgstr="past string")) poobj.save(potfile.name) self.assertFalse(testPOT(potfile.name)) libbytesize-2.2/translation-canary/tests/unittests/test_translated.py000066400000000000000000000267251361502636100265100ustar00rootroot00000000000000# Copyright (C) 2015 Red Hat, Inc. # # This copyrighted material is made available to anyone wishing to use, # modify, copy, or redistribute it subject to the terms and conditions of # the GNU Lesser General Public License v.2, or (at your option) any later # version. This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY expressed or implied, including the implied # warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See # the GNU Lesser General Public License for more details. You should have # received a copy of the GNU Lesser General Public License along with this # program; if not, write to the Free Software Foundation, Inc., 51 Franklin # Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat trademarks # that are incorporated in the source code or documentation are not subject # to the GNU Lesser General Public License and may only be used or # replicated with the express permission of Red Hat, Inc. # # Red Hat Author(s): David Shea import unittest import unittest.mock import tempfile import warnings import polib import os from translation_canary.translated.test_markup import test_markup from translation_canary.translated.test_percentage import test_percentage from translation_canary.translated.test_usability import test_usability, test_msgfmt from translation_canary.translated import testFile, testSourceTree # convert a polib.POFile into a NamedTemporaryFile def pofile(poobj): f = tempfile.NamedTemporaryFile(suffix='.po') poobj.save(f.name) return f # convenience function for creating a single-entry mofile def pofile_from_entry(*args, **kwargs): poobj = polib.POFile() poobj.metadata["Content-Type"] = "text/plain; charset=UTF-8" poobj.append(polib.POEntry(*args, **kwargs)) return pofile(poobj) class TestMarkup(unittest.TestCase): # I know, pylint, that's the point # pylint: disable=invalid-markup def test_ok(self): # no markup with pofile_from_entry(msgid="test string", msgstr="estay ingstray") as p: test_markup(p.name) # matching markup with pofile_from_entry(msgid="bold string", msgstr="oldbay ingstray") as p: test_markup(p.name) # matching plural with pofile_from_entry(msgid="%d bold string", msgid_plural="%d bold strings", msgstr_plural={0: "%d oldbay ingstray", 1: "%d oldbay instrays"}) as p: test_markup(p.name) def test_missing(self): with pofile_from_entry(msgid="bold string", msgstr="oldbay ingstray") as p: self.assertRaises(AssertionError, test_markup, p.name) def test_mismatch(self): with pofile_from_entry(msgid="bold string", msgstr="oldbay ingstray") as p: self.assertRaises(AssertionError, test_markup, p.name) def test_typo(self): with pofile_from_entry(msgid="bold string", msgstr=" ingstray") as p: self.assertRaises(AssertionError, test_markup, p.name) def test_mismatch_plural(self): with pofile_from_entry(msgid="%d bold string", msgid_plural="%d bold strings", msgstr_plural={0: "%d olbday ingstray", 1: "%d oldbay ingstrays"}) as p: self.assertRaises(AssertionError, test_markup, p.name) def test_invalid(self): # Tags themselves are valid, but the XML is not with pofile_from_entry(msgid="bold string", msgstr="oldbay ingstray") as p: self.assertRaises(AssertionError, test_markup, p.name) class TestPercentage(unittest.TestCase): def setUp(self): # Convert warnings into exceptions to make them easier to test for warnings.simplefilter("error") # polib throws a DeprecationWarnings so ignore that warnings.simplefilter("default", DeprecationWarning) def tearDown(self): warnings.resetwarnings() def test_ok(self): # 100% with pofile_from_entry(msgid="test string", msgstr="estay ingstray") as p: test_percentage(p.name) def test_not_ok(self): # 0% with pofile_from_entry(msgid="test string", msgstr="") as p: self.assertRaises(Warning, test_percentage, p.name) class TestUsability(unittest.TestCase): def test_ok(self): # what lt's Plural-Forms is supposed to look like poobj = polib.POFile() poobj.metadata["Plural-Forms"] = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2)\n" with pofile(poobj) as p: test_usability(p.name) def test_busted_plural_forms(self): # https://bugzilla.redhat.com/show_bug.cgi?id=1283599 poobj = polib.POFile() poobj.metadata["Plural-Forms"] = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 or n%100>=20) ? 1 : 2)\n" with pofile(poobj) as p: self.assertRaises(Exception, test_usability, p.name) class TestMsgFmt(unittest.TestCase): def test_ok(self): with pofile_from_entry(msgid="test string", msgstr="estay ingstray") as p: test_msgfmt(p.name) # Test a few cases that msgfmt will catch def test_busted_newlines(self): with pofile_from_entry(msgid="multi\nline\nstring", msgstr="ultimay\ninelay\ningstray\n") as p: self.assertRaises(AssertionError, test_msgfmt, p.name) def test_busted_format(self): with pofile_from_entry(msgid="test %(type)s", msgstr="estay", flags=["python-format"]) as p: self.assertRaises(AssertionError, test_msgfmt, p.name) def test_translated_format(self): with pofile_from_entry(msgid="test %(type)s", msgstr="estay %(ypetay)", flags=["python-format"]) as p: self.assertRaises(AssertionError, test_msgfmt, p.name) # Test the top-level functions # fake tests for testing with def _true_test(_p): pass def _false_test(_p): raise AssertionError("no good") def _picky_test(p): if os.path.basename(p).startswith("p"): raise AssertionError("I don't like this one") class TestTestFile(unittest.TestCase): @unittest.mock.patch("translation_canary.translated._tests", [_true_test]) def test_success(self): with pofile_from_entry() as p: self.assertTrue(testFile(p.name)) @unittest.mock.patch("translation_canary.translated._tests", [_false_test]) def test_failure(self): with pofile_from_entry() as p: self.assertFalse(testFile(p.name)) @unittest.mock.patch("translation_canary.translated._tests", [_true_test]) def test_release_mode_success(self): with pofile_from_entry() as p: self.assertTrue(testFile(p.name, releaseMode=True)) self.assertTrue(os.path.exists(p.name)) @unittest.mock.patch("translation_canary.translated._tests", [_false_test]) def test_release_mode_failure(self): p = tempfile.NamedTemporaryFile(suffix='.po', delete=False) try: # testFile should return True but delete the file self.assertTrue(testFile(p.name, releaseMode=True)) self.assertFalse(os.path.exists(p.name)) finally: try: p.close() os.unlink(p.name) except FileNotFoundError: pass @unittest.mock.patch("translation_canary.translated._tests", [_false_test]) def test_release_mode_failure_with_lingua(self): with tempfile.TemporaryDirectory() as d: open(os.path.join(d, "test.po"), "w").close() with open(os.path.join(d, "LINGUAS"), "w") as linguas: linguas.write("test other\n") # Check that test.po is removed and test is removed from LINGUAS self.assertTrue(testFile(os.path.join(d, "test.po"), releaseMode=True)) self.assertFalse(os.path.exists(os.path.join(d, "test.po"))) with open(os.path.join(d, "LINGUAS"), "r") as linguas: self.assertEqual(linguas.read().strip(), "other") @unittest.mock.patch("translation_canary.translated._tests", [_false_test]) def test_release_mode_failure_with_lingua_no_modify(self): with tempfile.TemporaryDirectory() as d: open(os.path.join(d, "test.po"), "w").close() with open(os.path.join(d, "LINGUAS"), "w") as linguas: linguas.write("test other\n") # Check that test.po is removed and test is *not* removed from LINGUAS self.assertTrue(testFile(os.path.join(d, "test.po"), releaseMode=True, modifyLinguas=False)) self.assertFalse(os.path.exists(os.path.join(d, "test.po"))) with open(os.path.join(d, "LINGUAS"), "r") as linguas: self.assertEqual(linguas.read().strip(), "test other") @unittest.mock.patch("translation_canary.translated._tests", [_picky_test]) class TestTestSourceTree(unittest.TestCase): def setUp(self): self.tmpobj = tempfile.TemporaryDirectory() self.tmpdir = self.tmpobj.name def tearDown(self): self.tmpobj.cleanup() def test_success(self): open(os.path.join(self.tmpdir, "aa.po"), "w").close() open(os.path.join(self.tmpdir, "ab.po"), "w").close() self.assertTrue(testSourceTree(self.tmpdir)) def test_some_failure(self): open(os.path.join(self.tmpdir, "aa.po"), "w").close() open(os.path.join(self.tmpdir, "pa.po"), "w").close() self.assertFalse(testSourceTree(self.tmpdir)) def test_all_failure(self): open(os.path.join(self.tmpdir, "pa.po"), "w").close() open(os.path.join(self.tmpdir, "pb.po"), "w").close() self.assertFalse(testSourceTree(self.tmpdir)) def test_release_mode_success(self): open(os.path.join(self.tmpdir, "aa.po"), "w").close() open(os.path.join(self.tmpdir, "ab.po"), "w").close() self.assertTrue(testSourceTree(self.tmpdir, releaseMode=True)) def test_release_mode_failure(self): open(os.path.join(self.tmpdir, "aa.po"), "w").close() open(os.path.join(self.tmpdir, "pa.po"), "w").close() self.assertTrue(testSourceTree(self.tmpdir, releaseMode=True)) self.assertTrue(os.path.exists(os.path.join(self.tmpdir, "aa.po"))) self.assertFalse(os.path.exists(os.path.join(self.tmpdir, "pa.po"))) def test_release_mode_failure_with_lingua(self): open(os.path.join(self.tmpdir, "aa.po"), "w").close() open(os.path.join(self.tmpdir, "pa.po"), "w").close() with open(os.path.join(self.tmpdir, "LINGUAS"), "w") as l: l.write("aa pa\n") self.assertTrue(testSourceTree(self.tmpdir, releaseMode=True)) self.assertTrue(os.path.exists(os.path.join(self.tmpdir, "aa.po"))) self.assertFalse(os.path.exists(os.path.join(self.tmpdir, "pa.po"))) with open(os.path.join(self.tmpdir, "LINGUAS")) as l: self.assertEqual(l.read().strip(), "aa") def test_release_mode_failure_with_lingua_no_modify(self): open(os.path.join(self.tmpdir, "aa.po"), "w").close() open(os.path.join(self.tmpdir, "pa.po"), "w").close() with open(os.path.join(self.tmpdir, "LINGUAS"), "w") as l: l.write("aa pa\n") self.assertTrue(testSourceTree(self.tmpdir, releaseMode=True, modifyLinguas=False)) self.assertTrue(os.path.exists(os.path.join(self.tmpdir, "aa.po"))) self.assertFalse(os.path.exists(os.path.join(self.tmpdir, "pa.po"))) with open(os.path.join(self.tmpdir, "LINGUAS")) as l: self.assertEqual(l.read().strip(), "aa pa") libbytesize-2.2/translation-canary/translation_canary/000077500000000000000000000000001361502636100234115ustar00rootroot00000000000000libbytesize-2.2/translation-canary/translation_canary/__init__.py000066400000000000000000000000001361502636100255100ustar00rootroot00000000000000libbytesize-2.2/translation-canary/translation_canary/translatable/000077500000000000000000000000001361502636100260655ustar00rootroot00000000000000libbytesize-2.2/translation-canary/translation_canary/translatable/__init__.py000066400000000000000000000055551361502636100302100ustar00rootroot00000000000000# Framework for testing translatable strings # # Copyright (C) 2015 Red Hat, Inc. # # This copyrighted material is made available to anyone wishing to use, # modify, copy, or redistribute it subject to the terms and conditions of # the GNU Lesser General Public License v.2, or (at your option) any later # version. This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY expressed or implied, including the implied # warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See # the GNU Lesser General Public License for more details. You should have # received a copy of the GNU Lesser General Public License along with this # program; if not, write to the Free Software Foundation, Inc., 51 Franklin # Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat trademarks # that are incorporated in the source code or documentation are not subject # to the GNU Lesser General Public License and may only be used or # replicated with the express permission of Red Hat, Inc. # # Red Hat Author(s): David Shea """ Framework for running tests against translatable strings. Tests are loaded from modules in this directory. A test is any callable object within the module with a name that starts with 'test_'. Each test is called with a POEntry object as an argument. A test passes if it returns without raising an exception. """ try: import polib except ImportError: print("You need to install the python-polib package to read translations") raise # Gather tests from this directory import pkgutil _tests = [] for finder, mod_name, _ispkg in pkgutil.iter_modules(__path__): # Skip __main__ if mod_name == "__main__": continue # Load the module module = finder.find_module(mod_name).load_module() # Look for attributes that start with 'test_' and add them to the test list for attrname, attr in module.__dict__.items(): if attrname.startswith('test_') and callable(attr): _tests.append(attr) def testString(poentry): """Run all tests against the given translatable string. :param polib.POEntry poentry: The PO file entry to test :returns: whether the tests succeeded or not :rtype: bool """ success = True for test in _tests: try: test(poentry) except Exception as e: # pylint: disable=broad-except success = False print("%s failed on %s: %s" % (test.__name__, poentry.msgid, str(e))) return success def testPOT(potfile): """Run all tests against all entries in a POT file. :param str potfile: The name of a .pot file to test :return: whether the checks succeeded or not :rtype: bool """ success = True parsed_pot = polib.pofile(potfile) for entry in parsed_pot: if not testString(entry): success = False return success libbytesize-2.2/translation-canary/translation_canary/translatable/__main__.py000066400000000000000000000024321361502636100301600ustar00rootroot00000000000000# Entry point for testing translatable strings # # Copyright (C) 2015 Red Hat, Inc. # # This copyrighted material is made available to anyone wishing to use, # modify, copy, or redistribute it subject to the terms and conditions of # the GNU Lesser General Public License v.2, or (at your option) any later # version. This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY expressed or implied, including the implied # warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See # the GNU Lesser General Public License for more details. You should have # received a copy of the GNU Lesser General Public License along with this # program; if not, write to the Free Software Foundation, Inc., 51 Franklin # Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat trademarks # that are incorporated in the source code or documentation are not subject # to the GNU Lesser General Public License and may only be used or # replicated with the express permission of Red Hat, Inc. # # Red Hat Author(s): David Shea import sys from . import testPOT if len(sys.argv) < 2: print("Usage: translatable ") sys.exit(1) status = 0 for potfile in sys.argv[1:]: if not testPOT(potfile): status = 1 sys.exit(status) libbytesize-2.2/translation-canary/translation_canary/translatable/test_comment.py000066400000000000000000000026201361502636100311400ustar00rootroot00000000000000# Check that a string that needs a comment has one # # Copyright (C) 2015 Red Hat, Inc. # # This copyrighted material is made available to anyone wishing to use, # modify, copy, or redistribute it subject to the terms and conditions of # the GNU Lesser General Public License v.2, or (at your option) any later # version. This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY expressed or implied, including the implied # warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See # the GNU Lesser General Public License for more details. You should have # received a copy of the GNU Lesser General Public License along with this # program; if not, write to the Free Software Foundation, Inc., 51 Franklin # Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat trademarks # that are incorporated in the source code or documentation are not subject # to the GNU Lesser General Public License and may only be used or # replicated with the express permission of Red Hat, Inc. # # Red Hat Author(s): David Shea def test_comment(poentry): # Single-character translatable strings (e.g., the 'c' of press c to # continue) need some additional context in order to make sense. Make # sure that they have it. if len(poentry.msgid) == 1 and not poentry.comment: raise AssertionError("Single-character string missing a comment.") libbytesize-2.2/translation-canary/translation_canary/translatable/test_markup.py000066400000000000000000000034311361502636100307760ustar00rootroot00000000000000# Check that a string does not contain unnecessary Pango markup # # Copyright (C) 2015 Red Hat, Inc. # # This copyrighted material is made available to anyone wishing to use, # modify, copy, or redistribute it subject to the terms and conditions of # the GNU Lesser General Public License v.2, or (at your option) any later # version. This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY expressed or implied, including the implied # warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See # the GNU Lesser General Public License for more details. You should have # received a copy of the GNU Lesser General Public License along with this # program; if not, write to the Free Software Foundation, Inc., 51 Franklin # Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat trademarks # that are incorporated in the source code or documentation are not subject # to the GNU Lesser General Public License and may only be used or # replicated with the express permission of Red Hat, Inc. # # Red Hat Author(s): David Shea from pocketlint.pangocheck import is_markup, markup_necessary import xml.etree.ElementTree as ET def test_markup(poentry): # Unnecessary markup is markup applied to an entire string, such as # _("Bold Text"). This could be instead be translated as # "%s" % _("Bold Text"), and then the translator doesn't have to see # the markup at all. if is_markup(poentry.msgid): # Wrap the string in nodes, parse it, test it # The markup is unescaped on purpose # pylint: disable=unescaped-markup tree = ET.fromstring("%s" % poentry.msgid) if not markup_necessary(tree): raise AssertionError("Unnecessary markup") libbytesize-2.2/translation-canary/translation_canary/translated/000077500000000000000000000000001361502636100255525ustar00rootroot00000000000000libbytesize-2.2/translation-canary/translation_canary/translated/__init__.py000066400000000000000000000140001361502636100276560ustar00rootroot00000000000000# Framework for testing translations # # Copyright (C) 2015 Red Hat, Inc. # # This copyrighted material is made available to anyone wishing to use, # modify, copy, or redistribute it subject to the terms and conditions of # the GNU Lesser General Public License v.2, or (at your option) any later # version. This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY expressed or implied, including the implied # warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See # the GNU Lesser General Public License for more details. You should have # received a copy of the GNU Lesser General Public License along with this # program; if not, write to the Free Software Foundation, Inc., 51 Franklin # Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat trademarks # that are incorporated in the source code or documentation are not subject # to the GNU Lesser General Public License and may only be used or # replicated with the express permission of Red Hat, Inc. # # Red Hat Author(s): David Shea """ Framework for running tests against translations. Tests are loaded from modules in this directory. A test is any callable object within the module with a name that starts with 'test_'. Each test is called with the name of .po file to test as an argument. A test passes if it returns without raising an exception. """ import os, warnings _tests = [] # Gather tests from this directory import pkgutil for finder, mod_name, _ispkg in pkgutil.iter_modules(__path__): # Skip __main__ if mod_name == "__main__": continue # Load the module module = finder.find_module(mod_name).load_module(mod_name) # Look for attributes that start with 'test_' and add them to the test list for attrname, attr in module.__dict__.items(): if attrname.startswith('test_') and callable(attr): _tests.append(attr) def _remove_lingua(linguas, language): # Read in the LINGUAS file with open(linguas, "rt") as f: lingua_lines = f.readlines() output_lines = [] for line in lingua_lines: # Leave comments alone if line.startswith('#'): output_lines.append(line) continue # Split the line into a list of languages, remove the one we don't # want, and put it back together lingua_list = line.split() lingua_list.remove(language) output_lines.append(" ".join(lingua_list)) # Write LINGUAS back out with open(linguas, "wt") as f: f.writelines(output_lines) def testFile(pofile, prefix=None, releaseMode=False, modifyLinguas=True): """Run all registered tests against the given .mo file. If run in release mode, this function will always return true, and if the mofile does not pass the tests the langauge will be removed. :param str mofile: The .mo file name to check :param str prefix: An optional directory prefix to strip from error messages :param bool releaseMode: whether to run in release mode :param bool modifyLinguas: whether to remove translations from LINGUAS in release mode :return: whether the checks succeeded or not :rtype: bool """ success = True for test in _tests: # Don't print the tmpdir path in error messages if prefix is not None and pofile.startswith(prefix): poerror = pofile[len(prefix):] else: poerror = pofile try: with warnings.catch_warnings(record=True) as w: test(pofile) # Print any warnings collected for warn in w: print("%s warned on %s: %s" % (test.__name__, poerror, warn.message)) except Exception as e: # pylint: disable=broad-except print("%s failed on %s: %s" % (test.__name__, poerror, str(e))) if releaseMode: # Remove the po file and the .mo file built from it print("Removing %s" % pofile) os.remove(pofile) # Check for both .mo and .gmo mofile = os.path.splitext(pofile)[0] + '.mo' if os.path.exists(mofile): print("Removing %s" % mofile) os.remove(mofile) gmofile = os.path.splitext(pofile)[0] + '.gmo' if os.path.exists(gmofile): print("Removing %s" % gmofile) os.remove(gmofile) if modifyLinguas: # If there is a LINGUAS file in the po directory, remove the # language from it linguas = os.path.join(os.path.dirname(mofile), 'LINGUAS') if os.path.exists(linguas): language = os.path.splitext(os.path.basename(pofile))[0] print("Removing %s from LINGUAS" % language) _remove_lingua(linguas, language) # No need to run the rest of the tests since we just killed the file break else: success = False return success def testSourceTree(srcdir, releaseMode=False, modifyLinguas=True): """Runs all registered tests against all .po files in the given directory. If run in release mode, this function will always return True and the languages that do not pass the tests will be removed. :param str srcdir: The path to the source directory to check :param bool releaseMode: whether to run in release mode :param bool modifyLinguas: whether to remove translations from LINGUAS in release mode :return: whether the checks succeeded or not :rtype: bool """ success = True srcdir = os.path.normpath(srcdir) for dirpath, _dirnames, paths in os.walk(srcdir): for pofile in (os.path.join(dirpath, path) for path in paths if path.endswith('.po')): if not testFile(pofile, prefix=srcdir + "/", releaseMode=releaseMode, modifyLinguas=modifyLinguas): success = False return success libbytesize-2.2/translation-canary/translation_canary/translated/__main__.py000066400000000000000000000035021361502636100276440ustar00rootroot00000000000000# Entry point for testing translations # # Copyright (C) 2015 Red Hat, Inc. # # This copyrighted material is made available to anyone wishing to use, # modify, copy, or redistribute it subject to the terms and conditions of # the GNU Lesser General Public License v.2, or (at your option) any later # version. This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY expressed or implied, including the implied # warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See # the GNU Lesser General Public License for more details. You should have # received a copy of the GNU Lesser General Public License along with this # program; if not, write to the Free Software Foundation, Inc., 51 Franklin # Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat trademarks # that are incorporated in the source code or documentation are not subject # to the GNU Lesser General Public License and may only be used or # replicated with the express permission of Red Hat, Inc. # # Red Hat Author(s): David Shea import sys, argparse from . import testSourceTree ap = argparse.ArgumentParser(description='Validate translated strings') ap.add_argument('--release', action='store_true', default=False, help='Run in release mode') ap.add_argument('--test', dest='release', action='store_false', help='Run in test mode') ap.add_argument('--no-modify-linguas', dest='modify_linguas', action='store_false', default=True, help='In release mode, do not remove failing translation from LINGUAS') ap.add_argument('source_trees', metavar='SOURCE-TREE', nargs='+', help='Source directory to test') args = ap.parse_args() status = 0 for srcdir in args.source_trees: if not testSourceTree(srcdir, args.release, args.modify_linguas): status = 1 sys.exit(status) libbytesize-2.2/translation-canary/translation_canary/translated/test_markup.py000066400000000000000000000056121361502636100304660ustar00rootroot00000000000000# Check translations of pango markup # # This will look for translatable strings that appear to contain markup and # check that the markup in the translation matches. # # Copyright (C) 2015 Red Hat, Inc. # # This copyrighted material is made available to anyone wishing to use, # modify, copy, or redistribute it subject to the terms and conditions of # the GNU Lesser General Public License v.2, or (at your option) any later # version. This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY expressed or implied, including the implied # warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See # the GNU Lesser General Public License for more details. You should have # received a copy of the GNU Lesser General Public License along with this # program; if not, write to the Free Software Foundation, Inc., 51 Franklin # Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat trademarks # that are incorporated in the source code or documentation are not subject # to the GNU Lesser General Public License and may only be used or # replicated with the express permission of Red Hat, Inc. # # Red Hat Author(s): David Shea try: import polib except ImportError: print("You need to install the python-polib package to read translations") raise from pocketlint.pangocheck import is_markup, markup_match import xml.etree.ElementTree as ET def test_markup(pofile): po = polib.pofile(pofile) for entry in po.translated_entries(): if is_markup(entry.msgid): # If this is a plural, check each of the plural translations if entry.msgid_plural: xlations = entry.msgstr_plural else: xlations = {None: entry.msgstr} for plural_id, msgstr in xlations.items(): # Check if the markup is valid at all try: # pylint: disable=unescaped-markup ET.fromstring('%s' % msgstr) except ET.ParseError: if entry.msgid_plural: raise AssertionError("Invalid markup translation for %d translation of msgid %s\n%s" % (plural_id, entry.msgid, msgstr)) else: raise AssertionError("Invalid markup translation for msgid %s\n%s" % (entry.msgid, msgstr)) # Check if the markup has the same number and kind of tags if not markup_match(entry.msgid, msgstr): if entry.msgid_plural: raise AssertionError("Markup does not match for %d translation of msgid %s\n%s" % (plural_id, entry.msgid, msgstr)) else: raise AssertionError("Markup does not match for msgid %s\n%s" % (entry.msgid, msgstr)) libbytesize-2.2/translation-canary/translation_canary/translated/test_percentage.py000066400000000000000000000032461361502636100313050ustar00rootroot00000000000000# Check what percentage of strings a .po translates # # This will reject translations that fall below a certain threshold of # translated strings. # # Copyright (C) 2015 Red Hat, Inc. # # This copyrighted material is made available to anyone wishing to use, # modify, copy, or redistribute it subject to the terms and conditions of # the GNU Lesser General Public License v.2, or (at your option) any later # version. This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY expressed or implied, including the implied # warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See # the GNU Lesser General Public License for more details. You should have # received a copy of the GNU Lesser General Public License along with this # program; if not, write to the Free Software Foundation, Inc., 51 Franklin # Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat trademarks # that are incorporated in the source code or documentation are not subject # to the GNU Lesser General Public License and may only be used or # replicated with the express permission of Red Hat, Inc. # # Red Hat Author(s): David Shea import warnings try: import polib except ImportError: print("You need to install the python-polib package to read translations") raise threshold = 10 def test_percentage(pofile): pofile = polib.pofile(pofile) if pofile.percent_translated() < threshold: # Issue a warning instead of an exception, since these should probably # be handled on a case-by-case basis warnings.warn("amount translated of %d%% below threshold of %d%%" % (pofile.percent_translated(), threshold)) libbytesize-2.2/translation-canary/translation_canary/translated/test_usability.py000066400000000000000000000037641361502636100312020ustar00rootroot00000000000000# Check a .po file for basic usability # # This will test that the file is well-formed and that the Plural-Forms value # is parseable # # Copyright (C) 2015 Red Hat, Inc. # # This copyrighted material is made available to anyone wishing to use, # modify, copy, or redistribute it subject to the terms and conditions of # the GNU Lesser General Public License v.2, or (at your option) any later # version. This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY expressed or implied, including the implied # warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See # the GNU Lesser General Public License for more details. You should have # received a copy of the GNU Lesser General Public License along with this # program; if not, write to the Free Software Foundation, Inc., 51 Franklin # Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat trademarks # that are incorporated in the source code or documentation are not subject # to the GNU Lesser General Public License and may only be used or # replicated with the express permission of Red Hat, Inc. # # Red Hat Author(s): David Shea import gettext import tempfile import polib import subprocess def test_usability(pofile): # Use polib to write a mofile with tempfile.NamedTemporaryFile(mode="w+b") as mofile: pofile = polib.pofile(pofile) pofile.save_as_mofile(mofile.name) # Try to open it _t = gettext.GNUTranslations(fp=mofile) def test_msgfmt(pofile): # Check that the .po file can actually be compiled with tempfile.NamedTemporaryFile(mode="w+b", suffix=".mo") as mofile: try: # Ignore the output on success subprocess.check_output(["msgfmt", "-c", "--verbose", "-o", mofile.name, pofile], stderr=subprocess.STDOUT, universal_newlines=True) except subprocess.CalledProcessError as e: raise AssertionError("Unable to compile %s: %s" % (pofile, e.output)) libbytesize-2.2/translation-canary/xgettext_werror.sh000077500000000000000000000040071361502636100233320ustar00rootroot00000000000000#!/bin/sh -e # # xgettext_werror.sh: Run xgettext and actually do something with the warnings # # xgettext prints out warnings for certain problems in translatable strings, # such as format strings that cannot be translated due to position-based # parameters. These warnings generally indicate something that needs to be # addressed before the strings can be submitted for translation. This script # exits with a status of 1 so that the warnings are not ignored as they scroll # by in pages of build output. # # This script should be used in place of xgettext when rebuilding the .pot file, # e.g. by setting XGETTEXT in po/Makevars. # # Copyright (C) 2015 Red Hat, Inc. # # This copyrighted material is made available to anyone wishing to use, # modify, copy, or redistribute it subject to the terms and conditions of # the GNU Lesser General Public License v.2, or (at your option) any later # version. This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY expressed or implied, including the implied # warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See # the GNU Lesser General Public License for more details. You should have # received a copy of the GNU Lesser General Public License along with this # program; if not, write to the Free Software Foundation, Inc., 51 Franklin # Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat trademarks # that are incorporated in the source code or documentation are not subject # to the GNU Lesser General Public License and may only be used or # replicated with the express permission of Red Hat, Inc. # # Red Hat Author(s): David Shea returncode=0 # Collect the output from xgettext. If xgettext fails, treat that as a failure # Make sure that "warning:" doesn't get translated xgettext_output="$(LC_MESSAGES=C xgettext "$@" 2>&1)" || returncode=$? # Look for warnings if echo "$xgettext_output" | fgrep -q "warning: "; then returncode=1 fi # Print the output and return echo "$xgettext_output" exit $returncode libbytesize-2.2/zanata.xml000066400000000000000000000004241361502636100157050ustar00rootroot00000000000000 https://fedora.zanata.org/ libbytesize master gettext