code:
import unittest
from inary.configfile import ConfigurationFile

class ConfigFileTestCase(unittest.TestCase):

    def setUp(self):
        self.cf = ConfigurationFile('inary.conf')

    def testGeneralDefaults(self):
        cf = self.cf
        self.assertEqual(cf.general.destinationDirectory, cf.general['destinationDirectory'])
        assert not cf.general.autoclean
        self.assertEqual(cf.general.http_proxy, cf.general['http_proxy'])
        assert not cf.general.package_cache

    def testBuildDefaults(self):
        cf = self.cf
        self.assertEqual(cf.build.jobs, cf.build['jobs'])
        assert cf.build.defaults.generateDebug
        assert not cf.build.defaults.enableSandbox
        self.assertEqual(cf.build.compressionlevel, cf.build['compressionlevel'])
        self.assertEqual(cf.build.fallback, cf.build['fallback'])

    def testDirectoriesDefaults(self):
        cf = self.cf
        self.assertEqual(cf.dirs.lib_dir, cf.dirs['lib_dir'])
        self.assertEqual(cf.dirs.index_dir, cf.dirs['index_dir'])

    def testConfigurationSection(self):
        cf = self.cf
        if not cf.general:
            self.fail()
        if not cf.build:
            self.fail()
        if not cf.dirs:
            self.fail()

    def testInaryConfValues(self):
        cf = self.cf
        self.assertEqual(cf.dirs.kde_dir, '/usr/kde/5')
        self.assertEqual(cf.dirs.compiled_packages_dir, '/var/cache/inary/packages')
        self.assertEqual(cf.general.architecture, 'x86_64')
        self.assertEqual(cf.general.distribution_release, '2019')

    def testValuesExists(self):
        cf = self.cf
        assert cf.general.distribution
        assert not cf.general.targetDirectory
        assert cf.build.cxxflags
        assert not cf.build.configurationlevel
        assert cf.dirs.qt_dir
        assert not cf.dirs.cache_dir

repo_name: SulinOS/inary

license: mit


code:
import unittest
import inary.constants
import inary.context as ctx

class ConstantTestCase(unittest.TestCase):

    def testConstants(self):
        constants = ctx.const
        constDict = {"actions": "actions.py", "setup":"setup","metadata":"metadata.xml"}

        for i in list(constDict.keys()):
            if hasattr(constants,i):
                value = getattr(constants,i)
                self.assertEqual(value, constDict[i])


code:
import unittest

from inary.mirrors import Mirrors

class MirrorsTestCase(unittest.TestCase):
    def testGetMirrors(self):
        with open("tests/mirrors.conf","w") as mirror:
            mirror.write(
"""apache http://www.eu.apache.org/dist/
apache http://www.apache.org/dist/
apache http://apache.planetmirror.com.au/dist/
apache http://gd.tuwien.ac.at/infosys/servers/http/apache/dist/
apache http://apache.fastorama.com/dist/
apache http://mir2.ovh.net/ftp.apache.org/dist/
cpan http://www.perl.com/CPAN/
cpan http://mirrors.jtlnet.com/CPAN/
cpan ftp://ftp.ncsu.edu/pub/mirror/CPAN/
cpan ftp://ftp.duke.edu/pub/perl/
gnu http://ftp.gnu.org/gnu/""")
            mirror.flush()
            mirror.close()
        mirrors = Mirrors("tests/mirrors.conf")
        assert "http://www.eu.apache.org/dist/" in mirrors.get_mirrors("apache")
        assert ['http://www.perl.com/CPAN/', 'http://mirrors.jtlnet.com/CPAN/',
                'ftp://ftp.ncsu.edu/pub/mirror/CPAN/','ftp://ftp.duke.edu/pub/perl/'] == mirrors.get_mirrors("cpan")
        assert ["http://ftp.gnu.org/gnu/"] == mirrors.get_mirrors("gnu")


code:
import unittest
import inary
import inary.actionsapi
import os
import shutil

class ShellTestCase(unittest.TestCase):
    def setUp(self):
        from inary.actionsapi.variables import initVariables
        unittest.TestCase.setUp(self)
        initVariables()
        return

    def testCanAccessFile(self):
        from inary.actionsapi.shelltools import can_access_file
        self.assertTrue(can_access_file(__file__))
        self.assertFalse(can_access_file('actionsapi/set.py'))

    def testCanAccessDirectory(self):
        from inary.actionsapi.shelltools import can_access_directory
        self.assertTrue(can_access_directory('tests/'))
        self.assertFalse(can_access_directory('tests/mirrors.conf'))

    def testMakedirs(self):
        from inary.actionsapi.shelltools import makedirs

        makedirs('tests/testdirectory/aDirectory')
        self.assertEqual(os.path.exists('tests/testdirectory/aDirectory'),True)
        shutil.rmtree('tests/testdirectory')

    def testEcho(self):
        from inary.actionsapi.shelltools import echo

        echo('tests/echo-file','eco subject')
        self.assertEqual(os.path.exists('tests/echo-file'),True)
        self.assertEqual(open('tests/echo-file').readlines()[0].strip(), 'eco subject')
        echo('tests/echo-file', 'subject eco')
        self.assertEqual(open('tests/echo-file').readlines()[1].strip(), 'subject eco')
        os.remove('tests/echo-file')

    def testSym(self):
        from inary.actionsapi.shelltools import sym

        sym('../../scenarios/repo','tests/repos')
        self.assertEqual(os.path.islink('tools'),False)
        self.assertEqual(os.path.islink('tests/repos'),True)

    def testUnlinkDir(self):
        from inary.actionsapi.shelltools import makedirs
        from inary.actionsapi.shelltools import sym
        from inary.actionsapi.shelltools import unlinkDir

        makedirs('tests/testdirectory/sample')
        sym('testdirectory/sample', 'tests/history')
        self.assertEqual(os.path.islink('tests/history'), True)
        unlinkDir('tests/testdirectory/sample')
        self.assertEqual(os.path.islink('tests/testdirectory/sample'), False)

    def testCopy(self):
        from inary.actionsapi.shelltools import echo
        from inary.actionsapi.shelltools import copy
        from inary.actionsapi.shelltools import makedirs

        makedirs('tests/testdirectory/sample')
        copy('tests', 'tests-copy')
        self.assertEqual(os.path.islink('tests-copy'), False)
        shutil.rmtree("tests-copy")

        echo('tests/echo-file', 'subject eco')
        copy('tests/echo-file', 'tests/echo-file-copy')
        self.assertEqual(os.path.islink('tests/echo-file-copy'), False)
        os.remove("tests/echo-file")

    def testIsLink(self):
        from inary.actionsapi.shelltools import sym
        from inary.actionsapi.shelltools import isLink

        sym('../database', 'tests/history')
        assert isLink('tests/history')
        assert not isLink('tests/runtests.py')

    def testIsFile(self):
        from inary.actionsapi.shelltools import isFile

        assert isFile('/bin/bash')
        assert not isFile('/tests/database')

    def testIsDirectory(self):
        from inary.actionsapi.shelltools import isDirectory

        assert not isDirectory('doc/dependency.pdf')
        assert isDirectory('/usr/lib')
        assert isDirectory('/etc/inary')
        assert not isDirectory('tests/shelltest.py')

    def testRealPath(self):
        from inary.actionsapi.shelltools import realPath

        assert realPath('doc/dependency.pdf')
        assert realPath('tests/database/sourcedbtest.py')

    def testBaseName(self):
        from inary.actionsapi.shelltools import baseName

        assert 'dependency.pdf' == baseName('doc/dependency.pdf')
        assert 'Arphic' == baseName('licenses/Arphic')
        assert not 'Atmel' == baseName('tools/atmel.py')

    def testSystem(self):
        from inary.actionsapi.shelltools import system

        self.assertEqual(os.path.exists('tests/systemtest'),False)
        system('touch tests/systemtest')
        self.assertEqual(os.path.exists('tests/systemtest'),True)
        os.remove('tests/systemtest')


code:
import unittest
import os
from inary import uri
from inary.file import File
from inary.data.specfile import SpecFile

class UriTestCase(unittest.TestCase):

    def setUp(self):
        unittest.TestCase.setUp(self)

    def testSetUri(self):
        self.url = uri.URI()
        self.url.set_uri('uri')
        assert 'uri' ==  self.url.get_uri()
        self.url.set_uri('urix')
        assert 'urix' == self.url.get_uri()

    def testIsLocalFile(self):
        uri1 = uri.URI()
        assert not uri1.is_local_file()
        uri1.set_uri('/usr/local')
        assert uri1.is_local_file()

    def testIsRemoteFile(self):
        uri2 = uri.URI()
        assert uri2.is_remote_file()
        uri2.set_uri('uri')
        assert not uri2.is_remote_file()

    def testSchemePath(self):
        uri3 = uri.URI()
        uri3.set_uri('/usr/bin')
        self.assertEqual('file', uri3.scheme())
        assert '/usr/bin' == uri3.path()

    def testFileName(self):
        uri4 = uri.URI()
        uri4.set_uri('/usr/share/aclocal')
        assert 'aclocal' ==  uri4.filename()


code:
import unittest
import shutil
from inary.util import *
import os

class UtilTestCase(unittest.TestCase):

    def initialize(self):
        testcase.testCase.initialize(self, database=False)

    #process related functions
    def testRunBatch(self):
        self.assertEqual((0, '', b''), run_batch('cd'))
        self.assertEqual((127, '', b'/bin/sh: add: command not found\n'), run_batch('add'))

    def testRunLogged(self):
        assert 0 == run_logged('ls')
        assert 1 == run_logged('rm')

    def testXtermTitle(self):
        xterm_title('sulin')
        xterm_title_reset()

    #path processing functions tests
    def testSplitPath(self):
        assert ['usr', 'local', 'src'] == splitpath('usr/local/src')
        assert ['usr', 'lib', 'sulin'] == splitpath('usr/lib/sulin')

    def testSubPath(self):
        self.assertTrue(subpath('usr','usr'))
        self.assertTrue(subpath('usr','usr/local/src'))
        self.assertTrue(not subpath('usr/local','usr'))

    def testRemovePathPrefix(self):
        pathname = removepathprefix('usr/local', 'usr/local/src')
        assert 'src' == pathname

        pathname = removepathprefix('usr/local','usr/local/bin')
        assert not 'bim' == pathname

    def testJoinPath(self):
        assert 'usr/local/src' == join_path('usr/local','src')
        assert not 'usr/lib/hal' == join_path('usr','hal')
        assert 'usr/sbin/lpc' == join_path('usr','sbin/lpc')

    #file/directory related functions tests
    def testCheckFile(self):
        assert check_file('/usr/bin/bash')
        try:
            check_file('/usr/bin/aatests')
        except:
            assert True

    def testCleanDir(self):
        assert None == clean_dir('usr/lib')
        assert None == clean_dir('usr/local')
        assert not 'tmp/inary-root' == clean_dir('usr/tmp')

    def testDirSize(self):
        self.assertNotEqual(dir_size('usr/lib/sulin'),2940)
        self.assertNotEqual(dir_size('usr/lib'),65)

    def testCopyFile(self):
        copy_file('/etc/inary/inary.conf', '/tmp/inary-test1')
        copy_file('/etc/inary/sandbox.conf', '/tmp/inary-test2')
        copy_file_stat('/etc/inary/inary.conf', '/tmp/inary-test1')


code:
import unittest

from inary.version import Version

class VersionTestCase(unittest.TestCase):
    def setUp(self):
        pass

    def testSingle(self):
        v1 = Version("103")
        v2 = Version("90")
        self.assertTrue(v1 > v2)

    def testOpsNumerical(self):
        v1 = Version("0.3.1")
        v2 = Version("0.3.5")
        v3 = Version("1.5.2")
        v4 = Version("0.3.1")
        v5 = Version("2.07")
        self.assertTrue(v1 < v2)
        self.assertTrue(v3 > v2)
        self.assertTrue(v1 <= v3)
        self.assertTrue(v4 >= v4)
        self.assertTrue(v5 > v3)

    def testOpsKeywords(self):
        # with keywords
        v1 = Version("2.23_pre10")
        v2 = Version("2.23")
        v3 = Version("2.21")
        v4 = Version("2.23_p1")
        v5 = Version("2.23_beta1")
        v6 = Version("2.23_m1")
        v7 = Version("2.23_rc1")
        v8 = Version("2.23_rc2")
        self.assertTrue(v1 < v2)
        self.assertTrue(v1 > v3)
        self.assertTrue(v1 < v4)
        self.assertTrue(v1 > v5)
        self.assertTrue(v2 < v4)
        self.assertTrue(v2 > v5)
        self.assertTrue(v6 < v4)
        self.assertTrue(v6 > v5)
        self.assertTrue(v7 > v5)
        self.assertTrue(v8 > v7)

        v1 = Version("1.0_alpha1")
        v2 = Version("1.0_alpha2")
        self.assertTrue(v2 > v1)

    def testOpsCharacters(self):
        # with character
        v1 = Version("2.10_alpha1")
        v2 = Version("2.10")
        v3 = Version("2.10_alpha2")
        self.assertTrue(v1 < v2)
        self.assertTrue(v1 < v3)
        self.assertTrue(v2 > v3)

    def testGeBug(self):
        # bug 603
        v1 = Version('1.8.0')
        v2 = Version('1.9.1')
        self.assertTrue( not v1 > v2 )
        self.assertTrue( not v1 >= v2 )


code:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import argparse
import sys
import time
import shutil

import unittest
from unittest import _TextTestResult

import inary
import inary.context as ctx
import inary.util as util
import os

def importTest(name):
    mod = __import__(name)
    components = name.split('.')
    for comp in components[1:]:
        mod = getattr(mod, comp)
    return mod

def getTests(path, base_path, files=''):
    if not files:
        files = os.listdir(path)
        files = [f[:-3] for f in files if f.startswith("test") and f.endswith(".py")]
        files.sort()
    parent_path = path[len(base_path)+1:]
    parent_module = parent_path.replace('/', '.')
    result = []
    for mymodule in files:
        modname = ".".join((parent_module, mymodule))
        mod = importTest(modname)
        result.append(unittest.TestLoader().loadTestsFromModule(mod))
    return result

class TextTestResult(_TextTestResult):
    def __init__(self, stream, descriptions, verbosity):
        super(TextTestResult, self).__init__(stream, descriptions, verbosity)
        self.todoed = []

    def addTodo(self, test, info):
        self.todoed.append((test, info))
        if self.showAll:
            self.stream.writeln("TODO")
        elif self.dots:
            self.stream.write(".")

    def printErrors(self):
        if self.dots or self.showAll:
            self.stream.writeln()
            self.printErrorList(util.colorize('ERROR','red'), self.errors)
            self.printErrorList(util.colorize('FAIL', 'blue'), self.failures)
            self.printErrorList(util.colorize('TODO', 'purple'),self.todoed)

class InaryTestRunner(unittest.TextTestRunner):

    def Result(self):
        return TextTestResult(self.stream, self.descriptions, self.verbosity)

    def run(self, Test, retresult=True):
        """
        Run the given test case or test suite.
        """
        result = self.Result()
        startTime = time.time()
        Test(result)
        stopTime = time.time()
        timeTaken = stopTime - startTime
        if retresult==True:
            result.printErrors()
        self.stream.writeln(result.separator2)
        run = result.testsRun
        self.stream.write(util.colorize("\n\n====== COMPLATE TESTS =======\n" ,'yellow'))
        self.stream.writeln(util.colorize("  * Runned %d test%s in %.3fs" %
                            (run, run != 1 and "s" or "", timeTaken),'blue'))
        self.stream.writeln()
        if not result.wasSuccessful():
            failed = len(result.failures)
            errored = len(result.errors)
            todoed = len(result.todoed)
            success = run - (failed + errored + todoed)
            self.stream.write(util.colorize("    => %d Successed\n" % success, 'green'))
            if failed:
                self.stream.write(util.colorize("\n    => %d Failures\n" % failed, 'red'))
            if errored:
                self.stream.write(util.colorize("\n    => %d Errored\n" % errored, 'red'))
            if todoed:
                self.stream.write(util.colorize("\n    => %d ToDo  |" % todoed, 'yellow'))
        else:
            self.stream.writeln("Tests End Succesfull...")
        return result

def main():
    suite = unittest.TestSuite()
    basedir = os.path.dirname(os.path.realpath(__file__))

    usage = "usage: %s [options] [tests to run]" % os.path.basename(sys.argv[0])
    parser = argparse.ArgumentParser(usage=usage)
    parser.add_argument("-v", "--verbose", action="store_true",
		        help="Print detailed log.", default="False",
                        dest="verbose_print")
    options, args = parser.parse_known_args(args=sys.argv)

    if len(args) > 1:
        result = []
        for arg in args:
            realpath = os.path.realpath(arg)
            path = os.path.dirname(realpath)
            f = realpath[len(path)+1:]

            if not f.startswith("test") or not f.endswith(".py"):
                raise Exception("Invalid argument: '%s'" % arg)

            mymodule = f[:-3]
            result.extend(getTests(path, basedir, [mymodule]))

        suite.addTests(result)
    else:
        testfile = '__test__.py'
        testDirs = []

        for root, dirs, files in os.walk(basedir):

            if testfile in files:
                testDirs.append(root)

        testDirs.sort()

        for mydir in testDirs:
            suite.addTests(getTests(os.path.join(basedir, mydir), basedir))

    verbosity=1
    if options.verbose_print==True:
            verbosity=2

    result = InaryTestRunner(verbosity=verbosity).run(suite, retresult=options.verbose_print)

def setup():
    options = inary.config.Options()
    options.destdir = 'tests/tmp_root'
    inary.api.set_options(options)
    inary.api.set_scom(False)

    ctx.config.values.general.distribution = "Sulin"
    ctx.config.values.general.distribution_release = "2018"

if __name__ == '__main__':
    if os.path.exists("tests/tmp_root"):
        shutil.rmtree("tests/tmp_root")
    setup()
    main()


code:
testGetComponent (databaseTests.testComponentDB.ComponentDBTestCase) ... ok
testGetPackages (databaseTests.testComponentDB.ComponentDBTestCase) ... ok
testGetSources (databaseTests.testComponentDB.ComponentDBTestCase) ... ok
testGetUnionComponent (databaseTests.testComponentDB.ComponentDBTestCase) ... ok
testGetUnionPackages (databaseTests.testComponentDB.ComponentDBTestCase) ... ok
testHasComponent (databaseTests.testComponentDB.ComponentDBTestCase) ... ok
testListComponents (databaseTests.testComponentDB.ComponentDBTestCase) ... ok
testSearchComponent (databaseTests.testComponentDB.ComponentDBTestCase) ... FAIL
testAddRemoveFiles (databaseTests.testFilesDB.FilesDBTestCase) ... ok
testGetFile (databaseTests.testFilesDB.FilesDBTestCase) ... ok
testHasFile (databaseTests.testFilesDB.FilesDBTestCase) ... ok
testSearchFile (databaseTests.testFilesDB.FilesDBTestCase) ... ok
testAddRemovePackage (databaseTests.testInstallDB.InstallDBTestCase) ... ok
testClearPending (databaseTests.testInstallDB.InstallDBTestCase) ... skipped ''
testGetFiles (databaseTests.testInstallDB.InstallDBTestCase) ... ok
testGetInfo (databaseTests.testInstallDB.InstallDBTestCase) ... ok
testGetPackage (databaseTests.testInstallDB.InstallDBTestCase) ... ok
testGetReverseDependencies (databaseTests.testInstallDB.InstallDBTestCase) ... FAIL
testGetVersion (databaseTests.testInstallDB.InstallDBTestCase) ... ok
testHasPackage (databaseTests.testInstallDB.InstallDBTestCase) ... ok
testListInstalled (databaseTests.testInstallDB.InstallDBTestCase) ... ok
testMarkListPending (databaseTests.testInstallDB.InstallDBTestCase) ... skipped ''
testSearchPackage (databaseTests.testInstallDB.InstallDBTestCase) ... ok
testGetItem (databaseTests.testItembyRepo.ItemByRepoTestCase) ... ok
testGetItemAndRepository (databaseTests.testItembyRepo.ItemByRepoTestCase) ... ok
testGetItemKeys (databaseTests.testItembyRepo.ItemByRepoTestCase) ... ok
testGetItemOfRepository (databaseTests.testItembyRepo.ItemByRepoTestCase) ... ok
testGetListItem (databaseTests.testItembyRepo.ItemByRepoTestCase) ... ok
testHasItem (databaseTests.testItembyRepo.ItemByRepoTestCase) ... ok
testHasRepository (databaseTests.testItembyRepo.ItemByRepoTestCase) ... ok
testItemRepos (databaseTests.testItembyRepo.ItemByRepoTestCase) ... ok
testWhichRepo (databaseTests.testItembyRepo.ItemByRepoTestCase) ... ERROR
testDatabaseMethodForcingInit (databaseTests.testLazyDB.LazyDBTestCase) ... ok
testDatabaseWithoutInit (databaseTests.testLazyDB.LazyDBTestCase) ... ok
testSingletonBehaviour (databaseTests.testLazyDB.LazyDBTestCase) ... ok
testGetObsoletes (databaseTests.testPackageDB.PackageDBTestCase) ... ok
testGetPackage (databaseTests.testPackageDB.PackageDBTestCase) ... ok
testGetPackageAndRepository (databaseTests.testPackageDB.PackageDBTestCase) ... ok
testGetReplaces (databaseTests.testPackageDB.PackageDBTestCase) ... ok
testGetReverseDependencies (databaseTests.testPackageDB.PackageDBTestCase) ... FAIL
testGetVersion (databaseTests.testPackageDB.PackageDBTestCase) ... ok
testHasPackage (databaseTests.testPackageDB.PackageDBTestCase) ... ok
testListPackages (databaseTests.testPackageDB.PackageDBTestCase) ... ok
testSearchPackage (databaseTests.testPackageDB.PackageDBTestCase) ... ok
testWhichRepo (databaseTests.testPackageDB.PackageDBTestCase) ... ok
testAddRemoveCycle (databaseTests.testRepoDB.RepoDBTestCase) ... ok
testAddRemoveRepo (databaseTests.testRepoDB.RepoDBTestCase) ... ok
testGetBinaryRepos (databaseTests.testRepoDB.RepoDBTestCase) ... ok
testGetRepo (databaseTests.testRepoDB.RepoDBTestCase) ... ok
testGetSourceRepos (databaseTests.testRepoDB.RepoDBTestCase) ... ok
testListRepos (databaseTests.testRepoDB.RepoDBTestCase) ... ok
testRepoOrder (databaseTests.testRepoDB.RepoDBTestCase) ... ok
testSearch (databaseTests.testSearch.SearchTestCase) ... ERROR
testGetSourceFromPackage (databaseTests.testSourceDB.SourceDBTestCase) ... ERROR
testGetSpec (databaseTests.testSourceDB.SourceDBTestCase) ... ok
testGetSpecAndRepository (databaseTests.testSourceDB.SourceDBTestCase) ... ok
testGetSpecOfRepository (databaseTests.testSourceDB.SourceDBTestCase) ... ok
testHasSpec (databaseTests.testSourceDB.SourceDBTestCase) ... ok
testListSources (databaseTests.testSourceDB.SourceDBTestCase) ... skipped ''
testSearchPackage (databaseTests.testSourceDB.SourceDBTestCase) ... ok
testBuildDefaults (inaryTests.testConfigFile.ConfigFileTestCase) ... ok
testConfigurationSection (inaryTests.testConfigFile.ConfigFileTestCase) ... ok
testDirectoriesDefaults (inaryTests.testConfigFile.ConfigFileTestCase) ... ok
testGeneralDefaults (inaryTests.testConfigFile.ConfigFileTestCase) ... ok
testInaryConfValues (inaryTests.testConfigFile.ConfigFileTestCase) ... ok
testValuesExists (inaryTests.testConfigFile.ConfigFileTestCase) ... ok
testConstants (inaryTests.testConstants.ConstantTestCase) ... ok
testGetMirrors (inaryTests.testMirrors.MirrorsTestCase) ... ok
testBaseName (inaryTests.testShell.ShellTestCase) ... ok
testCanAccessDirectory (inaryTests.testShell.ShellTestCase) ... ok
testCanAccessFile (inaryTests.testShell.ShellTestCase) ... ok
testCopy (inaryTests.testShell.ShellTestCase) ... ok
testEcho (inaryTests.testShell.ShellTestCase) ... ok
testIsDirectory (inaryTests.testShell.ShellTestCase) ... ok
testIsFile (inaryTests.testShell.ShellTestCase) ... ok
testIsLink (inaryTests.testShell.ShellTestCase) ... ok
testMakedirs (inaryTests.testShell.ShellTestCase) ... ok
testRealPath (inaryTests.testShell.ShellTestCase) ... ok
testSym (inaryTests.testShell.ShellTestCase) ... ok
testSystem (inaryTests.testShell.ShellTestCase) ... ok
testUnlinkDir (inaryTests.testShell.ShellTestCase) ... ok
testFileName (inaryTests.testUri.UriTestCase) ... ok
testIsLocalFile (inaryTests.testUri.UriTestCase) ... ok
testIsRemoteFile (inaryTests.testUri.UriTestCase) ... ok
testSchemePath (inaryTests.testUri.UriTestCase) ... ok
testSetUri (inaryTests.testUri.UriTestCase) ... ok
testCheckFile (inaryTests.testUtil.UtilTestCase) ... ERROR
testCleanDir (inaryTests.testUtil.UtilTestCase) ... ok
testCopyFile (inaryTests.testUtil.UtilTestCase) ... ok
testDirSize (inaryTests.testUtil.UtilTestCase) ... ok
testJoinPath (inaryTests.testUtil.UtilTestCase) ... ok
testRemovePathPrefix (inaryTests.testUtil.UtilTestCase) ... ok
testRunBatch (inaryTests.testUtil.UtilTestCase) ... FAIL
testRunLogged (inaryTests.testUtil.UtilTestCase) ... ok
testSplitPath (inaryTests.testUtil.UtilTestCase) ... ok
testSubPath (inaryTests.testUtil.UtilTestCase) ... ok
testXtermTitle (inaryTests.testUtil.UtilTestCase) ... ok
testGeBug (inaryTests.testVersion.VersionTestCase) ... ok
testOpsCharacters (inaryTests.testVersion.VersionTestCase) ... ok
testOpsKeywords (inaryTests.testVersion.VersionTestCase) ... ok
testOpsNumerical (inaryTests.testVersion.VersionTestCase) ... ok
testSingle (inaryTests.testVersion.VersionTestCase) ... ok
testAutosuper (typeTests.testOO.OOTestCase) ... ok
testConstant (typeTests.testOO.OOTestCase) ... ok
testSingleton (typeTests.testOO.OOTestCase) ... ok
testCycle (typeTests.testPgraph.GraphTestCase) ... ok
testHasEdge (typeTests.testPgraph.GraphTestCase) ... ok
testHasVertex (typeTests.testPgraph.GraphTestCase) ... ok
testTopologicalSort (typeTests.testPgraph.GraphTestCase) ... ok
testDeclaration (xmlTests.testAutoxml.AutoXmlTestCase) ... FAIL
testReadWrite (xmlTests.testAutoxml.AutoXmlTestCase) ... FAIL
testWriteRead (xmlTests.testAutoxml.AutoXmlTestCase) ... FAIL
testStr (xmlTests.testAutoxml.LocalTextTestCase) ... ok
testAddNode (xmlTests.testXmlext.XmlextTestCase) ... ok
testAddText (xmlTests.testXmlext.XmlextTestCase) ... ok
testGetAllNodes (xmlTests.testXmlext.XmlextTestCase) ... ok
testGetChildElts (xmlTests.testXmlext.XmlextTestCase) ... ok
testGetChildText (xmlTests.testXmlext.XmlextTestCase) ... ok
testGetNode (xmlTests.testXmlext.XmlextTestCase) ... ok
testGetNodeAttribute (xmlTests.testXmlext.XmlextTestCase) ... ok
testGetNodeText (xmlTests.testXmlext.XmlextTestCase) ... ok
testGetTagByName (xmlTests.testXmlext.XmlextTestCase) ... ok
testNewDocument (xmlTests.testXmlext.XmlextTestCase) ... ok
testNewNode (xmlTests.testXmlext.XmlextTestCase) ... ok
testParse (xmlTests.testXmlext.XmlextTestCase) ... ok
testRemoveChild (xmlTests.testXmlext.XmlextTestCase) ... ok
testRemoveChildText (xmlTests.testXmlext.XmlextTestCase) ... ok
testSetNodeAttribute (xmlTests.testXmlext.XmlextTestCase) ... ok
testToPretty (xmlTests.testXmlext.XmlextTestCase) ... ok
testToString (xmlTests.testXmlext.XmlextTestCase) ... ok

