diff options
Diffstat (limited to 'lib/pure')
-rw-r--r-- | lib/pure/asyncdispatch.nim | 15 | ||||
-rw-r--r-- | lib/pure/asyncnet.nim | 2 | ||||
-rw-r--r-- | lib/pure/distros.nim | 244 | ||||
-rw-r--r-- | lib/pure/endians.nim | 113 | ||||
-rw-r--r-- | lib/pure/math.nim | 2 | ||||
-rw-r--r-- | lib/pure/os.nim | 2 | ||||
-rw-r--r-- | lib/pure/times.nim | 2 | ||||
-rw-r--r-- | lib/pure/xmldom.nim | 4 |
8 files changed, 346 insertions, 38 deletions
diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 1367bc411..b72596060 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -254,8 +254,14 @@ when defined(windows) or defined(nimdoc): "Operation performed on a socket which has not been registered with" & " the dispatcher yet.") + proc hasPendingOperations*(): bool = + ## Returns `true` if the global dispatcher has pending operations. + let p = getGlobalDispatcher() + p.handles.len != 0 or p.timers.len != 0 or p.callbacks.len != 0 + proc poll*(timeout = 500) = - ## Waits for completion events and processes them. + ## Waits for completion events and processes them. Raises ``ValueError`` + ## if there are no pending operations. let p = getGlobalDispatcher() if p.handles.len == 0 and p.timers.len == 0 and p.callbacks.len == 0: raise newException(ValueError, @@ -1056,8 +1062,15 @@ else: newCBs.add(cb) callbacks = newCBs & callbacks + proc hasPendingOperations*(): bool = + let p = getGlobalDispatcher() + p.selector.len != 0 or p.timers.len != 0 or p.callbacks.len != 0 + proc poll*(timeout = 500) = let p = getGlobalDispatcher() + if p.selector.len == 0 and p.timers.len == 0 and p.callbacks.len == 0: + raise newException(ValueError, + "No handles or timers registered in dispatcher.") if p.selector.len > 0: for info in p.selector.select(p.adjustedTimeout(timeout)): diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim index 3b64c278f..5ad3b5263 100644 --- a/lib/pure/asyncnet.nim +++ b/lib/pure/asyncnet.nim @@ -36,12 +36,14 @@ ## proc processClient(client: AsyncSocket) {.async.} = ## while true: ## let line = await client.recvLine() +## if line.len == 0: break ## for c in clients: ## await c.send(line & "\c\L") ## ## proc serve() {.async.} = ## clients = @[] ## var server = newAsyncSocket() +## server.setSockOpt(OptReuseAddr, true) ## server.bindAddr(Port(12345)) ## server.listen() ## diff --git a/lib/pure/distros.nim b/lib/pure/distros.nim new file mode 100644 index 000000000..ff30f6134 --- /dev/null +++ b/lib/pure/distros.nim @@ -0,0 +1,244 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2016 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## This module implements the basics for Linux distribution ("distro") +## detection and the OS's native package manager. Its primary purpose is to +## produce output for Nimble packages like:: +## +## To complete the installation, run: +## +## sudo apt-get libblas-dev +## sudo apt-get libvoodoo +## +## The above output could be the result of a code snippet like: +## +## .. code-block:: nim +## +## if detectOs(Ubuntu): +## foreignDep "lbiblas-dev" +## foreignDep "libvoodoo" +## + +from strutils import contains, toLowerAscii + +when not defined(nimscript): + from osproc import execProcess + +type + Distribution* {.pure.} = enum ## the list of known distributions + Windows ## some version of Windows + Posix ## some Posix system + MacOSX ## some version of OSX + Linux ## some version of Linux + Ubuntu + Debian + Gentoo + Fedora + RedHat + + OpenSUSE + Manjaro + Elementary + Zorin + CentOS + Deepin + ArchLinux + Antergos + PCLinuxOS + Mageia + LXLE + Solus + Lite + Slackware + Androidx86 + Puppy + Peppermint + Tails + AntiX + Kali + SparkyLinux + Apricity + BlackLab + Bodhi + TrueOS + ArchBang + KaOS + WattOS + Korora + Simplicity + RemixOS + OpenMandriva + Netrunner + Alpine + BlackArch + Ultimate + Gecko + Parrot + KNOPPIX + GhostBSD + Sabayon + Salix + Q4OS + ClearOS + Container + ROSA + Zenwalk + Parabola + ChaletOS + BackBox + MXLinux + Vector + Maui + Qubes + RancherOS + Oracle + TinyCore + Robolinux + Trisquel + Voyager + Clonezilla + SteamOS + Absolute + NixOS + AUSTRUMI + Arya + Porteus + AVLinux + Elive + Bluestar + SliTaz + Solaris + Chakra + Wifislax + Scientific + ExTiX + Rockstor + GoboLinux + + BSD + FreeBSD + OpenBSD + DragonFlyBSD + + +const + LacksDevPackages* = {Distribution.Gentoo, Distribution.Slackware, + Distribution.ArchLinux} + +var unameRes, releaseRes: string ## we cache the result of the 'uname -a' + ## execution for faster platform detections. + +template unameRelease(cmd, cache): untyped = + if cache.len == 0: + cache = (when defined(nimscript): gorge(cmd) else: execProcess(cmd)) + cache + +template uname(): untyped = unameRelease("uname -a", unameRes) +template release(): untyped = unameRelease("lsb_release -a", releaseRes) + +proc detectOsImpl(d: Distribution): bool = + case d + of Distribution.Windows: ## some version of Windows + result = defined(windows) + of Distribution.Posix: result = defined(posix) + of Distribution.MacOSX: result = defined(macosx) + of Distribution.Linux: result = defined(linux) + of Distribution.Ubuntu, Distribution.Gentoo, Distribution.FreeBSD, + Distribution.OpenBSD: + result = ("-" & $d & " ") in uname() + of Distribution.RedHat: + result = "Red Hat" in uname() + of Distribution.BSD: result = defined(bsd) + of Distribution.ArchLinux: + result = "arch" in toLowerAscii(uname()) + of Distribution.OpenSUSE: + result = "suse" in toLowerAscii(uname()) + of Distribution.GoboLinux: + result = "-Gobo " in uname() + of Distribution.OpenMandriva: + result = "mandriva" in toLowerAscii(uname()) + of Distribution.Solaris: + let uname = toLowerAscii(uname()) + result = ("sun" in uname) or ("solaris" in uname) + else: + let dd = toLowerAscii($d) + result = dd in toLowerAscii(uname()) or dd in toLowerAscii(release()) + +template detectOs*(d: untyped): bool = + ## Distro/OS detection. For convenience the + ## required ``Distribution.`` qualifier is added to the + ## enum value. + detectOsImpl(Distribution.d) + +when not defined(nimble): + var foreignDeps: seq[string] = @[] + +proc foreignCmd*(cmd: string; requiresSudo=false) = + ## Registers a foreign command to the intern list of commands + ## that can be queried later. + let c = (if requiresSudo: "sudo " else: "") & cmd + when defined(nimble): + nimscriptapi.foreignDeps.add(c) + else: + foreignDeps.add(c) + +proc foreignDepInstallCmd*(foreignPackageName: string): (string, bool) = + ## Returns the distro's native command line to install 'foreignPackageName' + ## and whether it requires root/admin rights. + let p = foreignPackageName + when defined(windows): + result = ("Chocolatey install " & p, false) + elif defined(bsd): + result = ("ports install " & p, true) + elif defined(linux): + if detectOs(Ubuntu) or detectOs(Elementary) or detectOs(Debian) or + detectOs(KNOPPIX) or detectOs(SteamOS): + result = ("apt-get install " & p, true) + elif detectOs(Gentoo): + result = ("emerge install " & p, true) + elif detectOs(Fedora): + result = ("yum install " & p, true) + elif detectOs(RedHat): + result = ("rpm install " & p, true) + elif detectOs(OpenSUSE): + result = ("yast -i " & p, true) + elif detectOs(Slackware): + result = ("installpkg " & p, true) + elif detectOs(OpenMandriva): + result = ("urpmi " & p, true) + elif detectOs(ZenWalk): + result = ("netpkg install " & p, true) + elif detectOs(NixOS): + result = ("nix-env -i " & p, false) + elif detectOs(Solaris): + result = ("pkg install " & p, true) + elif detectOs(PCLinuxOS): + result = ("rpm -ivh " & p, true) + elif detectOs(ArchLinux): + result = ("pacman -S " & p, true) + else: + result = ("<your package manager here> install " & p, true) + else: + result = ("brew install " & p, true) + +proc foreignDep*(foreignPackageName: string) = + ## Registers 'foreignPackageName' to the internal list of foreign deps. + ## It is your job to ensure the package name + let (installCmd, sudo) = foreignDepInstallCmd(foreignPackageName) + foreignCmd installCmd, sudo + +proc echoForeignDeps*() = + ## Writes the list of registered foreign deps to stdout. + for d in foreignDeps: + echo d + +when false: + foreignDep("libblas-dev") + foreignDep "libfoo" + echoForeignDeps() diff --git a/lib/pure/endians.nim b/lib/pure/endians.nim index 5a23169d4..6f80d56ef 100644 --- a/lib/pure/endians.nim +++ b/lib/pure/endians.nim @@ -10,38 +10,87 @@ ## This module contains helpers that deal with different byte orders ## (`endian`:idx:). -proc swapEndian64*(outp, inp: pointer) = - ## copies `inp` to `outp` swapping bytes. Both buffers are supposed to - ## contain at least 8 bytes. - var i = cast[cstring](inp) - var o = cast[cstring](outp) - o[0] = i[7] - o[1] = i[6] - o[2] = i[5] - o[3] = i[4] - o[4] = i[3] - o[5] = i[2] - o[6] = i[1] - o[7] = i[0] - -proc swapEndian32*(outp, inp: pointer) = - ## copies `inp` to `outp` swapping bytes. Both buffers are supposed to - ## contain at least 4 bytes. - var i = cast[cstring](inp) - var o = cast[cstring](outp) - o[0] = i[3] - o[1] = i[2] - o[2] = i[1] - o[3] = i[0] - -proc swapEndian16*(outp, inp: pointer) = - ## copies `inp` to `outp` swapping bytes. Both buffers are supposed to - ## contain at least 2 bytes. - var - i = cast[cstring](inp) - o = cast[cstring](outp) - o[0] = i[1] - o[1] = i[0] +when defined(gcc) or defined(llvm_gcc) or defined(clang): + const useBuiltinSwap = true + proc builtin_bswap16(a: uint16): uint16 {. + importc: "__builtin_bswap16", nodecl, nosideeffect.} + + proc builtin_bswap32(a: uint32): uint32 {. + importc: "__builtin_bswap32", nodecl, nosideeffect.} + + proc builtin_bswap64(a: uint64): uint64 {. + importc: "__builtin_bswap64", nodecl, nosideeffect.} +elif defined(icc): + const useBuiltinSwap = true + proc builtin_bswap16(a: uint16): uint16 {. + importc: "_bswap16", nodecl, nosideeffect.} + + proc builtin_bswap32(a: uint32): uint32 {. + importc: "_bswap", nodecl, nosideeffect.} + + proc builtin_bswap64(a: uint64): uint64 {. + importc: "_bswap64", nodecl, nosideeffect.} +elif defined(vcc): + const useBuiltinSwap = true + proc builtin_bswap16(a: uint16): uint16 {. + importc: "_byteswap_ushort", nodecl, header: "<intrin.h>", nosideeffect.} + + proc builtin_bswap32(a: uint32): uint32 {. + importc: "_byteswap_ulong", nodecl, header: "<intrin.h>", nosideeffect.} + + proc builtin_bswap64(a: uint64): uint64 {. + importc: "_byteswap_uint64", nodecl, header: "<intrin.h>", nosideeffect.} +else: + const useBuiltinSwap = false + +when useBuiltinSwap: + proc swapEndian64*(outp, inp: pointer) {.inline, nosideeffect.}= + var i = cast[ptr uint64](inp) + var o = cast[ptr uint64](outp) + o[] = builtin_bswap64(i[]) + + proc swapEndian32*(outp, inp: pointer) {.inline, nosideeffect.}= + var i = cast[ptr uint32](inp) + var o = cast[ptr uint32](outp) + o[] = builtin_bswap32(i[]) + + proc swapEndian16*(outp, inp: pointer) {.inline, nosideeffect.}= + var i = cast[ptr uint16](inp) + var o = cast[ptr uint16](outp) + o[] = builtin_bswap16(i[]) + +else: + proc swapEndian64*(outp, inp: pointer) = + ## copies `inp` to `outp` swapping bytes. Both buffers are supposed to + ## contain at least 8 bytes. + var i = cast[cstring](inp) + var o = cast[cstring](outp) + o[0] = i[7] + o[1] = i[6] + o[2] = i[5] + o[3] = i[4] + o[4] = i[3] + o[5] = i[2] + o[6] = i[1] + o[7] = i[0] + + proc swapEndian32*(outp, inp: pointer) = + ## copies `inp` to `outp` swapping bytes. Both buffers are supposed to + ## contain at least 4 bytes. + var i = cast[cstring](inp) + var o = cast[cstring](outp) + o[0] = i[3] + o[1] = i[2] + o[2] = i[1] + o[3] = i[0] + + proc swapEndian16*(outp, inp: pointer) = + ## copies `inp` to `outp` swapping bytes. Both buffers are supposed to + ## contain at least 2 bytes. + var i = cast[cstring](inp) + var o = cast[cstring](outp) + o[0] = i[1] + o[1] = i[0] when system.cpuEndian == bigEndian: proc littleEndian64*(outp, inp: pointer) {.inline.} = swapEndian64(outp, inp) diff --git a/lib/pure/math.nim b/lib/pure/math.nim index 4ef169b4f..a8432b6f0 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -213,7 +213,7 @@ when not defined(JS): ## .. code-block:: nim ## echo ceil(-2.1) ## -2.0 - when defined(windows) and defined(vcc): + when defined(windows) and (defined(vcc) or defined(bcc)): # MSVC 2010 don't have trunc/truncf # this implementation was inspired by Go-lang Math.Trunc proc truncImpl(f: float64): float64 = diff --git a/lib/pure/os.nim b/lib/pure/os.nim index f077e798a..8a5461567 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -1427,7 +1427,7 @@ elif defined(windows): if isNil(ownArgv): ownArgv = parseCmdLine($getCommandLine()) return TaintedString(ownArgv[i]) -elif not defined(createNimRtl): +elif not defined(createNimRtl) and not(defined(posix) and appType == "lib"): # On Posix, there is no portable way to get the command line from a DLL. var cmdCount {.importc: "cmdCount".}: cint diff --git a/lib/pure/times.nim b/lib/pure/times.nim index 99fdb5b0e..39d46c675 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -70,7 +70,7 @@ when defined(posix) and not defined(JS): elif defined(windows): import winlean - when defined(vcc): + when defined(vcc) or defined(bcc): # newest version of Visual C++ defines time_t to be of 64 bits type TimeImpl {.importc: "time_t", header: "<time.h>".} = int64 # visual c's c runtime exposes these under a different name diff --git a/lib/pure/xmldom.nim b/lib/pure/xmldom.nim index 559f45348..3c891c81b 100644 --- a/lib/pure/xmldom.nim +++ b/lib/pure/xmldom.nim @@ -890,7 +890,7 @@ proc tagName*(el: PElement): string = return el.fTagName # Procedures -proc getAttribute*(el: PElement, name: string): string = +proc getAttribute*(el: PNode, name: string): string = ## Retrieves an attribute value by ``name`` if isNil(el.attributes): return nil @@ -900,7 +900,7 @@ proc getAttribute*(el: PElement, name: string): string = else: return nil -proc getAttributeNS*(el: PElement, namespaceURI: string, localName: string): string = +proc getAttributeNS*(el: PNode, namespaceURI: string, localName: string): string = ## Retrieves an attribute value by ``localName`` and ``namespaceURI`` if isNil(el.attributes): return nil |