======================================================================
ERROR: testWhichRepo (databaseTests.testItembyRepo.ItemByRepoTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/suleyman/Development/SulinOS/inary/tests/databaseTests/testItembyRepo.py", line 60, in testWhichRepo
    self.assertEqual(self.testdb.tdb.which_repo("aggdraw"), "repo1")
  File "/usr/local/lib/python3.6/dist-packages/inary/db/itembyrepo.py", line 50, in which_repo
    raise Exception(_("\"{}\" not found in any repository.").format(str(item)))
Exception: "aggdraw" not found in any repository.

======================================================================
ERROR: testSearch (databaseTests.testSearch.SearchTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/suleyman/Development/SulinOS/inary/tests/databaseTests/testSearch.py", line 28, in testSearch
    inary.search.init(['test'], ['en'])
AttributeError: module 'inary' has no attribute 'search'

======================================================================
ERROR: testGetSourceFromPackage (databaseTests.testSourceDB.SourceDBTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/suleyman/Development/SulinOS/inary/tests/databaseTests/testSourceDB.py", line 50, in testGetSourceFromPackage
    pkg = self.sourcedb.pkgtosrc("xz")
  File "/usr/local/lib/python3.6/dist-packages/inary/db/sourcedb.py", line 141, in pkgtosrc
    return self.psdb.get_item(name, repo)
  File "/usr/local/lib/python3.6/dist-packages/inary/db/itembyrepo.py", line 63, in get_item
    item, repo = self.get_item_repo(item, repo)
  File "/usr/local/lib/python3.6/dist-packages/inary/db/itembyrepo.py", line 60, in get_item_repo
    raise Exception(_("Repo item \"{}\" not found.").format(str(item)))
Exception: Repo item "xz" not found.

======================================================================
ERROR: testCheckFile (inaryTests.testUtil.UtilTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/suleyman/Development/SulinOS/inary/tests/inaryTests/testUtil.py", line 48, in testCheckFile
    assert check_file('/usr/bin/bash')
  File "/usr/local/lib/python3.6/dist-packages/inary/util.py", line 436, in check_file
    raise FileError(_("File {} not found.").format(_file))
inary.util.FileError: File /usr/bin/bash not found.

======================================================================
FAIL: testSearchComponent (databaseTests.testComponentDB.ComponentDBTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/suleyman/Development/SulinOS/inary/tests/databaseTests/testComponentDB.py", line 113, in testSearchComponent
    self.assertIn("util.misc", packages)
AssertionError: 'util.misc' not found in []

======================================================================
FAIL: testGetReverseDependencies (databaseTests.testInstallDB.InstallDBTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/suleyman/Development/SulinOS/inary/tests/databaseTests/testInstallDB.py", line 74, in testGetReverseDependencies
    self.assertIn(set(["attr"]), set(map(lambda x:x[0], revdeps)))
AssertionError: {'attr'} not found in set()

======================================================================
FAIL: testGetReverseDependencies (databaseTests.testPackageDB.PackageDBTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/suleyman/Development/SulinOS/inary/tests/databaseTests/testPackageDB.py", line 58, in testGetReverseDependencies
    assert pkg == "bash-dbginfo"
AssertionError

======================================================================
FAIL: testRunBatch (inaryTests.testUtil.UtilTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/suleyman/Development/SulinOS/inary/tests/inaryTests/testUtil.py", line 14, in testRunBatch
    self.assertEqual((127, '', b'/bin/sh: add: command not found\n'), run_batch('add'))
AssertionError: Tuples differ: (127, '', b'/bin/sh: add: command not found\n') != (127, '', b'/bin/sh: 1: add: not found\n')

First differing element 2:
b'/bin/sh: add: command not found\n'
b'/bin/sh: 1: add: not found\n'

- (127, '', b'/bin/sh: add: command not found\n')
?                           --------

+ (127, '', b'/bin/sh: 1: add: not found\n')
?                      +++

======================================================================
FAIL: testDeclaration (xmlTests.testAutoxml.AutoXmlTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/suleyman/Development/SulinOS/inary/tests/xmlTests/testAutoxml.py", line 19, in setUp
    class Rat(xmlfile.XmlFile, metaclass = autoxml.autoxml):
  File "/usr/local/lib/python3.6/dist-packages/inary/sxml/autoxml.py", line 311, in __init__
    x = autoxml.gen_attr_member(cls, name)
  File "/usr/local/lib/python3.6/dist-packages/inary/sxml/autoxml.py", line 517, in gen_attr_member
    assert type(tag_type) == type(type)
AssertionError

======================================================================
FAIL: testReadWrite (xmlTests.testAutoxml.AutoXmlTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/suleyman/Development/SulinOS/inary/tests/xmlTests/testAutoxml.py", line 19, in setUp
    class Rat(xmlfile.XmlFile, metaclass = autoxml.autoxml):
  File "/usr/local/lib/python3.6/dist-packages/inary/sxml/autoxml.py", line 311, in __init__
    x = autoxml.gen_attr_member(cls, name)
  File "/usr/local/lib/python3.6/dist-packages/inary/sxml/autoxml.py", line 517, in gen_attr_member
    assert type(tag_type) == type(type)
AssertionError

======================================================================
FAIL: testWriteRead (xmlTests.testAutoxml.AutoXmlTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/suleyman/Development/SulinOS/inary/tests/xmlTests/testAutoxml.py", line 19, in setUp
    class Rat(xmlfile.XmlFile, metaclass = autoxml.autoxml):
  File "/usr/local/lib/python3.6/dist-packages/inary/sxml/autoxml.py", line 311, in __init__
    x = autoxml.gen_attr_member(cls, name)
  File "/usr/local/lib/python3.6/dist-packages/inary/sxml/autoxml.py", line 517, in gen_attr_member
    assert type(tag_type) == type(type)
AssertionError

----------------------------------------------------------------------

====== COMPLATE TESTS =======
  * Runned 130 tests in 31.047s

    => 119 Successed

    => 7 Failures

    => 4 Errored
[Running Command]: touch tests/systemtest

path: tests/status


code:
import unittest
import os
import time

from inary import version
import inary.constants as constant
from inary.oo import *
from inary.util import Singleton

class OOTestCase(unittest.TestCase):
    def setUp(self):
        pass

    def testAutosuper(self):
        class A(metaclass = autosuper):
            def meth(self):
                return "A"
        class B(A):
            def meth(self):
                return "B" + self.__super.meth()
        class C(A):
            def meth(self):
                return "C" + self.__super.meth()
        class D(C, B):
            def meth(self):
                return "D" + self.__super.meth()

        self.assert_( D().meth() == "DCBA" )

    def testConstant(self):
        class A(constant._constant):
            def __init__(self):
                self.a = 1
                self.b = 2
        mya = A()
        try:
            passed = False
            mya.a = 0
        except constant._constant.ConstError as e:
            passed = True
        self.assert_(passed)

    def testSingleton(self):
        class A(metaclass = Singleton):
            def __init__(self):
                self.a = time.time()
        a1 = A()
        a2 = A()
        self.assert_(a1 is a2)


code:
import unittest
import os
import inary
from inary.data import pgraph

class GraphTestCase(unittest.TestCase):
    def setUp(self):
        self.g0 = pgraph.Digraph()
        self.g0.add_edge(1,2)
        self.g0.add_edge(1,3)
        self.g0.add_edge(2,3)
        self.g0.add_edge(3,4)
        self.g0.add_edge(4,1)

        self.g1 = pgraph.Digraph()
        self.g1.add_edge(0,2)
        self.g1.add_edge(0,3)
        self.g1.add_edge(2,4)
        self.g1.add_edge(3,4)

    def testHasVertex(self):
        assert not self.g0.has_vertex(5)
        assert not self.g1.has_vertex(1)

    def testHasEdge(self):
        assert not self.g0.has_edge(5,6)
        assert not self.g0.has_edge(3,5)
        assert not self.g1.has_edge(2,3)

    def testCycle(self):
        assert not self.g0.cycle_free()
        assert self.g1.cycle_free()

    def testTopologicalSort(self):
        order = self.g1.topological_sort()
        assert order[0] == 0
        assert order[-1] == 4


code:
import unittest
import os

import inary
import inary.api
from inary.sxml import xmlfile
from inary.sxml import autoxml
import inary.util as util

class AutoXmlTestCase(unittest.TestCase):

    def setUp(self):

        class OtherInfo(metaclass = autoxml.autoxml):
            t_StartDate = [autoxml.String, autoxml.mandatory]
            t_Interest = [autoxml.String, autoxml.optional]
            t_Tith = [[autoxml.Text], autoxml.optional, 'Tith/Person']

        class Rat(xmlfile.XmlFile, metaclass = autoxml.autoxml):
            t_Name = [autoxml.Text, autoxml.mandatory]
            t_Description = [autoxml.LocalText, autoxml.mandatory]
            t_Number = [autoxml.Long, autoxml.optional]
            t_Email = [autoxml.String, autoxml.optional]
            a_href = [autoxml.String, autoxml.mandatory]
            t_Dreams = [[autoxml.String], autoxml.mandatory, 'Dreams']
            t_Heality = [autoxml.String, autoxml.optional ]
            s_Comment = [autoxml.Text, autoxml.mandatory]
            a_otherInfo = [OtherInfo, autoxml.mandatory]

        self.Rat = Rat

    def testDeclaration(self):
        self.assertEqual(len(self.Rat.decoders), 8) # Decoders not work well
        self.assert_(hasattr(self.Rat, 'encode'))

    def testReadWrite(self):
        a = self.Rat()

        # test initializer
        self.assertEqual(a.href, None)

        # test read
        a.read('tests/rat.xml')
        self.assert_(a.href.startswith('http://www.su'))
        self.assertEqual(a.number, 911)
        self.assertEqual(a.name, 'Inary Testers')
        self.assertEqual(len(a.dreams), 3)
        self.assertEqual(len(a.heality.tith), 100)
        self.assert_(not a.errors())

        a.print_text(file('/tmp/a', 'w'))
        la = file('/tmp/a').readlines()
        self.assert_( util.any(lambda x:x.find('02012018')!=-1, la) )
        a.write('/tmp/a.xml')
        return

    def testWriteRead(self):
        a = self.Rat()
        a.name = b"Inary Testers"
        a.number = 911
        a.email = "admins@sulin.org"
        a.description['tr'] = 'inary tester ekibi'
        a.comment = b'Sozde test ekibi her seyi ben yapiom'
        a.href = 'http://www.sulin.orf/'
        a.otherInfo.startDate = '01012018'
        a.dreams = [ 'will', 'be', 'hero' ]
        errs = a.errors()
        if errs:
            self.fail( 'We got a bunch of errors: ' + str(errs))
        a.write('/tmp/rat1.xml')
        a2 = self.Rat()
        a2.read('/tmp/rat2.xml')
        self.assertEqual(a, a2)

class LocalTextTestCase(unittest.TestCase):

    def setUp(self):
        a = autoxml.LocalText()
        a['tr'] = 'hop hop zıpla'
        a['en'] = 'jump hop hop'
        self.a = a

    def testStr(self):
        s = str(self.a)
        self.assert_(s!= None and len(s)>=6)


code:
import unittest

try:
    from inary.sxml import xmlext_iks as xmliks
    import ciksemel

except:
    pass

from inary.sxml import xmlext_minidom as xmlmdom
import xml.dom.minidom
import shutil

class XmlextTestCase(unittest.TestCase):

    def setUp(self):
        self.xmlscript = 'something in b tag.<c>something in c tag.</c><d>something in d tag.</d>'
        self.parsedmdom = xmlmdom.parseString(self.xmlscript)
        self.parsediks = xmliks.parseString(self.xmlscript)

    def testParse(self):
        with open("tests/deneme.xml", "w") as a:
            a.write(self.xmlscript)
            a.flush()
            a.close()
        self.assertEqual(xmlmdom.toString(xmlmdom.parse("tests/deneme.xml")), xmliks.toString(xmliks.parse("tests/deneme.xml")))

    def testAddNode(self):
        xmliks.addNode(self.parsediks ,"newtag")
        xmliks.addNode(xmliks.getNode(self.parsediks, "b"), "newtag")
        xmlmdom.addNode(self.parsedmdom ,"newtag")
        xmlmdom.addNode(xmlmdom.getNode(self.parsedmdom, "b"), "newtag")
        self.assertEqual(xmliks.toString(self.parsediks), xmlmdom.toString(self.parsedmdom))

    def testAddText(self):
        xmliks.addText(self.parsediks ,"newtag", "Something else in newtag under a")
        xmliks.addText(xmliks.getNode(self.parsediks, "b"), "newtag", "Something else in newtag under b")
        xmlmdom.addText(self.parsedmdom ,"newtag", "Something else in newtag under a")
        xmlmdom.addText(xmlmdom.getNode(self.parsedmdom, "b"), "newtag", "Something else in newtag under b")
        self.assertEqual(xmliks.toString(self.parsediks), xmlmdom.toString(self.parsedmdom))

    def testGetNode(self):
        self.assertEqual(xmliks.getNode(xmliks.getNode(self.parsediks, "b"), "c").toString(), '<c>something in c tag.</c>')
        self.assertEqual(xmlmdom.getNode(xmlmdom.getNode(self.parsedmdom, "b"), "c").toxml(), '<c>something in c tag.</c>')
        self.assertEqual(xmliks.getNode(xmliks.getNode(self.parsediks, "b"), "c").toString(),
                         xmlmdom.getNode(xmlmdom.getNode(self.parsedmdom, "b"), "c").toxml())

    def testGetChildElts(self):
        self.assertEqual( [xmliks.getNodeText(x) for x in xmliks.getChildElts(self.parsediks)],
                          [xmlmdom.getNodeText(x) for x in xmlmdom.getChildElts(self.parsedmdom)])

    def testGetTagByName(self):
        self.assertEqual( xmliks.getNodeText(xmliks.getTagByName(self.parsediks, "b")[0]),
                          xmlmdom.getNodeText(xmlmdom.getTagByName(self.parsedmdom, "b")[0]) )
        self.assertEqual( xmliks.getNodeText(xmliks.getTagByName(self.parsediks, "d")[0]),
                          xmlmdom.getNodeText(xmlmdom.getTagByName(self.parsedmdom, "d")[0]) )

    def testGetChildText(self):
        self.assertEqual( xmliks.getChildText(self.parsediks, "b"),
                          xmlmdom.getChildText(self.parsedmdom, "b") )
        self.assertEqual( xmliks.getChildText(self.parsediks, "d"),
                          xmlmdom.getChildText(self.parsedmdom, "d") )
        self.assertEqual( xmliks.getChildText(xmliks.getNode(self.parsediks, "b"), "c"),
                          xmlmdom.getChildText(xmlmdom.getNode(self.parsedmdom, "b"),"c") )

    def testGetAllNodes(self):
        self.assertEqual(type(xmlmdom.getAllNodes(self.parsedmdom, "b")[0]),xml.dom.minidom.Element)
        self.assertEqual(type(xmliks.getAllNodes(self.parsediks, "b")[0]), ciksemel.Node)
        self.assertEqual(type(xmlmdom.getAllNodes(self.parsedmdom, "d")[0]),xml.dom.minidom.Element)
        self.assertEqual(type(xmliks.getAllNodes(self.parsediks, "d")[0]), ciksemel.Node)

    def testGetNodeText(self):
        self.assertEqual(xmliks.getNodeText(self.parsediks, "b"), "something in b tag.")
        self.assertEqual(xmlmdom.getNodeText(self.parsedmdom, "b"), "something in b tag.")
        self.assertEqual(xmliks.getNodeText(self.parsediks, "b"), xmlmdom.getNodeText(self.parsedmdom, "b"))

        self.assertEqual(xmliks.getNodeText(self.parsediks, "d"), "something in d tag.")
        self.assertEqual(xmlmdom.getNodeText(self.parsedmdom, "d"), "something in d tag.")
        self.assertEqual(xmliks.getNodeText(self.parsediks, "d"), xmlmdom.getNodeText(self.parsedmdom, "d"))

    def testGetNodeAttribute(self):
        self.assertEqual(xmliks.getNodeAttribute(xmliks.getNode(self.parsediks, "b"), "atrib"), "something")
        self.assertEqual(xmlmdom.getNodeAttribute(xmlmdom.getNode(self.parsedmdom, "b"), "atrib"), "something")
        self.assertEqual(xmliks.getNodeAttribute(xmliks.getNode(self.parsediks, "b"), "atrib"),
                         xmlmdom.getNodeAttribute(xmlmdom.getNode(self.parsedmdom, "b"), "atrib"))

        self.assertEqual(xmliks.getNodeAttribute(xmliks.getNode(self.parsediks, "b"), "actrib"), None)
        self.assertEqual(xmlmdom.getNodeAttribute(xmlmdom.getNode(self.parsedmdom, "b"), "actrib"), None)
        self.assertEqual(xmliks.getNodeAttribute(xmliks.getNode(self.parsediks, "b"), "actrib"),
                         xmlmdom.getNodeAttribute(xmlmdom.getNode(self.parsedmdom, "b"), "actrib"))

        self.assertEqual(xmliks.getNodeAttribute(xmliks.getNode(self.parsediks, "d"), "atrib"), None)
        self.assertEqual(xmlmdom.getNodeAttribute(xmlmdom.getNode(self.parsedmdom, "d"), "atrib"), None)
        self.assertEqual(xmliks.getNodeAttribute(xmliks.getNode(self.parsediks, "d"), "atrib"),
                         xmlmdom.getNodeAttribute(xmlmdom.getNode(self.parsedmdom, "d"), "atrib"))

    def testSetNodeAttribute(self):
        xmliks.setNodeAttribute(xmliks.getNode(self.parsediks, "b"), "atrib", "everything")
        xmlmdom.setNodeAttribute(xmlmdom.getNode(self.parsedmdom, "b"), "atrib", "everything")
        self.assertEqual(xmliks.getNodeAttribute(xmliks.getNode(self.parsediks, "b"), "atrib"), "everything")
        self.assertEqual(xmlmdom.getNodeAttribute(xmlmdom.getNode(self.parsedmdom, "b"), "atrib"), "everything")
        self.assertEqual(xmliks.getNodeAttribute(xmliks.getNode(self.parsediks, "b"), "atrib"),
                         xmlmdom.getNodeAttribute(xmlmdom.getNode(self.parsedmdom, "b"), "atrib"))

        xmliks.setNodeAttribute(xmliks.getNode(self.parsediks, "d"), "atrib", "anything")
        xmlmdom.setNodeAttribute(xmlmdom.getNode(self.parsedmdom, "d"), "atrib", "anything")
        self.assertEqual(xmliks.getNodeAttribute(xmliks.getNode(self.parsediks, "d"), "atrib"), "anything")
        self.assertEqual(xmlmdom.getNodeAttribute(xmlmdom.getNode(self.parsedmdom, "d"), "atrib"), "anything")
        self.assertEqual(xmliks.getNodeAttribute(xmliks.getNode(self.parsediks, "d"), "atrib"),
                         xmlmdom.getNodeAttribute(xmlmdom.getNode(self.parsedmdom, "d"), "atrib"))

    def testRemoveChild(self):
        xmliks.removeChild(xmliks.getNode(self.parsediks, "d"), self.parsediks)
        xmlmdom.removeChild(xmlmdom.getNode(self.parsedmdom, "d"), self.parsedmdom)
        self.assertEqual(xmliks.toString(self.parsediks), xmlmdom.toString(self.parsedmdom))

    def testRemoveChildText(self):
        xmliks.removeChildText(xmliks.getNode(self.parsediks, "d"))
        xmlmdom.removeChildText(xmlmdom.getNode(self.parsedmdom, "d"))
        self.assertEqual(xmliks.toString(self.parsediks), 'something in b tag.<c>something in c tag.</c><d/>')
        self.assertEqual(xmlmdom.toString(self.parsedmdom), 'something in b tag.<c>something in c tag.</c><d></d>')

    def testNewNode(self):
        newiks= xmliks.newNode(self.parsediks, "a")
        newdom= xmlmdom.newNode(self.parsedmdom, "a")
        xmliks.addText(newiks,"b","something under b" )
        xmlmdom.addText(newdom,"b","something under b" )
        self.assertEqual(xmliks.toString(newiks), xmlmdom.toString(newdom))

    def testNewDocument(self):
        self.assertEqual( xmlmdom.toString(xmlmdom.newDocument("newdocument")),
                          xmliks.toString(xmliks.newDocument("newdocument")) )

    def testToString(self):
        self.assertEqual(xmliks.toString(self.parsediks), xmlmdom.toString(self.parsedmdom))

    def testToPretty(self):
        self.assertEqual(xmliks.toPretty(self.parsediks),
"""
    something in b tag.<c>something in c tag.</c>

    <d>something in d tag.</d>
""")
        self.assertEqual(xmlmdom.toPretty(self.parsedmdom),
"""

		something in b tag.
		<c>something in c tag.</c>

	<d>something in d tag.</d>

""")


code:
# ---> Emacs
# -*- mode: gitignore; -*-
*~
\#*\#
/.emacs.desktop
/.emacs.desktop.lock
*.elc
auto-save-list
tramp
.\#*

# Org-mode
.org-id-locations
*_archive

# flymake-mode
*_flymake.*

# eshell files
/eshell/history
/eshell/lastdir

# elpa packages
/elpa/

# reftex files
*.rel

# AUCTeX auto folder
/auto/

# cask packages
.cask/

path: .gitignore


code:
#####
#
# TAGGING
#

We're working on a machine with 64 bit words that address bytes.

* 64 bits = 2^3 = 8 bytes

If we ensure our pointers are 8 byte aligned then their
addresses all end in 000. We can use these 3 bits as a tag.

pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppttt

not every object is a pointer though, we have immediates:

(A) bool, nil, symbol, char
(B) number

(We don't need the symbol object to be a pointer, an index into the
symbol table is fine since displaying symbol names isn't a speed
priority.)

In the case of immediates we can smush several into one ttt tag
and use some more bits ss to distinguish them:

iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiissttt

We also make vectors a special type of a record, to save a tag.

* The special 'all zeros' value of #f can be used with jnz.
* We can save the 'nil' value in a register for fast comparison.
* Char is large enough to hold a unicode code point.

type    obj                       data
--------------------------------------
bool    #f             .....0[00][000]
bool    #t             .....1[00][000]
nil     nil            .....0[01][000]
symbol       [--32 bits--]...[10][000]
char         [--32 bits--]...[11][000]
number     [-------61 bits------][001]
cons                            *[010]
closure                         *[011]
string                          *[100]
vector + record                 *[101]
io port                          [110]
gc-redirect marker              *[111]

#####
#
# LAYOUT
#

All objects will point into the heap except strings may be stored
elsewhere (e.g. constant strings stored in the data section).

ptr           heap
-------------------------------------------------------------
cons     -->  [ car     ][ cdr     ]
closure  -->  [ label   ][ length  ][ env1    ][ env2    ]...
string   -->  <string-data>
vec/rec  -->  [ tag/len ][ field-1 ][ field 2 ][ field-3 ]...
gc-mark  -->  <an objects new place in the other-heap>

#####
#
# CALLING CONVENTION
#

The calling convention is like this:

- Caller enter:
push base-pointer
set base-pointer to stack-pointer
push arg-1
push arg-2
...
push arg-n
call (pushes return address)

this sets the stack up like:

[ret addr][saved bp][arg-1][arg-2]..[arg-n]
                      ^ new bp

- Callee enter:
increase the stack size to make space for its own temps

- Callee exit:

we need to throw away all the temps and args
restore the previous base pointer
and jump to the return address

mov rsp, rbp
pop rbp
ret

- Caller exit:
The caller has no resposibility.
All the args it pushed on the stack have been consumed, base pointer restored.

#####
#
# STACK
#

The stack layout needs to support the following:

* The garbage collector needs to scan through to as a gc root.
  For this to be possible it has to be able to skip past non scheme objects like labels.
* We need to be able to produce stack traces based on the labels.
* Support variable number of arguments to function calls

. previous stack .
: frame          :
+----------------+
| return address |
+----------------+
| saved base ptr |
+----------------+
| arg 1          | <- base pointer
+----------------+
| arg 2          |
+----------------+
:                :
:                :
+----------------+
| arg n          |
+----------------+
| tmp 1          |
+----------------+
| tmp 2          |
+----------------+
:                :
:                :
+----------------+
| tmp n          |
+----------------+
: scheme objects : (this will usually just
: saved by the   :  be the env register)
: callee         :
+----------------+
        .          <-- stack pointer

args will be referenced relative to base pointer
temporaries will be referenced relative to stack pointer

this allows us to support variadic functions!

in the case of a variadic function the callee must cons up the rest list. The reason for this is it allows fast function calls in the non-variadic case.


code:
.vs/
bin/
obj/
winrar-keygen.vcxproj.user

repo_name: lichendaozhu/winrar

license: unknown


code:
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <mpir.h>
#include <vector>
#include <string>
#include <type_traits>
#include <stdexcept>

class BigInteger {
private:
    mpz_t _Value;
public:

    BigInteger() noexcept {
        mpz_init(_Value);
    }

    template<typename __IntegerType>
    BigInteger(__IntegerType SmallInteger) noexcept {
        // __IntegerType must be a integer type, i.e. char, int, unsigned long...
        static_assert(std::is_integral<__IntegerType>::value);

        if constexpr (std::is_signed<__IntegerType>::value) {
            mpz_init_set_sx(_Value, SmallInteger);
        } else {
            mpz_init_set_ux(_Value, SmallInteger);
        }
    }

    BigInteger(bool IsNegative, const void* lpBuffer, size_t cbBuffer, bool UseLittleEndian) noexcept {
        mpz_init(_Value);
        mpz_import(_Value, cbBuffer, UseLittleEndian ? -1 : 1, sizeof(unsigned char), 0, 0, lpBuffer);
        if (IsNegative)
            mpz_neg(_Value, _Value);
    }

    BigInteger(bool IsNegative, const std::vector<uint8_t>& Buffer, bool UseLittleEndian) noexcept {
        mpz_init(_Value);
        mpz_import(_Value, Buffer.size(), UseLittleEndian ? -1 : 1, sizeof(unsigned char), 0, 0, Buffer.data());
        if (IsNegative)
            mpz_neg(_Value, _Value);
    }

    BigInteger(const char* lpszValue) noexcept {
        mpz_init_set_str(_Value, lpszValue, 0);
    }

    BigInteger(const std::string& szValue) noexcept {
        mpz_init_set_str(_Value, szValue.c_str(), 0);
    }

    BigInteger(const BigInteger& Other) noexcept {
        mpz_init(_Value);
        mpz_set(_Value, Other._Value);
    }

    BigInteger(BigInteger&& Other) noexcept {
        mpz_init(_Value);
        mpz_swap(_Value, Other._Value);
    }

    BigInteger& operator=(const BigInteger& Other) noexcept {
        if (this != &Other) {
            mpz_set(_Value, Other._Value);
        }
        return *this;
    }

    BigInteger& operator=(BigInteger&& Other) noexcept {
        if (this != &Other) {
            mpz_swap(_Value, Other._Value);
            mpz_set_ux(Other._Value, 0);
        }
        return *this;
    }

    template<typename __IntegerType>
    BigInteger& operator=(__IntegerType SmallInteger) noexcept {
        // __IntegerType must be a integer type, i.e. char, int, unsigned long...
        static_assert(std::is_integral<__IntegerType>::value);

        if constexpr (std::is_signed<__IntegerType>::value) {
            mpz_set_sx(_Value, SmallInteger);
        } else {
            mpz_set_ux(_Value, SmallInteger);
        }

        return *this;
    }

    BigInteger& operator=(const char* lpszValue) noexcept {
        mpz_init_set_str(_Value, lpszValue, 0);
        return *this;
    }

    bool operator==(const BigInteger& Other) const noexcept {
        return mpz_cmp(_Value, Other._Value) == 0;
    }

    bool operator!=(const BigInteger& Other) const noexcept {
        return mpz_cmp(_Value, Other._Value) != 0;
    }

    bool operator<(const BigInteger& Other) const noexcept {
        return mpz_cmp(_Value, Other._Value) < 0;
    }

    bool operator<=(const BigInteger& Other) const noexcept {
        auto d = mpz_cmp(_Value, Other._Value);
        return d < 0 || d == 0;
    }

    bool operator>(const BigInteger& Other) const noexcept {
        return mpz_cmp(_Value, Other._Value) > 0;
    }

    bool operator>=(const BigInteger& Other) const noexcept {
        auto d = mpz_cmp(_Value, Other._Value);
        return d > 0 || d == 0;
    }

    BigInteger operator-() const noexcept {
        BigInteger Result;
        mpz_neg(Result._Value, _Value);
        return Result;
    }

    BigInteger operator+(const BigInteger& Other) const noexcept {
        BigInteger Result;
        mpz_add(Result._Value, _Value, Other._Value);
        return Result;
    }

    BigInteger& operator+=(const BigInteger& Other) noexcept {
        mpz_add(_Value, _Value, Other._Value);
        return *this;
    }

    BigInteger operator-(const BigInteger& Other) const noexcept {
        BigInteger Result;
        mpz_sub(Result._Value, _Value, Other._Value);
        return Result;
    }

    BigInteger& operator-=(const BigInteger& Other) noexcept {
        mpz_sub(_Value, _Value, Other._Value);
        return *this;
    }

    BigInteger operator*(const BigInteger& Other) const noexcept {
        BigInteger Result;
        mpz_mul(Result._Value, _Value, Other._Value);
        return Result;
    }

    BigInteger& operator*=(const BigInteger& Other) noexcept {
        mpz_mul(_Value, _Value, Other._Value);
        return *this;
    }

    BigInteger operator/(const BigInteger& Other) const noexcept {
        BigInteger Result;
        mpz_fdiv_q(Result._Value, _Value, Other._Value);
        return Result;
    }

    BigInteger& operator/=(const BigInteger& Other) noexcept {
        mpz_fdiv_q(_Value, _Value, Other._Value);
        return *this;
    }

    BigInteger operator%(const BigInteger& Other) const noexcept {
        BigInteger Result;
        mpz_fdiv_r(Result._Value, _Value, Other._Value);
        return Result;
    }

    BigInteger& operator%=(const BigInteger& Other) noexcept {
        mpz_fdiv_r(_Value, _Value, Other._Value);
        return *this;
    }

    BigInteger operator~() const noexcept {
        BigInteger Result;
        mpz_com(Result._Value, _Value);
        return Result;
    }

    BigInteger operator&(const BigInteger& Other) const noexcept {
        BigInteger Result;
        mpz_and(Result._Value, _Value, Other._Value);
        return Result;
    }

    BigInteger& operator&=(const BigInteger& Other) noexcept {
        mpz_and(_Value, _Value, Other._Value);
        return *this;
    }

    BigInteger operator|(const BigInteger& Other) const noexcept {
        BigInteger Result;
        mpz_ior(Result._Value, _Value, Other._Value);
        return Result;
    }

    BigInteger& operator|=(const BigInteger& Other) noexcept {
        mpz_ior(_Value, _Value, Other._Value);
        return *this;
    }

    BigInteger operator^(const BigInteger& Other) const noexcept {
        BigInteger Result;
        mpz_xor(Result._Value, _Value, Other._Value);
        return Result;
    }

    BigInteger& operator^=(const BigInteger& Other) noexcept {
        mpz_xor(_Value, _Value, Other._Value);
        return *this;
    }

    BigInteger& operator++() noexcept {
        mpz_add_ui(_Value, _Value, 1);
        return *this;
    }

    BigInteger operator++(int) noexcept {
        BigInteger Result(*this);
        mpz_add_ui(_Value, _Value, 1);
        return Result;
    }

    BigInteger& operator--() noexcept {
        mpz_sub_ui(_Value, _Value, 1);
        return *this;
    }

    BigInteger operator--(int) noexcept {
        BigInteger Result(*this);
        mpz_sub_ui(_Value, _Value, 1);
        return Result;
    }

    bool IsZero() const noexcept {
        return mpz_sgn(_Value) == 0;
    }

    bool IsPositive() const noexcept {
        return mpz_sgn(_Value) > 0;
    }

    bool IsNegative() const noexcept {
        return mpz_sgn(_Value) < 0;
    }

    bool IsOne() const noexcept {
        return mpz_cmp_si(_Value, 1) == 0;
    }

    BigInteger& Load(bool IsNegative, const void* lpBuffer, size_t cbBuffer, bool UseLittleEndian) noexcept {
        mpz_import(_Value, cbBuffer, UseLittleEndian ? -1 : 1, sizeof(uint8_t), 0, 0, lpBuffer);
        if (IsNegative)
            mpz_neg(_Value, _Value);
        return *this;
    }

    BigInteger& Load(bool IsNegative, const std::vector<uint8_t> Buffer, bool UseLittleEndian) noexcept {
        mpz_import(_Value, Buffer.size(), UseLittleEndian ? -1 : 1, sizeof(uint8_t), 0, 0, Buffer.data());
        if (IsNegative)
            mpz_neg(_Value, _Value);
        return *this;
    }

    void DumpAbs(void* lpBuffer, size_t cbBuffer, bool UseLittleEndian) const {
        size_t bit_size = mpz_sizeinbase(_Value, 2);
        size_t storage_size = (bit_size + 7) / 8;
        if (cbBuffer >= storage_size) {
            size_t bytes_written;
            mpz_export(lpBuffer, &bytes_written, UseLittleEndian ? -1 : 1, sizeof(uint8_t), 0, 0, _Value);
            memset(reinterpret_cast<unsigned char*>(lpBuffer) + bytes_written, 0, cbBuffer - bytes_written);
        } else {
            throw std::length_error("Insufficient buffer.");
        }
    }

    std::vector<uint8_t> DumpAbs(bool UseLittleEndian) const noexcept {
        size_t bit_size = mpz_sizeinbase(_Value, 2);
        size_t storage_size = (bit_size + 7) / 8;
        std::vector<uint8_t> bytes(storage_size);
        mpz_export(bytes.data(), nullptr, UseLittleEndian ? -1 : 1, sizeof(uint8_t), 0, 0, _Value);
        return bytes;
    }

    size_t BitLength() const noexcept {
        return mpz_sizeinbase(_Value, 2);
    }

    bool TestBit(size_t i) const noexcept {
        return mpz_tstbit(_Value, i) != 0;
    }

    void SetBit(size_t i) noexcept {
        mpz_setbit(_Value, i);
    }

    std::string ToString(size_t Base, bool LowerCase) const {
        if (2 <= Base && Base <= 10 + 26) {
            int base = LowerCase ? static_cast<int>(Base) : -static_cast<int>(Base);
            std::string s(mpz_sizeinbase(_Value, base) + 2, '\x00');

            mpz_get_str(s.data(), base, _Value);

            while (s.back() == '\x00') {
                s.pop_back();
            }

            return s;
        } else {
            throw std::invalid_argument("Invalid base value.");
        }
    }

    ~BigInteger() {
        mpz_clear(_Value);
    }
};


code:
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <stdexcept>
#include <algorithm>
#include "BigInteger.hpp"

template<typename __FieldType>
class EllipticCurveGF2m {
private:
    // y^2 + xy = x^3 + Ax^2 + B

    __FieldType _A;
    __FieldType _B;

    void _VerifyParameters() const {
        if (_B.IsZero()) {
            throw std::invalid_argument("B cannot be zero.");
        }
    }
public:

    class Point {
        friend EllipticCurveGF2m<__FieldType>;
    private:
        const EllipticCurveGF2m<__FieldType>& _Curve;
        __FieldType _X;
        __FieldType _Y;

        void _VerifyParameters() const {
            auto Left = _Y.SquareValue() + _X * _Y;
            auto Right = (_X + _Curve._A) * _X.SquareValue() + _Curve._B;
            if (Left != Right) {
                throw std::invalid_argument("New point is not on the curve specified.");
            }
        }
    public:

        Point(const EllipticCurveGF2m<__FieldType>& Curve) noexcept :
            _Curve(Curve) {}

        Point(const EllipticCurveGF2m<__FieldType>& Curve, const void* pbX, size_t cbX, const void* pbY, size_t cbY) :
            _Curve(Curve),
            _X(pbX, cbX),
            _Y(pbY, cbY)
        {
            _VerifyParameters();
        }

        Point(const EllipticCurveGF2m<__FieldType>& Curve, const __FieldType& X, const __FieldType& Y) :
            _Curve(Curve), _X(X), _Y(Y)
        {
            _VerifyParameters();
        }

        Point operator-() const noexcept {
            return Point(_X, _X + _Y);
        }

        Point& operator=(const Point& Other) {
            if (&_Curve == &Other._Curve || _Curve == Other._Curve) {
                _X = Other._X;
                _Y = Other._Y;
                return *this;
            } else {
                throw std::invalid_argument("Not on the same curve.");
            }
        }

        bool operator==(const Point& Other) const noexcept {
            if (&_Curve == &Other._Curve || _Curve == Other._Curve) {
                return _X == Other._X && _Y == Other._Y;
            } else {
                return false;
            }
        }

        bool operator!=(const Point& Other) const noexcept {
            if (&_Curve == &Other._Curve || _Curve == Other._Curve) {
                return _X != Other._X || _Y != Other._Y;
            } else {
                return true;
            }
        }

        const __FieldType& GetX() const noexcept {
            return _X;
        }

        const __FieldType& GetY() const noexcept {
            return _Y;
        }

        bool IsAtInfinity() const noexcept {
            return _X.IsZero() && _Y.IsZero();
        }

        Point& Double() noexcept {
            if (IsAtInfinity() == false) {
                auto m = _Y / _X + _X;

                // NewX = m ^ 2 + m + a
                __FieldType NewX = m.SquareValue();
                NewX += m;
                NewX += _Curve._A;

                // NewY = X ^ 2 + (m + 1) * NewX
                _Y = m.AddOne();
                _Y *= NewX;
                _Y += _X.Square();

                _X = NewX;
            }
            return *this;
        }

        Point ValueOfDouble() const noexcept {
            Point Result(_Curve);

            if (IsAtInfinity() == false) {
                // m = X + Y / X
                auto m = _Y / _X + _X;

                // NewX = m ^ 2 + m + a
                Result._X = m.SquareValue();
                Result._X += m;
                Result._X += _Curve._A;

                // NewY = X ^ 2 + (m + 1) * NewX
                Result._Y = m.AddOne();
                Result._Y *= Result._X;
                Result._Y += _X.SquareValue();
            }

            return Result;
        }

        Point operator+(const Point& Other) const {
            if (&_Curve == &Other._Curve || _Curve == Other._Curve) {
                if (IsAtInfinity()) {
                    return Other;
                } else {
                    if (this == &Other || _X == Other._X) {
                        return ValueOfDouble();
                    } else {
                        Point Result(_Curve);

                        // m = (Y0 + Y1) / (X0 + X1)
                        auto m = (_Y + Other._Y) / (_X + Other._X);

                        // NewX = m ^ 2 + m + X0 + X1 + a
                        Result._X = m.SquareValue();
                        Result._X += m;
                        Result._X += _X;
                        Result._X += Other._X;
                        Result._X += _Curve._A;

                        // NewY = m * (X0 + NewX) + NewX + Y0
                        Result._Y = _X + Result._X;
                        Result._Y *= m;
                        Result._Y += Result._X;
                        Result._Y += _Y;

                        return Result;
                    }
                }
            } else {
                throw std::invalid_argument("Not on the same curve.");
            }
        }

        Point& operator+=(const Point& Other) {
            if (&_Curve == &Other._Curve || _Curve == Other._Curve) {
                if (IsAtInfinity()) {
                    _X = Other._X;
                    _Y = Other._Y;
                } else {
                    if (this == &Other || _X == Other._X) {
                        Double();
                    } else {
                        Point Result(_Curve);

                        // m = (Y0 + Y1) / (X0 + X1)
                        auto m = (_Y + Other._Y) / (_X + Other._X);

                        // NewX = m ^ 2 + m + X0 + X1 + a
                        __FieldType NewX = m.SquareValue();
                        NewX += m;
                        NewX += _X;
                        NewX += Other._X;
                        NewX += _Curve._A;

                        // NewY = m * (X0 + NewX) + NewX + Y0
                        _X += NewX;
                        _X *= m;
                        _X += NewX;
                        _Y += _X;

                        _X = NewX;
                    }
                }
                return *this;
            } else {
                throw std::invalid_argument("Not on the same curve.");
            }
        }

        Point operator-(const Point& Other) const {
            Point Result = -Other;
            Result += *this;
            return Result;
        }

        Point& operator-=(const Point& Other) {
            return *this += -Other;
        }

        Point operator*(const BigInteger N) const noexcept {
            Point Result(_Curve);
            Point temp(*this);
            size_t bit_length = N.BitLength();

            for (size_t i = 0; i < bit_length; ++i) {
                if (N.TestBit(i) == true)
                    Result += temp;
                temp.Double();
            }

            return Result;
        }

        Point operator*=(const BigInteger N) noexcept {
            Point Result(_Curve);
            size_t bit_length = N.BitLength();

            for (size_t i = 0; i < bit_length; ++i) {
                if (N.TestBit(i) == true)
                    Result += *this;
                Double();
            }

            *this = Result;
        }

        // SEC 1: Elliptic Curve Cryptography
        //     2.3.3 Elliptic-Curve-Point-to-Octet-String Conversion
        std::vector<uint8_t> Dump() const noexcept {
            if (IsAtInfinity()) {
                std::vector<uint8_t> bytes = { 0x00 };
                return bytes;
            } else {
                std::vector<uint8_t> bytes = { 0x04 };
                std::vector<uint8_t> xbytes = _X.Dump();
                std::vector<uint8_t> ybytes = _Y.Dump();
                std::reverse(xbytes.begin(), xbytes.end());     // to big endian
                std::reverse(ybytes.begin(), ybytes.end());     // to big endian
                bytes.insert(bytes.end(), xbytes.begin(), xbytes.end());
                bytes.insert(bytes.end(), ybytes.begin(), ybytes.end());
                return bytes;
            }
        }

        // SEC 1: Elliptic Curve Cryptography
        //     2.3.3 Elliptic-Curve-Point-to-Octet-String Conversion
        std::vector<uint8_t> DumpCompressed() const noexcept {
            if (IsAtInfinity()) {
                std::vector<uint8_t> bytes = { 0x00 };
                return bytes;
            } else {
                std::vector<uint8_t> bytes(1);
                std::vector<uint8_t> xbytes = _X.Dump();
                std::vector<uint8_t> zbytes = (_Y / _X).Dump();

                if (zbytes[0] & 1) {
                    bytes[0] = 0x03;
                } else {
                    bytes[0] = 0x02;
                }

                std::reverse(xbytes.begin(), xbytes.end());     // to big endian
                bytes.insert(bytes.end(), xbytes.begin(), xbytes.end());
                return bytes;
            }
        }
    };

    EllipticCurveGF2m(const __FieldType& A, const __FieldType& B) : _A(A), _B(B) {
        _VerifyParameters();
    }

    EllipticCurveGF2m(const void* pbA, size_t cbA, const void* pbB, size_t cbB) : _A(pbA, cbA), _B(pbB, cbB) {
        _VerifyParameters();
    }

    bool operator==(const EllipticCurveGF2m<__FieldType>& Other) const noexcept {
        return _A == Other._A && _B == Other._B;
    }

    bool operator!=(const EllipticCurveGF2m<__FieldType>& Other) const noexcept {
        return _A != Other._A || _B != Other._B;
    }

    Point GetInfinityPoint() const noexcept {
        return Point(*this);
    }

    Point GetPoint(const __FieldType& X, const __FieldType& Y) const {
        return Point(*this, X, Y);
    }

    Point GetPoint(const void* pbX, size_t cbX, const void* pbY, size_t cbY) const {
        return Point(*this, pbX, cbX, pbY, cbY);
    }
};


code:
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <vector>
#include <type_traits>

struct GaloisFieldInitByZero {};
struct GaloisFieldInitByOne {};
struct GaloisFieldInitByElement {};
struct GaloisFieldInitByDump {};

template<typename __FieldTraits>
class GaloisField {
public:
    static constexpr size_t BitSizeValue = __FieldTraits::BitSizeValue;
    static constexpr size_t DumpSizeValue = __FieldTraits::DumpSizeValue;
private:
    static_assert(std::is_pod<typename __FieldTraits::ElementType>::value == true);

    typename __FieldTraits::ElementType _Val;

#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 26495)  // disable uninitialized warning
#endif
    struct NoInitialization {};
    GaloisField(NoInitialization) noexcept {};
#ifdef _MSC_VER
#pragma warning(pop)
#endif

public:
    GaloisField() noexcept {
        __FieldTraits::SetZero(_Val);
    }

    GaloisField(GaloisFieldInitByZero) noexcept {
        __FieldTraits::SetZero(_Val);
    }

    GaloisField(GaloisFieldInitByOne) noexcept {
        __FieldTraits::SetOne(_Val);
    }

    GaloisField(GaloisFieldInitByElement, const typename __FieldTraits::ElementType& Element) {
        __FieldTraits::Verify(Element);
        _Val = Element;
    }

    GaloisField(GaloisFieldInitByDump, const void* pbBuffer, size_t cbBuffer) {
        __FieldTraits::Load(_Val, pbBuffer, cbBuffer);
    }

    template<typename F=__FieldTraits, typename std::enable_if<F::BitSizeValue <= sizeof(uintptr_t) * 8, std::nullptr_t>::type = nullptr>
    GaloisField(GaloisFieldInitByDump, uintptr_t SerializedValue) {
        __FieldTraits::Load(_Val, SerializedValue);
    }

    GaloisField<__FieldTraits>& operator=(const typename __FieldTraits::ElementType& Element) {
        __FieldTraits::Verify(Element);
        _Val = Element;
        return *this;
    }

    template<typename F=__FieldTraits, typename std::enable_if<F::BitSizeValue <= sizeof(uintptr_t) * 8, std::nullptr_t>::type = nullptr>
    GaloisField<__FieldTraits>& operator=(uintptr_t SerializedValue) {
        __FieldTraits::Load(_Val, SerializedValue);
        return *this;
    }

    bool IsZero() const noexcept {
        return __FieldTraits::IsZero(_Val);
    }

    bool IsOne() const noexcept {
        return __FieldTraits::IsOne(_Val);
    }

    bool operator==(const GaloisField<__FieldTraits>& Other) const noexcept {
        return __FieldTraits::IsEqual(_Val, Other._Val);
    }

    bool operator!=(const GaloisField<__FieldTraits>& Other) const noexcept {
        return __FieldTraits::IsEqual(_Val, Other._Val) == false;
    }

    GaloisField<__FieldTraits> operator+(const GaloisField<__FieldTraits>& Other) const noexcept {
        GaloisField<__FieldTraits> Result(NoInitialization{});
        __FieldTraits::Add(Result._Val, _Val, Other._Val);
        return Result;
    }

    GaloisField<__FieldTraits>& operator+=(const GaloisField<__FieldTraits>& Other) noexcept {
        __FieldTraits::AddAssign(_Val, Other._Val);
        return *this;
    }

    GaloisField<__FieldTraits> operator-(const GaloisField<__FieldTraits>& Other) const noexcept {
        GaloisField<__FieldTraits> Result(NoInitialization{});
        __FieldTraits::Substract(Result._Val, _Val, Other._Val);
        return Result;
    }

    GaloisField<__FieldTraits>& operator-=(const GaloisField<__FieldTraits>& Other) noexcept {
        __FieldTraits::SubstractAssign(_Val, Other._Val);
        return *this;
    }

    GaloisField<__FieldTraits> operator*(const GaloisField<__FieldTraits>& Other) const noexcept {
        GaloisField<__FieldTraits> Result(NoInitialization{});
        __FieldTraits::Multiply(Result._Val, _Val, Other._Val);
        return Result;
    }

    GaloisField<__FieldTraits>& operator*=(const GaloisField<__FieldTraits>& Other) noexcept {
        __FieldTraits::MultiplyAssign(_Val, Other._Val);
        return *this;
    }

    GaloisField<__FieldTraits> operator/(const GaloisField<__FieldTraits>& Other) const {
        GaloisField<__FieldTraits> Result(NoInitialization{});
        __FieldTraits::Divide(Result._Val, _Val, Other._Val);
        return Result;
    }

    GaloisField<__FieldTraits>& operator/=(const GaloisField<__FieldTraits>& Other) {
        __FieldTraits::DivideAssign(_Val, Other._Val);
        return *this;
    }

    GaloisField<__FieldTraits>& operator++() noexcept {  // prefix ++
        __FieldTraits::AddOneAssign(_Val);
        return *this;
    }

    GaloisField<__FieldTraits> operator++(int) noexcept { // postfix ++
        GaloisField<__FieldTraits> Prev(*this);
        __FieldTraits::AddOneAssign(_Val);
        return Prev;
    }

    GaloisField<__FieldTraits>& operator--() noexcept {  // prefix --
        __FieldTraits::SubstractOneAssign(_Val);
        return *this;
    }

    GaloisField<__FieldTraits> operator--(int) noexcept { // postfix --
        GaloisField<__FieldTraits> Prev(*this);
        __FieldTraits::SubstractOneAssign(_Val);
        return Prev;
    }

    GaloisField<__FieldTraits>& Inverse() {
        __FieldTraits::InverseAssign(_Val);
        return *this;
    }

    GaloisField<__FieldTraits> InverseValue() const {
        GaloisField<__FieldTraits> Result(NoInitialization{});
        __FieldTraits::Inverse(Result, _Val);
        return Result;
    }

    GaloisField<__FieldTraits>& AddOne() noexcept {
        __FieldTraits::AddOneAssign(_Val);
        return *this;
    }

    GaloisField<__FieldTraits> AddOneValue() const noexcept {
        GaloisField<__FieldTraits> Result(NoInitialization{});
        __FieldTraits::AddOne(Result._Val, _Val);
        return Result;
    }

    GaloisField<__FieldTraits>& SubstractOne() noexcept {
        __FieldTraits::SubstractOneAssign(_Val);
        return *this;
    }

    GaloisField<__FieldTraits> SubstractOneValue() const noexcept {
        GaloisField<__FieldTraits> Result(NoInitialization{});
        __FieldTraits::SubstractOne(Result._Val, _Val);
        return Result;
    }

    GaloisField<__FieldTraits>& Square() noexcept {
        __FieldTraits::SquareAssign(_Val);
        return *this;
    }

    GaloisField<__FieldTraits> SquareValue() const noexcept {
        GaloisField<__FieldTraits> Result(NoInitialization{});
        __FieldTraits::Square(Result._Val, _Val);
        return Result;
    }

    template<typename F=__FieldTraits, typename std::enable_if<F::BitSizeValue <= sizeof(uintptr_t) * 8, std::nullptr_t>::type = nullptr>
    uintptr_t Dump() const noexcept {
        return __FieldTraits::Dump(_Val);
    }

    size_t Dump(void* lpBuffer, size_t cbBuffer) const {
        return __FieldTraits::Dump(_Val, lpBuffer, cbBuffer);
    }

    std::vector<uint8_t> Dump() const noexcept {
        return __FieldTraits::Dump(_Val);
    }

    template<typename F=__FieldTraits, typename std::enable_if<F::BitSizeValue <= sizeof(uintptr_t) * 8, std::nullptr_t>::type = nullptr>
    GaloisField<__FieldTraits>& Load(uintptr_t SerializedValue) {
        __FieldTraits::Load(_Val, SerializedValue);
        return *this;
    }

    GaloisField<__FieldTraits>& Load(const void* lpBuffer, size_t cbBuffer) {
        __FieldTraits::Load(_Val, lpBuffer, cbBuffer);
        return *this;
    }

    GaloisField<__FieldTraits>& Load(const std::vector<uint8_t>& Buffer) {
        __FieldTraits::Load(_Val, Buffer);
        return *this;
    }
};


code:
#pragma once
#include <utility>

template<typename __HashTraits>
class Hasher {
public:
    static constexpr size_t BlockSizeValue = __HashTraits::BlockSize;
    static constexpr size_t DigestSizeValue = __HashTraits::DigestSize;
    using DigestType = typename __HashTraits::DigestType;
private:
    using ContextType = typename __HashTraits::ContextType;
    ContextType _Ctx;
public:

    Hasher(__HashTraits) :
        _Ctx(__HashTraits::ContextCreate()) {}

    template<typename... __Ts>
    Hasher(__HashTraits, __Ts&&... Args) :
        _Ctx(__HashTraits::ContextCreate(std::forward<__Ts>(Args)...)) {}

    Hasher(const Hasher<__HashTraits>& Other) :
        _Ctx(__HashTraits::ContextCopy(Other._Ctx)) {}

    Hasher(Hasher<__HashTraits>&& Other) noexcept :
        _Ctx(std::move(Other._Ctx)) {}

    Hasher<__HashTraits>& operator=(const Hasher<__HashTraits>& Other) {
        ContextType t = __HashTraits::ContextCopy(Other._Ctx);
        __HashTraits::ContextDestroy(_Ctx);
        _Ctx = std::move(t);
        return *this;
    }

    Hasher<__HashTraits>& operator=(Hasher<__HashTraits>&& Other) noexcept {
        _Ctx = std::move(Other._Ctx);
        return *this;
    }

    constexpr size_t BlockSize() const noexcept {
        return BlockSizeValue;
    }

    constexpr size_t DigestSize() const noexcept {
        return DigestSizeValue;
    }

    void Update(const void* lpBuffer, size_t cbBuffer) noexcept {
        __HashTraits::ContextUpdate(_Ctx, lpBuffer, cbBuffer);
    }

    DigestType Evaluate() const noexcept {
        DigestType Digest;
        __HashTraits::ContextEvaluate(_Ctx, Digest);
        return Digest;
    }

    ~Hasher() {
        __HashTraits::ContextDestroy(_Ctx);
    }
};


code:
#pragma once
#include <stddef.h>
#include <stdint.h>

template<uint32_t __Polynomial>
struct HasherCrc32Traits {
    static constexpr size_t BlockSize = 0;
    static constexpr size_t DigestSize = 32 / 8;

    using DigestType = uint32_t;
    using LookupTableType = uint32_t[256];

    struct ContextType {
        uint32_t Value;

        ContextType() noexcept :
            Value(0) {}

        ContextType(uint32_t InitialValue) noexcept :
            Value(InitialValue) {}

        ContextType(const ContextType& Other) noexcept = default;

        ContextType(ContextType&& Other) noexcept : Value(Other.Value) {
            Other.Value = 0;
        }

        ContextType& operator=(const ContextType& Other) noexcept = default;

        ContextType& operator=(ContextType&& Other) noexcept {
            Value = Other.Value;
            Other.Value = 0;
            return *this;
        }
    };

    static const LookupTableType& InitializeLookupTable() noexcept {
        static LookupTableType LookupTable = {};

        if (LookupTable[1] == 0) {
            for (unsigned i = 0; i < 256; ++i) {
                uint32_t result = i;
                for (unsigned j = 0; j < 8; ++j) {
                    if (result % 2) {
                        result /= 2;
                        result ^= __Polynomial;
                    } else {
                        result /= 2;
                    }
                }
                LookupTable[i] = result;
            }
        }

        return LookupTable;
    }

    static inline const LookupTableType& LookupTable = InitializeLookupTable();

    static inline ContextType ContextCreate() noexcept {
        ContextType Ctx;
        return Ctx;
    }

    static inline ContextType ContextCreate(const void* lpBuffer, size_t cbBuffer) noexcept {
        ContextType Ctx;
        ContextUpdate(Ctx, lpBuffer, cbBuffer);
        return Ctx;
    }

    static inline ContextType ContextCreate(uint32_t InitialValue) noexcept {
        ContextType Ctx(InitialValue);
        return Ctx;
    }

    static inline ContextType ContextCreate(uint32_t InitialValue, const void* lpBuffer, size_t cbBuffer) noexcept {
        ContextType Ctx;
        ContextUpdate(Ctx, lpBuffer, cbBuffer);
        return Ctx;
    }

    static inline ContextType ContextCopy(const ContextType& Ctx) noexcept {
        return Ctx;
    }

    static inline void ContextUpdate(ContextType& Ctx, const void* lpBuffer, size_t cbBuffer) noexcept {
        auto pbBuffer = reinterpret_cast<const uint8_t*>(lpBuffer);
        Ctx.Value = ~Ctx.Value;
        for (size_t i = 0; i < cbBuffer; ++i) {
            Ctx.Value = (Ctx.Value >> 8) ^ LookupTable[static_cast<uint8_t>(Ctx.Value) ^ pbBuffer[i]];
        }
        Ctx.Value = ~Ctx.Value;
    }

    static inline void ContextEvaluate(const ContextType& Ctx, DigestType& Digest) noexcept {
        Digest = Ctx.Value;
    }

    static inline void ContextDestroy(ContextType& Ctx) noexcept {
        Ctx.Value = 0;
    }
};

#ifdef _WIN32
#include <windows.h>

#ifdef __cplusplus
extern "C" {
#endif

#pragma comment(lib, "ntdll")

    // available on WindowsXP and above
    NTSYSAPI
    DWORD
    NTAPI
    RtlComputeCrc32(
        _In_ DWORD InitialCrc,
        _In_reads_bytes_(Size) const void* Buffer,
        _In_ size_t Size
    );

#ifdef __cplusplus
}
#endif

template<>
struct HasherCrc32Traits<0xEDB88320> {
    static constexpr size_t BlockSize = 0;
    static constexpr size_t DigestSize = 32 / 8;

    using DigestType = uint32_t;

    struct ContextType {
        uint32_t Value;

        ContextType() noexcept :
            Value(0) {}

        ContextType(uint32_t InitialValue) noexcept :
            Value(InitialValue) {}

        ContextType(const ContextType& Other) noexcept = default;

        ContextType(ContextType&& Other) noexcept : Value(Other.Value) {
            Other.Value = 0;
        }

        ContextType& operator=(const ContextType& Other) noexcept = default;

        ContextType& operator=(ContextType&& Other) noexcept {
            Value = Other.Value;
            Other.Value = 0;
            return *this;
        }
    };

    static inline ContextType ContextCreate() noexcept {
        ContextType Ctx;
        return Ctx;
    }

    static inline ContextType ContextCreate(const void* lpBuffer, size_t cbBuffer) noexcept {
        ContextType Ctx;
        ContextUpdate(Ctx, lpBuffer, cbBuffer);
        return Ctx;
    }

    static inline ContextType ContextCreate(uint32_t InitialValue) noexcept {
        ContextType Ctx(InitialValue);
        return Ctx;
    }

    static inline ContextType ContextCreate(uint32_t InitialValue, const void* lpBuffer, size_t cbBuffer) noexcept {
        ContextType Ctx;
        ContextUpdate(Ctx, lpBuffer, cbBuffer);
        return Ctx;
    }

    static inline ContextType ContextCopy(const ContextType& Ctx) noexcept {
        return Ctx;
    }

    static inline void ContextUpdate(ContextType& Ctx, const void* lpBuffer, size_t cbBuffer) noexcept {
        Ctx.Value = RtlComputeCrc32(Ctx.Value, lpBuffer, cbBuffer);
    }

    static inline void ContextEvaluate(const ContextType& Ctx, DigestType& Digest) noexcept {
        Digest = Ctx.Value;
    }

    static inline void ContextDestroy(ContextType& Ctx) noexcept {
        Ctx.Value = 0;
    }
};

#endif  // #ifdef _MSC_VER


code:
#pragma once

#ifndef _WIN32
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/sha.h>

//ndef _WIN32
struct HasherSha1Traits {
public:
    static constexpr size_t BlockSize = 512 / 8;
    static constexpr size_t DigestSize = 160 / 8;

    struct DigestType {
        unsigned char Bytes[DigestSize];
    };

    using ContextType = SHA_CTX;

public:
    static inline ContextType ContextCreate() {
        ContextType Ctx;
        SHA1_Init(&Ctx);
        return Ctx;
    }

    static inline ContextType ContextCreate(const void* lpBuffer, size_t cbBuffer) {
        ContextType Ctx = ContextCreate();
        ContextUpdate(Ctx, lpBuffer, cbBuffer);
        return Ctx;
    }

    static inline ContextType ContextCopy(const ContextType& Ctx) {
        return Ctx;
    }

    static inline void ContextUpdate(ContextType& Ctx, const void* lpBuffer, size_t cbBuffer) {
        SHA1_Update(&Ctx, lpBuffer, cbBuffer);
    }

    static inline void ContextEvaluate(const ContextType& Ctx, DigestType& Digest) {
        auto ForkedCtx = ContextCopy(Ctx);
        SHA1_Final(Digest.Bytes, &ForkedCtx);
    }

    static inline void ContextDestroy(ContextType& Ctx) noexcept {
        OPENSSL_cleanse(&Ctx, sizeof(Ctx));
    }
};
#else
#include <windows.h>
#include <wincrypt.h>
#include <system_error>

struct HasherSha1Traits {
public:
    static constexpr size_t BlockSize = 512 / 8;
    static constexpr size_t DigestSize = 160 / 8;

    struct DigestType {
        BYTE Bytes[DigestSize];
    };

    struct ContextType {
        HCRYPTHASH hHash;

        ContextType() noexcept :
            hHash(NULL) {}

        ContextType(const ContextType& Other) noexcept = default;

        ContextType(ContextType&& Other) noexcept : hHash(Other.hHash) {
            Other.hHash = NULL;
        }

        ContextType& operator=(const ContextType& Other) noexcept = default;

        ContextType& operator=(ContextType&& Other) noexcept {
            hHash = Other.hHash;
            Other.hHash = NULL;
            return *this;
        }
    };

private:

    static inline struct ContextProvider {
        HCRYPTPROV Handle;

        ~ContextProvider() {
            if (Handle) {
                CryptReleaseContext(Handle, 0);
                Handle = NULL;
            }
        }
    } CryptProvider;

public:
    static inline ContextType ContextCreate() {
        ContextType Ctx;

        if (CryptProvider.Handle == NULL) {
            if (!CryptAcquireContext(&CryptProvider.Handle, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0)) {
                auto err = GetLastError();
                if (err == NTE_BAD_KEYSET) {
                    if (!CryptAcquireContext(&CryptProvider.Handle, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, CRYPT_NEWKEYSET)) {
                        err = GetLastError();
                        throw std::system_error(err, std::system_category());
                    }
                } else {
                    throw std::system_error(err, std::system_category());
                }
            }
        }

        if (!CryptCreateHash(CryptProvider.Handle, CALG_SHA1, NULL, 0, &Ctx.hHash)) {
            auto err = GetLastError();
            throw std::system_error(err, std::system_category());
        }

        return Ctx;
    }

    static inline ContextType ContextCreate(const void* lpBuffer, size_t cbBuffer) {
        ContextType Ctx = ContextCreate();
        ContextUpdate(Ctx, lpBuffer, cbBuffer);

        return Ctx;
    }

    static inline ContextType ContextCopy(const ContextType& Ctx) {
        ContextType NewCtx;
        if (!CryptDuplicateHash(Ctx.hHash, NULL, 0, &NewCtx.hHash)) {
            auto err = GetLastError();
            throw std::system_error(err, std::system_category());
        }
        return NewCtx;
    }

    static inline void ContextUpdate(ContextType& Ctx, const void* lpBuffer, size_t cbBuffer) {
        if constexpr (sizeof(size_t) <= sizeof(DWORD)) {
            if (!CryptHashData(Ctx.hHash, reinterpret_cast<const BYTE*>(lpBuffer), static_cast<DWORD>(cbBuffer), 0)) {
                auto err = GetLastError();
                throw std::system_error(err, std::system_category());
            }
        } else {
            size_t BytesRead = 0;
            DWORD BytesToRead = cbBuffer - BytesRead > MAXDWORD ? MAXDWORD : static_cast<DWORD>(cbBuffer - BytesRead);

            do {
                if (!CryptHashData(Ctx.hHash, reinterpret_cast<const BYTE*>(lpBuffer) + BytesRead, BytesToRead, 0)) {
                    auto err = GetLastError();
                    throw std::system_error(err, std::system_category());
                }
                BytesRead += BytesToRead;
                BytesToRead = cbBuffer - BytesRead > MAXDWORD ? MAXDWORD : static_cast<DWORD>(cbBuffer - BytesRead);
            } while (BytesToRead);
        }
    }

    static inline void ContextEvaluate(const ContextType& Ctx, DigestType& Digest) {
        DWORD SizeOfDigest = sizeof(Digest.Bytes);
        if (!CryptGetHashParam(Ctx.hHash, HP_HASHVAL, Digest.Bytes, &SizeOfDigest, 0)) {
            auto err = GetLastError();
            throw std::system_error(err, std::system_category());
        }
    }

    static inline void ContextDestroy(ContextType& Ctx) noexcept {
        if (Ctx.hHash) {
            CryptDestroyHash(Ctx.hHash);
            Ctx.hHash = NULL;
        }
    }
};
#endif


code:
CC := g++
UNAME := $(shell uname)

ifeq ($(UNAME), Darwin)
	OPENSSL_INCLUDE_PATH := /usr/local/opt/openssl@1.1/include
	OPENSSL_LIB_PATH := /usr/local/opt/openssl@1.1/lib
else
	OPENSSL_INCLUDE_PATH :=	# use system default
	OPENSSL_LIB_PATH := # use system default
endif
MPIR_INCLUDE_PATH := # use system default
MPIR_LIB_PATH := # use system default

OUTPUT_DIR := ./bin/

KEYGEN_HEADER := \
	BigInteger.hpp \
	EllipticCurveGF2m.hpp \
	GaloisField.hpp \
	Hasher.hpp \
	HasherCrc32Traits.hpp \
	HasherSha1Traits.hpp \
	WinRarConfig.hpp \
	WinRarKeygen.hpp
KEYGEN_SOURCE := \
	_tmain.cpp

KEYGEN_BINARY = $(OUTPUT_DIR)winrar-keygen

keygen: $(KEYGEM_HEADER) $(KEYGEN_SOURCE)
	@if [ ! -d $(OUTPUT_DIR) ]; then mkdir -p $(OUTPUT_DIR); fi
	$(CC) -std=c++17 -O2 \
$(if $(OPENSSL_INCLUDE_PATH),-I$(OPENSSL_INCLUDE_PATH),) $(if $(OPENSSL_LIB_PATH),-L$(OPENSSL_LIB_PATH),) \
$(if $(MPIR_INCLUDE_PATH),-I$(MPIR_INCLUDE_PATH),) $(if $(MPIR_LIB_PATH),-L$(MPIR_LIB_PATH),) \
$(KEYGEN_SOURCE) \
-o $(KEYGEN_BINARY) \
-lcrypto -lmpir
	@echo 'Done.'

.PHONY: keygen

clean:
ifeq ($(wildcard $(KEYGEN_BINARY)), $(KEYGEN_BINARY))
	rm $(KEYGEN_BINARY)
endif

path: Makefile


code:
# WinRAR-Keygen

[中文版README](README.zh-CN.md)

## 1. What is WinRAR?

WinRAR is a trialware file archiver utility for Windows, developed by Eugene Roshal of win.rar GmbH.

It can create and view archives in RAR or ZIP file formats and unpack numerous archive file formats.

WinRAR is not a free software. If you want to use it, you should pay to [__RARLAB__](https://rarlab.com/) and then you will get a license file named `rarreg.key`.

This repository will tell you how WinRAR license file `"rarreg.key"` is generated.

## 2. How is "rarreg.key" generated?

See [here](doc/how-does-it-work.md).

## 3. How to build?

This project supports both __Windows__ and __Linux/macOS__ platform.

To compile, see [here](doc/how-to-build.md).

PS: Thanks to Multi for providing unix support.

## 4. How to Use?

```
Usage:
        winrar-keygen.exe <your name> <license type>

Example:

        winrar-keygen.exe "Rebecca Morrison" "Single PC usage license"
  or:
        winrar-keygen.exe "Rebecca Morrison" "Single PC usage license" > rarreg.key
```

```console
$ winrar-keygen.exe "DoubleLabyrinth" "Single PC usage license"
RAR registration data
DoubleLabyrinth
Single PC usage license
UID=d2fb7cb15c078a3def58
6412212250ef58bef21cdcb49ca34b7040112cae5a512f1adad1a8
f6d2ee8c382fe64f8e3d6035c6ab9048e2c5c62f0238f183d28519
aa87488bf38f5b634cf28190bdf438ac593b1857cdb55a7fcb0eb0
c3e4c2736090b3dfa45384e08e9de05c5860d3051942adf2db9d96
e2ec37f1cfae00b3e2455093b90e4e352f016f6b9853c735d45fb4
01f9cbb91d3f3ac5664511229f8c9b0a9e1d61a2e087b481607e91
bfc8a83414f6807d31a5f8c587513aa54f9b1249ad804214409316
```


code:
# WinRAR-Keygen

## 1. WinRAR是什么？

WinRAR是一款用于管理压缩包文件的共享软件。其算法由作者尤金·罗谢尔研发，享有原创专利。

它可以用来创建或浏览RAR、ZIP等众多格式的压缩包。

WinRAR不是免费的软件。如果你想使用它，你应当向[__RARLAB__](https://rarlab.com/)付费，然后获得一个授权文件 `rarreg.key`。

这份repo将会告诉你 `rarreg.key` 是如何生成的。

## 2. "rarreg.key"是如何生成的？

见[这里](doc/how-does-it-work.zh-CN.md)。

## 3. 如何编译？

该项目支持 __Windows__ 和 __Linux/macOS__ 平台。

请见[这里](doc/how-to-build.zh-CN.md)来完成编译。

PS: 感谢Multi提供unix的支持。

## 4. 如何使用？

```
Usage:
        winrar-keygen.exe <your name> <license type>

Example:

        winrar-keygen.exe "Rebecca Morrison" "Single PC usage license"
  or:
        winrar-keygen.exe "Rebecca Morrison" "Single PC usage license" > rarreg.key
```

```console
$ winrar-keygen.exe "DoubleLabyrinth" "Single PC usage license"
RAR registration data
DoubleLabyrinth
Single PC usage license
UID=d2fb7cb15c078a3def58
6412212250ef58bef21cdcb49ca34b7040112cae5a512f1adad1a8
f6d2ee8c382fe64f8e3d6035c6ab9048e2c5c62f0238f183d28519
aa87488bf38f5b634cf28190bdf438ac593b1857cdb55a7fcb0eb0
c3e4c2736090b3dfa45384e08e9de05c5860d3051942adf2db9d96
e2ec37f1cfae00b3e2455093b90e4e352f016f6b9853c735d45fb4
01f9cbb91d3f3ac5664511229f8c9b0a9e1d61a2e087b481607e91
bfc8a83414f6807d31a5f8c587513aa54f9b1249ad804214409316
```