mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-19 07:21:19 +00:00
lib/pure/e-o - Dropped 'T' from types
This commit is contained in:
@@ -211,12 +211,13 @@ when defined(windows):
|
||||
when false:
|
||||
# not needed yet:
|
||||
type
|
||||
TCpInfo = object
|
||||
CpInfo = object
|
||||
maxCharSize: int32
|
||||
defaultChar: array[0..1, char]
|
||||
leadByte: array[0..12-1, char]
|
||||
{.deprecated: [TCpInfo: CpInfo].}
|
||||
|
||||
proc getCPInfo(codePage: CodePage, lpCPInfo: var TCpInfo): int32 {.
|
||||
proc getCPInfo(codePage: CodePage, lpCPInfo: var CpInfo): int32 {.
|
||||
stdcall, importc: "GetCPInfo", dynlib: "kernel32".}
|
||||
|
||||
proc nameToCodePage(name: string): CodePage =
|
||||
|
||||
@@ -18,20 +18,22 @@ import
|
||||
os, hashes, strutils
|
||||
|
||||
type
|
||||
TGenTableMode* = enum ## describes the table's key matching mode
|
||||
GenTableMode* = enum ## describes the table's key matching mode
|
||||
modeCaseSensitive, ## case sensitive matching of keys
|
||||
modeCaseInsensitive, ## case insensitive matching of keys
|
||||
modeStyleInsensitive ## style sensitive matching of keys
|
||||
|
||||
TGenKeyValuePair[T] = tuple[key: string, val: T]
|
||||
TGenKeyValuePairSeq[T] = seq[TGenKeyValuePair[T]]
|
||||
TGenTable*[T] = object of RootObj
|
||||
GenKeyValuePair[T] = tuple[key: string, val: T]
|
||||
GenKeyValuePairSeq[T] = seq[GenKeyValuePair[T]]
|
||||
GenTable*[T] = object of RootObj
|
||||
counter: int
|
||||
data: TGenKeyValuePairSeq[T]
|
||||
mode: TGenTableMode
|
||||
data: GenKeyValuePairSeq[T]
|
||||
mode: GenTableMode
|
||||
|
||||
PGenTable*[T] = ref TGenTable[T] ## use this type to declare hash tables
|
||||
PGenTable*[T] = ref GenTable[T] ## use this type to declare hash tables
|
||||
|
||||
{.deprecated: [TGenTableMode: GenTableMode, TGenKeyValuePair: GenKeyValuePair,
|
||||
TGenKeyValuePairSeq: GenKeyValuePairSeq, TGenTable: GenTable].}
|
||||
|
||||
const
|
||||
growthFactor = 2
|
||||
@@ -48,7 +50,7 @@ iterator pairs*[T](tbl: PGenTable[T]): tuple[key: string, value: T] =
|
||||
if not isNil(tbl.data[h].key):
|
||||
yield (tbl.data[h].key, tbl.data[h].val)
|
||||
|
||||
proc myhash[T](tbl: PGenTable[T], key: string): THash =
|
||||
proc myhash[T](tbl: PGenTable[T], key: string): Hash =
|
||||
case tbl.mode
|
||||
of modeCaseSensitive: result = hashes.hash(key)
|
||||
of modeCaseInsensitive: result = hashes.hashIgnoreCase(key)
|
||||
@@ -64,18 +66,18 @@ proc mustRehash(length, counter: int): bool =
|
||||
assert(length > counter)
|
||||
result = (length * 2 < counter * 3) or (length - counter < 4)
|
||||
|
||||
proc newGenTable*[T](mode: TGenTableMode): PGenTable[T] =
|
||||
proc newGenTable*[T](mode: GenTableMode): PGenTable[T] =
|
||||
## creates a new generic hash table that is empty.
|
||||
new(result)
|
||||
result.mode = mode
|
||||
result.counter = 0
|
||||
newSeq(result.data, startSize)
|
||||
|
||||
proc nextTry(h, maxHash: THash): THash {.inline.} =
|
||||
proc nextTry(h, maxHash: Hash): Hash {.inline.} =
|
||||
result = ((5 * h) + 1) and maxHash
|
||||
|
||||
proc rawGet[T](tbl: PGenTable[T], key: string): int =
|
||||
var h: THash
|
||||
var h: Hash
|
||||
h = myhash(tbl, key) and high(tbl.data) # start with real hash value
|
||||
while not isNil(tbl.data[h].key):
|
||||
if myCmp(tbl, tbl.data[h].key, key):
|
||||
@@ -83,9 +85,9 @@ proc rawGet[T](tbl: PGenTable[T], key: string): int =
|
||||
h = nextTry(h, high(tbl.data))
|
||||
result = - 1
|
||||
|
||||
proc rawInsert[T](tbl: PGenTable[T], data: var TGenKeyValuePairSeq[T],
|
||||
proc rawInsert[T](tbl: PGenTable[T], data: var GenKeyValuePairSeq[T],
|
||||
key: string, val: T) =
|
||||
var h: THash
|
||||
var h: Hash
|
||||
h = myhash(tbl, key) and high(data)
|
||||
while not isNil(data[h].key):
|
||||
h = nextTry(h, high(data))
|
||||
@@ -93,7 +95,7 @@ proc rawInsert[T](tbl: PGenTable[T], data: var TGenKeyValuePairSeq[T],
|
||||
data[h].val = val
|
||||
|
||||
proc enlarge[T](tbl: PGenTable[T]) =
|
||||
var n: TGenKeyValuePairSeq[T]
|
||||
var n: GenKeyValuePairSeq[T]
|
||||
newSeq(n, len(tbl.data) * growthFactor)
|
||||
for i in countup(0, high(tbl.data)):
|
||||
if not isNil(tbl.data[i].key):
|
||||
@@ -146,19 +148,20 @@ when isMainModule:
|
||||
# Verify a table of user-defined types
|
||||
#
|
||||
type
|
||||
TMyType = tuple[first, second: string] # a pair of strings
|
||||
MyType = tuple[first, second: string] # a pair of strings
|
||||
{.deprecated: [TMyType: MyType].}
|
||||
|
||||
var y = newGenTable[TMyType](modeCaseInsensitive) # hash table where each
|
||||
# value is TMyType tuple
|
||||
var y = newGenTable[MyType](modeCaseInsensitive) # hash table where each
|
||||
# value is MyType tuple
|
||||
|
||||
#var junk: TMyType = ("OK", "Here")
|
||||
#var junk: MyType = ("OK", "Here")
|
||||
|
||||
#echo junk.first, " ", junk.second
|
||||
|
||||
y["Hello"] = ("Hello", "World")
|
||||
y["Goodbye"] = ("Goodbye", "Everyone")
|
||||
#y["Hello"] = TMyType( ("Hello", "World") )
|
||||
#y["Goodbye"] = TMyType( ("Goodbye", "Everyone") )
|
||||
#y["Hello"] = MyType( ("Hello", "World") )
|
||||
#y["Goodbye"] = MyType( ("Goodbye", "Everyone") )
|
||||
|
||||
assert( not isNil(y["Hello"].first) )
|
||||
assert( y["Hello"].first == "Hello" )
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
## code:
|
||||
##
|
||||
## .. code-block:: Nim
|
||||
## proc hash(x: Something): THash =
|
||||
## ## Computes a THash from `x`.
|
||||
## var h: THash = 0
|
||||
## proc hash(x: Something): Hash =
|
||||
## ## Computes a Hash from `x`.
|
||||
## var h: Hash = 0
|
||||
## # Iterate over parts of `x`.
|
||||
## for xAtom in x:
|
||||
## # Mix the atom with the partial hash.
|
||||
@@ -30,9 +30,9 @@
|
||||
## together the hash value of the individual fields:
|
||||
##
|
||||
## .. code-block:: Nim
|
||||
## proc hash(x: Something): THash =
|
||||
## ## Computes a THash from `x`.
|
||||
## var h: THash = 0
|
||||
## proc hash(x: Something): Hash =
|
||||
## ## Computes a Hash from `x`.
|
||||
## var h: Hash = 0
|
||||
## h = h !& hash(x.foo)
|
||||
## h = h !& hash(x.bar)
|
||||
## result = !$h
|
||||
@@ -41,27 +41,28 @@ import
|
||||
strutils, etcpriv
|
||||
|
||||
type
|
||||
THash* = int ## a hash value; hash tables using these values should
|
||||
Hash* = int ## a hash value; hash tables using these values should
|
||||
## always have a size of a power of two and can use the ``and``
|
||||
## operator instead of ``mod`` for truncation of the hash value.
|
||||
{.deprecated: [THash: Hash].}
|
||||
|
||||
proc `!&`*(h: THash, val: int): THash {.inline.} =
|
||||
proc `!&`*(h: Hash, val: int): Hash {.inline.} =
|
||||
## mixes a hash value `h` with `val` to produce a new hash value. This is
|
||||
## only needed if you need to implement a hash proc for a new datatype.
|
||||
result = h +% val
|
||||
result = result +% result shl 10
|
||||
result = result xor (result shr 6)
|
||||
|
||||
proc `!$`*(h: THash): THash {.inline.} =
|
||||
proc `!$`*(h: Hash): Hash {.inline.} =
|
||||
## finishes the computation of the hash value. This is
|
||||
## only needed if you need to implement a hash proc for a new datatype.
|
||||
result = h +% h shl 3
|
||||
result = result xor (result shr 11)
|
||||
result = result +% result shl 15
|
||||
|
||||
proc hashData*(data: pointer, size: int): THash =
|
||||
proc hashData*(data: pointer, size: int): Hash =
|
||||
## hashes an array of bytes of size `size`
|
||||
var h: THash = 0
|
||||
var h: Hash = 0
|
||||
when defined(js):
|
||||
var p: cstring
|
||||
asm """`p` = `Data`;"""
|
||||
@@ -78,7 +79,7 @@ proc hashData*(data: pointer, size: int): THash =
|
||||
when defined(js):
|
||||
var objectID = 0
|
||||
|
||||
proc hash*(x: pointer): THash {.inline.} =
|
||||
proc hash*(x: pointer): Hash {.inline.} =
|
||||
## efficient hashing of pointers
|
||||
when defined(js):
|
||||
asm """
|
||||
@@ -92,38 +93,38 @@ proc hash*(x: pointer): THash {.inline.} =
|
||||
}
|
||||
"""
|
||||
else:
|
||||
result = (cast[THash](x)) shr 3 # skip the alignment
|
||||
result = (cast[Hash](x)) shr 3 # skip the alignment
|
||||
|
||||
when not defined(booting):
|
||||
proc hash*[T: proc](x: T): THash {.inline.} =
|
||||
proc hash*[T: proc](x: T): Hash {.inline.} =
|
||||
## efficient hashing of proc vars; closures are supported too.
|
||||
when T is "closure":
|
||||
result = hash(rawProc(x)) !& hash(rawEnv(x))
|
||||
else:
|
||||
result = hash(pointer(x))
|
||||
|
||||
proc hash*(x: int): THash {.inline.} =
|
||||
proc hash*(x: int): Hash {.inline.} =
|
||||
## efficient hashing of integers
|
||||
result = x
|
||||
|
||||
proc hash*(x: int64): THash {.inline.} =
|
||||
proc hash*(x: int64): Hash {.inline.} =
|
||||
## efficient hashing of integers
|
||||
result = toU32(x)
|
||||
|
||||
proc hash*(x: char): THash {.inline.} =
|
||||
proc hash*(x: char): Hash {.inline.} =
|
||||
## efficient hashing of characters
|
||||
result = ord(x)
|
||||
|
||||
proc hash*(x: string): THash =
|
||||
proc hash*(x: string): Hash =
|
||||
## efficient hashing of strings
|
||||
var h: THash = 0
|
||||
var h: Hash = 0
|
||||
for i in 0..x.len-1:
|
||||
h = h !& ord(x[i])
|
||||
result = !$h
|
||||
|
||||
proc hashIgnoreStyle*(x: string): THash =
|
||||
proc hashIgnoreStyle*(x: string): Hash =
|
||||
## efficient hashing of strings; style is ignored
|
||||
var h: THash = 0
|
||||
var h: Hash = 0
|
||||
var i = 0
|
||||
let xLen = x.len
|
||||
while i < xLen:
|
||||
@@ -140,9 +141,9 @@ proc hashIgnoreStyle*(x: string): THash =
|
||||
|
||||
result = !$h
|
||||
|
||||
proc hashIgnoreCase*(x: string): THash =
|
||||
proc hashIgnoreCase*(x: string): Hash =
|
||||
## efficient hashing of strings; case is ignored
|
||||
var h: THash = 0
|
||||
var h: Hash = 0
|
||||
for i in 0..x.len-1:
|
||||
var c = x[i]
|
||||
if c in {'A'..'Z'}:
|
||||
@@ -150,28 +151,28 @@ proc hashIgnoreCase*(x: string): THash =
|
||||
h = h !& ord(c)
|
||||
result = !$h
|
||||
|
||||
proc hash*(x: float): THash {.inline.} =
|
||||
proc hash*(x: float): Hash {.inline.} =
|
||||
var y = x + 1.0
|
||||
result = cast[ptr THash](addr(y))[]
|
||||
result = cast[ptr Hash](addr(y))[]
|
||||
|
||||
|
||||
# Forward declarations before methods that hash containers. This allows
|
||||
# containers to contain other containers
|
||||
proc hash*[A](x: openArray[A]): THash
|
||||
proc hash*[A](x: set[A]): THash
|
||||
proc hash*[A](x: openArray[A]): Hash
|
||||
proc hash*[A](x: set[A]): Hash
|
||||
|
||||
|
||||
proc hash*[T: tuple](x: T): THash =
|
||||
proc hash*[T: tuple](x: T): Hash =
|
||||
## efficient hashing of tuples.
|
||||
for f in fields(x):
|
||||
result = result !& hash(f)
|
||||
result = !$result
|
||||
|
||||
proc hash*[A](x: openArray[A]): THash =
|
||||
proc hash*[A](x: openArray[A]): Hash =
|
||||
for it in items(x): result = result !& hash(it)
|
||||
result = !$result
|
||||
|
||||
proc hash*[A](x: set[A]): THash =
|
||||
proc hash*[A](x: set[A]): Hash =
|
||||
for it in items(x): result = result !& hash(it)
|
||||
result = !$result
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
import strutils, streams, parsexml, xmltree, unicode, strtabs
|
||||
|
||||
type
|
||||
THtmlTag* = enum ## list of all supported HTML tags; order will always be
|
||||
HtmlTag* = enum ## list of all supported HTML tags; order will always be
|
||||
## alphabetically
|
||||
tagUnknown, ## unknown HTML element
|
||||
tagA, ## the HTML ``a`` element
|
||||
@@ -178,6 +178,7 @@ type
|
||||
tagVar, ## the HTML ``var`` element
|
||||
tagVideo, ## the HTML ``video`` element
|
||||
tagWbr ## the HTML ``wbr`` element
|
||||
{.deprecated: [THtmlTag: HtmlTag].}
|
||||
|
||||
const
|
||||
tagToStr* = [
|
||||
@@ -295,7 +296,7 @@ proc allLower(s: string): bool =
|
||||
if c < 'a' or c > 'z': return false
|
||||
return true
|
||||
|
||||
proc toHtmlTag(s: string): THtmlTag =
|
||||
proc toHtmlTag(s: string): HtmlTag =
|
||||
case s
|
||||
of "a": tagA
|
||||
of "abbr": tagAbbr
|
||||
@@ -422,14 +423,14 @@ proc toHtmlTag(s: string): THtmlTag =
|
||||
of "wbr": tagWbr
|
||||
else: tagUnknown
|
||||
|
||||
proc htmlTag*(n: XmlNode): THtmlTag =
|
||||
## gets `n`'s tag as a ``THtmlTag``.
|
||||
proc htmlTag*(n: XmlNode): HtmlTag =
|
||||
## gets `n`'s tag as a ``HtmlTag``.
|
||||
if n.clientData == 0:
|
||||
n.clientData = toHtmlTag(n.tag).ord
|
||||
result = THtmlTag(n.clientData)
|
||||
result = HtmlTag(n.clientData)
|
||||
|
||||
proc htmlTag*(s: string): THtmlTag =
|
||||
## converts `s` to a ``THtmlTag``. If `s` is no HTML tag, ``tagUnknown`` is
|
||||
proc htmlTag*(s: string): HtmlTag =
|
||||
## converts `s` to a ``HtmlTag``. If `s` is no HTML tag, ``tagUnknown`` is
|
||||
## returned.
|
||||
let s = if allLower(s): s else: s.toLower
|
||||
result = toHtmlTag(s)
|
||||
|
||||
@@ -106,9 +106,10 @@ proc serveFile*(client: Socket, filename: string) =
|
||||
when false:
|
||||
# TODO: Fix this, or get rid of it.
|
||||
type
|
||||
TRequestMethod = enum reqGet, reqPost
|
||||
RequestMethod = enum reqGet, reqPost
|
||||
{.deprecated: [TRequestMethod: RequestMethod].}
|
||||
|
||||
proc executeCgi(client: Socket, path, query: string, meth: TRequestMethod) =
|
||||
proc executeCgi(client: Socket, path, query: string, meth: RequestMethod) =
|
||||
var env = newStringTable(modeCaseInsensitive)
|
||||
var contentLength = -1
|
||||
case meth
|
||||
@@ -208,7 +209,7 @@ when false:
|
||||
executeCgi(client, path, query, meth)
|
||||
|
||||
type
|
||||
TServer* = object of RootObj ## contains the current server state
|
||||
Server* = object of RootObj ## contains the current server state
|
||||
socket: Socket
|
||||
port: Port
|
||||
client*: Socket ## the socket to write the file data to
|
||||
@@ -218,11 +219,12 @@ type
|
||||
body*: string ## only set with POST requests
|
||||
ip*: string ## ip address of the requesting client
|
||||
|
||||
PAsyncHTTPServer* = ref TAsyncHTTPServer
|
||||
TAsyncHTTPServer = object of TServer
|
||||
PAsyncHTTPServer* = ref AsyncHTTPServer
|
||||
AsyncHTTPServer = object of Server
|
||||
asyncSocket: AsyncSocket
|
||||
{.deprecated: [TAsyncHTTPServer: AsyncHTTPServer, TServer: Server].}
|
||||
|
||||
proc open*(s: var TServer, port = Port(80), reuseAddr = false) =
|
||||
proc open*(s: var Server, port = Port(80), reuseAddr = false) =
|
||||
## creates a new server at port `port`. If ``port == 0`` a free port is
|
||||
## acquired that can be accessed later by the ``port`` proc.
|
||||
s.socket = socket(AF_INET)
|
||||
@@ -243,11 +245,11 @@ proc open*(s: var TServer, port = Port(80), reuseAddr = false) =
|
||||
s.query = ""
|
||||
s.headers = {:}.newStringTable()
|
||||
|
||||
proc port*(s: var TServer): Port =
|
||||
proc port*(s: var Server): Port =
|
||||
## get the port number the server has acquired.
|
||||
result = s.port
|
||||
|
||||
proc next*(s: var TServer) =
|
||||
proc next*(s: var Server) =
|
||||
## proceed to the first/next request.
|
||||
var client: Socket
|
||||
new(client)
|
||||
@@ -354,7 +356,7 @@ proc next*(s: var TServer) =
|
||||
s.query = ""
|
||||
s.path = data.substr(i, last-1)
|
||||
|
||||
proc close*(s: TServer) =
|
||||
proc close*(s: Server) =
|
||||
## closes the server (and the socket the server uses).
|
||||
close(s.socket)
|
||||
|
||||
@@ -362,7 +364,7 @@ proc run*(handleRequest: proc (client: Socket,
|
||||
path, query: string): bool {.closure.},
|
||||
port = Port(80)) =
|
||||
## encapsulates the server object and main loop
|
||||
var s: TServer
|
||||
var s: Server
|
||||
open(s, port, reuseAddr = true)
|
||||
#echo("httpserver running on port ", s.port)
|
||||
while true:
|
||||
@@ -517,7 +519,7 @@ proc close*(h: PAsyncHTTPServer) =
|
||||
when not defined(testing) and isMainModule:
|
||||
var counter = 0
|
||||
|
||||
var s: TServer
|
||||
var s: Server
|
||||
open(s, Port(0))
|
||||
echo("httpserver running on port ", s.port)
|
||||
while true:
|
||||
|
||||
@@ -68,7 +68,7 @@ type
|
||||
jsonArrayStart, ## start of an array: the ``[`` token
|
||||
jsonArrayEnd ## start of an array: the ``]`` token
|
||||
|
||||
TTokKind = enum # must be synchronized with TJsonEventKind!
|
||||
TokKind = enum # must be synchronized with TJsonEventKind!
|
||||
tkError,
|
||||
tkEof,
|
||||
tkString,
|
||||
@@ -103,14 +103,14 @@ type
|
||||
|
||||
JsonParser* = object of BaseLexer ## the parser object.
|
||||
a: string
|
||||
tok: TTokKind
|
||||
tok: TokKind
|
||||
kind: JsonEventKind
|
||||
err: JsonError
|
||||
state: seq[ParserState]
|
||||
filename: string
|
||||
|
||||
{.deprecated: [TJsonEventKind: JsonEventKind, TJsonError: JsonError,
|
||||
TJsonParser: JsonParser].}
|
||||
TJsonParser: JsonParser, TTokKind: TokKind].}
|
||||
|
||||
const
|
||||
errorMessages: array [JsonError, string] = [
|
||||
@@ -126,7 +126,7 @@ const
|
||||
"EOF expected",
|
||||
"expression expected"
|
||||
]
|
||||
tokToStr: array [TTokKind, string] = [
|
||||
tokToStr: array [TokKind, string] = [
|
||||
"invalid token",
|
||||
"EOF",
|
||||
"string literal",
|
||||
@@ -203,7 +203,7 @@ proc handleHexChar(c: char, x: var int): bool =
|
||||
of 'A'..'F': x = (x shl 4) or (ord(c) - ord('A') + 10)
|
||||
else: result = false # error
|
||||
|
||||
proc parseString(my: var JsonParser): TTokKind =
|
||||
proc parseString(my: var JsonParser): TokKind =
|
||||
result = tkString
|
||||
var pos = my.bufpos + 1
|
||||
var buf = my.buf
|
||||
@@ -359,7 +359,7 @@ proc parseName(my: var JsonParser) =
|
||||
inc(pos)
|
||||
my.bufpos = pos
|
||||
|
||||
proc getTok(my: var JsonParser): TTokKind =
|
||||
proc getTok(my: var JsonParser): TokKind =
|
||||
setLen(my.a, 0)
|
||||
skip(my) # skip whitespace, comments
|
||||
case my.buf[my.bufpos]
|
||||
@@ -734,7 +734,7 @@ proc `==`* (a,b: JsonNode): bool =
|
||||
of JObject:
|
||||
a.fields == b.fields
|
||||
|
||||
proc hash* (n:JsonNode): THash =
|
||||
proc hash* (n:JsonNode): Hash =
|
||||
## Compute the hash for a JSON node
|
||||
case n.kind
|
||||
of JArray:
|
||||
@@ -1016,7 +1016,7 @@ iterator mpairs*(node: var JsonNode): var tuple[key: string, val: JsonNode] =
|
||||
for keyVal in mitems(node.fields):
|
||||
yield keyVal
|
||||
|
||||
proc eat(p: var JsonParser, tok: TTokKind) =
|
||||
proc eat(p: var JsonParser, tok: TokKind) =
|
||||
if p.tok == tok: discard getTok(p)
|
||||
else: raiseParseErr(p, tokToStr[tok])
|
||||
|
||||
@@ -1091,8 +1091,10 @@ when not defined(js):
|
||||
else:
|
||||
from math import `mod`
|
||||
type
|
||||
TJSObject = object
|
||||
proc parseNativeJson(x: cstring): TJSObject {.importc: "JSON.parse".}
|
||||
JSObject = object
|
||||
{.deprecated: [TJSObject: JSObject].}
|
||||
|
||||
proc parseNativeJson(x: cstring): JSObject {.importc: "JSON.parse".}
|
||||
|
||||
proc getVarType(x): JsonNodeKind =
|
||||
result = JNull
|
||||
@@ -1111,25 +1113,25 @@ else:
|
||||
of "[object String]": return JString
|
||||
else: assert false
|
||||
|
||||
proc len(x: TJSObject): int =
|
||||
proc len(x: JSObject): int =
|
||||
assert x.getVarType == JArray
|
||||
asm """
|
||||
return `x`.length;
|
||||
"""
|
||||
|
||||
proc `[]`(x: TJSObject, y: string): TJSObject =
|
||||
proc `[]`(x: JSObject, y: string): JSObject =
|
||||
assert x.getVarType == JObject
|
||||
asm """
|
||||
return `x`[`y`];
|
||||
"""
|
||||
|
||||
proc `[]`(x: TJSObject, y: int): TJSObject =
|
||||
proc `[]`(x: JSObject, y: int): JSObject =
|
||||
assert x.getVarType == JArray
|
||||
asm """
|
||||
return `x`[`y`];
|
||||
"""
|
||||
|
||||
proc convertObject(x: TJSObject): JsonNode =
|
||||
proc convertObject(x: JSObject): JsonNode =
|
||||
case getVarType(x)
|
||||
of JArray:
|
||||
result = newJArray()
|
||||
@@ -1141,7 +1143,7 @@ else:
|
||||
if (`x`.hasOwnProperty(property)) {
|
||||
"""
|
||||
var nimProperty: cstring
|
||||
var nimValue: TJSObject
|
||||
var nimValue: JSObject
|
||||
asm "`nimProperty` = property; `nimValue` = `x`[property];"
|
||||
result[$nimProperty] = nimValue.convertObject()
|
||||
asm "}}"
|
||||
|
||||
@@ -39,7 +39,7 @@ type
|
||||
{.deprecated: [TBaseLexer: BaseLexer].}
|
||||
|
||||
proc open*(L: var BaseLexer, input: Stream, bufLen: int = 8192)
|
||||
## inits the TBaseLexer with a stream to read from
|
||||
## inits the BaseLexer with a stream to read from
|
||||
|
||||
proc close*(L: var BaseLexer)
|
||||
## closes the base lexer. This closes `L`'s associated stream too.
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
## .. code-block:: nim
|
||||
##
|
||||
## type
|
||||
## TA = object
|
||||
## TB = object of TA
|
||||
## A = object
|
||||
## B = object of A
|
||||
## f: int
|
||||
##
|
||||
## var
|
||||
## a: ref TA
|
||||
## b: ref TB
|
||||
## a: ref A
|
||||
## b: ref B
|
||||
##
|
||||
## new(b)
|
||||
## a = b
|
||||
@@ -36,7 +36,7 @@ import streams, typeinfo, json, intsets, tables
|
||||
proc ptrToInt(x: pointer): int {.inline.} =
|
||||
result = cast[int](x) # don't skip alignment
|
||||
|
||||
proc storeAny(s: Stream, a: TAny, stored: var IntSet) =
|
||||
proc storeAny(s: Stream, a: Any, stored: var IntSet) =
|
||||
case a.kind
|
||||
of akNone: assert false
|
||||
of akBool: s.write($getBool(a))
|
||||
@@ -96,7 +96,7 @@ proc storeAny(s: Stream, a: TAny, stored: var IntSet) =
|
||||
of akInt..akInt64, akUInt..akUInt64: s.write($getBiggestInt(a))
|
||||
of akFloat..akFloat128: s.write($getBiggestFloat(a))
|
||||
|
||||
proc loadAny(p: var JsonParser, a: TAny, t: var Table[BiggestInt, pointer]) =
|
||||
proc loadAny(p: var JsonParser, a: Any, t: var Table[BiggestInt, pointer]) =
|
||||
case a.kind
|
||||
of akNone: assert false
|
||||
of akBool:
|
||||
@@ -222,7 +222,7 @@ proc loadAny(p: var JsonParser, a: TAny, t: var Table[BiggestInt, pointer]) =
|
||||
raiseParseErr(p, "float expected")
|
||||
of akRange: loadAny(p, a.skipRange, t)
|
||||
|
||||
proc loadAny(s: Stream, a: TAny, t: var Table[BiggestInt, pointer]) =
|
||||
proc loadAny(s: Stream, a: Any, t: var Table[BiggestInt, pointer]) =
|
||||
var p: JsonParser
|
||||
open(p, s, "unknown file")
|
||||
next(p)
|
||||
@@ -278,10 +278,11 @@ when not defined(testing) and isMainModule:
|
||||
else:
|
||||
nil
|
||||
|
||||
PNode = ref TNode
|
||||
TNode = object
|
||||
PNode = ref Node
|
||||
Node = object
|
||||
next, prev: PNode
|
||||
data: string
|
||||
{.deprecated: [TNode: Node].}
|
||||
|
||||
proc buildList(): PNode =
|
||||
new(result)
|
||||
@@ -317,14 +318,15 @@ when not defined(testing) and isMainModule:
|
||||
testit(test7)
|
||||
|
||||
type
|
||||
TA {.inheritable.} = object
|
||||
TB = object of TA
|
||||
A {.inheritable.} = object
|
||||
B = object of A
|
||||
f: int
|
||||
|
||||
var
|
||||
a: ref TA
|
||||
b: ref TB
|
||||
a: ref A
|
||||
b: ref B
|
||||
new(b)
|
||||
a = b
|
||||
echo($$a[]) # produces "{}", not "{f: 0}"
|
||||
|
||||
|
||||
|
||||
@@ -196,7 +196,7 @@ proc open*(filename: string, mode: FileMode = fmRead,
|
||||
if mappedSize != -1:
|
||||
result.size = mappedSize
|
||||
else:
|
||||
var stat: TStat
|
||||
var stat: Stat
|
||||
if fstat(result.handle, stat) != -1:
|
||||
# XXX: Hmm, this could be unsafe
|
||||
# Why is mmap taking int anyway?
|
||||
|
||||
@@ -86,7 +86,7 @@ type
|
||||
IPv6, ## IPv6 address
|
||||
IPv4 ## IPv4 address
|
||||
|
||||
TIpAddress* = object ## stores an arbitrary IP address
|
||||
IpAddress* = object ## stores an arbitrary IP address
|
||||
case family*: IpAddressFamily ## the type of the IP address (IPv4 or IPv6)
|
||||
of IpAddressFamily.IPv6:
|
||||
address_v6*: array[0..15, uint8] ## Contains the IP address in bytes in
|
||||
@@ -94,9 +94,10 @@ type
|
||||
of IpAddressFamily.IPv4:
|
||||
address_v4*: array[0..3, uint8] ## Contains the IP address in bytes in
|
||||
## case of IPv4
|
||||
{.deprecated: [TIpAddress: IpAddress].}
|
||||
|
||||
proc isIpAddress*(address_str: string): bool {.tags: [].}
|
||||
proc parseIpAddress*(address_str: string): TIpAddress
|
||||
proc parseIpAddress*(address_str: string): IpAddress
|
||||
|
||||
proc isDisconnectionError*(flags: set[SocketFlag],
|
||||
lastError: OSErrorCode): bool =
|
||||
@@ -395,7 +396,7 @@ proc acceptAddr*(server: Socket, client: var Socket, address: var string,
|
||||
|
||||
when false: #defined(ssl):
|
||||
proc acceptAddrSSL*(server: Socket, client: var Socket,
|
||||
address: var string): TSSLAcceptResult {.
|
||||
address: var string): SSLAcceptResult {.
|
||||
tags: [ReadIOEffect].} =
|
||||
## This procedure should only be used for non-blocking **SSL** sockets.
|
||||
## It will immediately return with one of the following values:
|
||||
@@ -992,39 +993,39 @@ proc isSsl*(socket: Socket): bool =
|
||||
proc getFd*(socket: Socket): SocketHandle = return socket.fd
|
||||
## Returns the socket's file descriptor
|
||||
|
||||
proc IPv4_any*(): TIpAddress =
|
||||
proc IPv4_any*(): IpAddress =
|
||||
## Returns the IPv4 any address, which can be used to listen on all available
|
||||
## network adapters
|
||||
result = TIpAddress(
|
||||
result = IpAddress(
|
||||
family: IpAddressFamily.IPv4,
|
||||
address_v4: [0'u8, 0, 0, 0])
|
||||
|
||||
proc IPv4_loopback*(): TIpAddress =
|
||||
proc IPv4_loopback*(): IpAddress =
|
||||
## Returns the IPv4 loopback address (127.0.0.1)
|
||||
result = TIpAddress(
|
||||
result = IpAddress(
|
||||
family: IpAddressFamily.IPv4,
|
||||
address_v4: [127'u8, 0, 0, 1])
|
||||
|
||||
proc IPv4_broadcast*(): TIpAddress =
|
||||
proc IPv4_broadcast*(): IpAddress =
|
||||
## Returns the IPv4 broadcast address (255.255.255.255)
|
||||
result = TIpAddress(
|
||||
result = IpAddress(
|
||||
family: IpAddressFamily.IPv4,
|
||||
address_v4: [255'u8, 255, 255, 255])
|
||||
|
||||
proc IPv6_any*(): TIpAddress =
|
||||
proc IPv6_any*(): IpAddress =
|
||||
## Returns the IPv6 any address (::0), which can be used
|
||||
## to listen on all available network adapters
|
||||
result = TIpAddress(
|
||||
result = IpAddress(
|
||||
family: IpAddressFamily.IPv6,
|
||||
address_v6: [0'u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
|
||||
|
||||
proc IPv6_loopback*(): TIpAddress =
|
||||
proc IPv6_loopback*(): IpAddress =
|
||||
## Returns the IPv6 loopback address (::1)
|
||||
result = TIpAddress(
|
||||
result = IpAddress(
|
||||
family: IpAddressFamily.IPv6,
|
||||
address_v6: [0'u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1])
|
||||
|
||||
proc `==`*(lhs, rhs: TIpAddress): bool =
|
||||
proc `==`*(lhs, rhs: IpAddress): bool =
|
||||
## Compares two IpAddresses for Equality. Returns two if the addresses are equal
|
||||
if lhs.family != rhs.family: return false
|
||||
if lhs.family == IpAddressFamily.IPv4:
|
||||
@@ -1035,8 +1036,8 @@ proc `==`*(lhs, rhs: TIpAddress): bool =
|
||||
if lhs.address_v6[i] != rhs.address_v6[i]: return false
|
||||
return true
|
||||
|
||||
proc `$`*(address: TIpAddress): string =
|
||||
## Converts an TIpAddress into the textual representation
|
||||
proc `$`*(address: IpAddress): string =
|
||||
## Converts an IpAddress into the textual representation
|
||||
result = ""
|
||||
case address.family
|
||||
of IpAddressFamily.IPv4:
|
||||
@@ -1095,7 +1096,7 @@ proc `$`*(address: TIpAddress): string =
|
||||
mask = mask shr 4
|
||||
printedLastGroup = true
|
||||
|
||||
proc parseIPv4Address(address_str: string): TIpAddress =
|
||||
proc parseIPv4Address(address_str: string): IpAddress =
|
||||
## Parses IPv4 adresses
|
||||
## Raises EInvalidValue on errors
|
||||
var
|
||||
@@ -1129,7 +1130,7 @@ proc parseIPv4Address(address_str: string): TIpAddress =
|
||||
raise newException(ValueError, "Invalid IP Address")
|
||||
result.address_v4[byteCount] = cast[uint8](currentByte)
|
||||
|
||||
proc parseIPv6Address(address_str: string): TIpAddress =
|
||||
proc parseIPv6Address(address_str: string): IpAddress =
|
||||
## Parses IPv6 adresses
|
||||
## Raises EInvalidValue on errors
|
||||
result.family = IpAddressFamily.IPv6
|
||||
@@ -1250,7 +1251,7 @@ proc parseIPv6Address(address_str: string): TIpAddress =
|
||||
raise newException(ValueError,
|
||||
"Invalid IP Address. The address consists of too many groups")
|
||||
|
||||
proc parseIpAddress(address_str: string): TIpAddress =
|
||||
proc parseIpAddress(address_str: string): IpAddress =
|
||||
## Parses an IP address
|
||||
## Raises EInvalidValue on error
|
||||
if address_str == nil:
|
||||
|
||||
@@ -26,17 +26,19 @@ const
|
||||
withThreads = compileOption("threads")
|
||||
tickCountCorrection = 50_000
|
||||
|
||||
when not declared(system.TStackTrace):
|
||||
type TStackTrace = array [0..20, cstring]
|
||||
when not declared(system.StackTrace):
|
||||
type StackTrace = array [0..20, cstring]
|
||||
{.deprecated: [TStackTrace: StackTrace].}
|
||||
|
||||
# We use a simple hash table of bounded size to keep track of the stack traces:
|
||||
type
|
||||
TProfileEntry = object
|
||||
ProfileEntry = object
|
||||
total: int
|
||||
st: TStackTrace
|
||||
TProfileData = array [0..64*1024-1, ptr TProfileEntry]
|
||||
st: StackTrace
|
||||
ProfileData = array [0..64*1024-1, ptr ProfileEntry]
|
||||
{.deprecated: [TProfileEntry: ProfileEntry, TProfileData: ProfileData].}
|
||||
|
||||
proc `==`(a, b: TStackTrace): bool =
|
||||
proc `==`(a, b: StackTrace): bool =
|
||||
for i in 0 .. high(a):
|
||||
if a[i] != b[i]: return false
|
||||
result = true
|
||||
@@ -44,13 +46,13 @@ proc `==`(a, b: TStackTrace): bool =
|
||||
# XXX extract this data structure; it is generally useful ;-)
|
||||
# However a chain length of over 3000 is suspicious...
|
||||
var
|
||||
profileData: TProfileData
|
||||
profileData: ProfileData
|
||||
emptySlots = profileData.len * 3 div 2
|
||||
maxChainLen = 0
|
||||
totalCalls = 0
|
||||
|
||||
when not defined(memProfiler):
|
||||
var interval: TNanos = 5_000_000 - tickCountCorrection # 5ms
|
||||
var interval: Nanos = 5_000_000 - tickCountCorrection # 5ms
|
||||
|
||||
proc setSamplingFrequency*(intervalInUs: int) =
|
||||
## set this to change the sampling frequency. Default value is 5ms.
|
||||
@@ -62,11 +64,11 @@ when not defined(memProfiler):
|
||||
when withThreads:
|
||||
import locks
|
||||
var
|
||||
profilingLock: TLock
|
||||
profilingLock: Lock
|
||||
|
||||
initLock profilingLock
|
||||
|
||||
proc hookAux(st: TStackTrace, costs: int) =
|
||||
proc hookAux(st: StackTrace, costs: int) =
|
||||
# this is quite performance sensitive!
|
||||
when withThreads: acquire profilingLock
|
||||
inc totalCalls
|
||||
@@ -94,8 +96,8 @@ proc hookAux(st: TStackTrace, costs: int) =
|
||||
var chain = 0
|
||||
while true:
|
||||
if profileData[h] == nil:
|
||||
profileData[h] = cast[ptr TProfileEntry](
|
||||
allocShared0(sizeof(TProfileEntry)))
|
||||
profileData[h] = cast[ptr ProfileEntry](
|
||||
allocShared0(sizeof(ProfileEntry)))
|
||||
profileData[h].total = costs
|
||||
profileData[h].st = st
|
||||
dec emptySlots
|
||||
@@ -115,7 +117,7 @@ when defined(memProfiler):
|
||||
var
|
||||
gTicker {.threadvar.}: int
|
||||
|
||||
proc hook(st: TStackTrace, size: int) {.nimcall.} =
|
||||
proc hook(st: StackTrace, size: int) {.nimcall.} =
|
||||
if gTicker == 0:
|
||||
gTicker = -1
|
||||
when defined(ignoreAllocationSize):
|
||||
@@ -127,26 +129,26 @@ when defined(memProfiler):
|
||||
|
||||
else:
|
||||
var
|
||||
t0 {.threadvar.}: TTicks
|
||||
t0 {.threadvar.}: Ticks
|
||||
|
||||
proc hook(st: TStackTrace) {.nimcall.} =
|
||||
proc hook(st: StackTrace) {.nimcall.} =
|
||||
if interval == 0:
|
||||
hookAux(st, 1)
|
||||
elif int64(t0) == 0 or getTicks() - t0 > interval:
|
||||
hookAux(st, 1)
|
||||
t0 = getTicks()
|
||||
|
||||
proc getTotal(x: ptr TProfileEntry): int =
|
||||
proc getTotal(x: ptr ProfileEntry): int =
|
||||
result = if isNil(x): 0 else: x.total
|
||||
|
||||
proc cmpEntries(a, b: ptr TProfileEntry): int =
|
||||
proc cmpEntries(a, b: ptr ProfileEntry): int =
|
||||
result = b.getTotal - a.getTotal
|
||||
|
||||
proc `//`(a, b: int): string =
|
||||
result = format("$1/$2 = $3%", a, b, formatFloat(a / b * 100.0, ffDefault, 2))
|
||||
|
||||
proc writeProfile() {.noconv.} =
|
||||
when declared(system.TStackTrace):
|
||||
when declared(system.StackTrace):
|
||||
system.profilerHook = nil
|
||||
const filename = "profile_results.txt"
|
||||
echo "writing " & filename & "..."
|
||||
@@ -161,7 +163,7 @@ proc writeProfile() {.noconv.} =
|
||||
var perProc = initCountTable[string]()
|
||||
for i in 0..entries-1:
|
||||
var dups = initSet[string]()
|
||||
for ii in 0..high(TStackTrace):
|
||||
for ii in 0..high(StackTrace):
|
||||
let procname = profileData[i].st[ii]
|
||||
if isNil(procname): break
|
||||
let p = $procname
|
||||
@@ -176,7 +178,7 @@ proc writeProfile() {.noconv.} =
|
||||
writeln(f, "Entry: ", i+1, "/", entries, " Calls: ",
|
||||
profileData[i].total // totalCalls, " [sum: ", sum, "; ",
|
||||
sum // totalCalls, "]")
|
||||
for ii in 0..high(TStackTrace):
|
||||
for ii in 0..high(StackTrace):
|
||||
let procname = profileData[i].st[ii]
|
||||
if isNil(procname): break
|
||||
writeln(f, " ", procname, " ", perProc[$procname] // totalCalls)
|
||||
@@ -189,16 +191,16 @@ var
|
||||
disabled: int
|
||||
|
||||
proc disableProfiling*() =
|
||||
when declared(system.TStackTrace):
|
||||
when declared(system.StackTrace):
|
||||
atomicDec disabled
|
||||
system.profilerHook = nil
|
||||
|
||||
proc enableProfiling*() =
|
||||
when declared(system.TStackTrace):
|
||||
when declared(system.StackTrace):
|
||||
if atomicInc(disabled) >= 0:
|
||||
system.profilerHook = hook
|
||||
|
||||
when declared(system.TStackTrace):
|
||||
when declared(system.StackTrace):
|
||||
system.profilerHook = hook
|
||||
addQuitProc(writeProfile)
|
||||
|
||||
|
||||
@@ -359,7 +359,7 @@ when defined(windows):
|
||||
|
||||
template wrapBinary(varname, winApiProc, arg, arg2: expr) {.immediate.} =
|
||||
var varname = winApiProc(newWideCString(arg), arg2)
|
||||
proc findFirstFile(a: string, b: var TWIN32_FIND_DATA): THandle =
|
||||
proc findFirstFile(a: string, b: var TWIN32_FIND_DATA): Handle =
|
||||
result = findFirstFileW(newWideCString(a), b)
|
||||
template findNextFile(a, b: expr): expr = findNextFileW(a, b)
|
||||
template getCommandLine(): expr = getCommandLineW()
|
||||
@@ -390,7 +390,7 @@ proc existsFile*(filename: string): bool {.rtl, extern: "nos$1",
|
||||
if a != -1'i32:
|
||||
result = (a and FILE_ATTRIBUTE_DIRECTORY) == 0'i32
|
||||
else:
|
||||
var res: TStat
|
||||
var res: Stat
|
||||
return stat(filename, res) >= 0'i32 and S_ISREG(res.st_mode)
|
||||
|
||||
proc existsDir*(dir: string): bool {.rtl, extern: "nos$1", tags: [ReadDirEffect].} =
|
||||
@@ -404,7 +404,7 @@ proc existsDir*(dir: string): bool {.rtl, extern: "nos$1", tags: [ReadDirEffect]
|
||||
if a != -1'i32:
|
||||
result = (a and FILE_ATTRIBUTE_DIRECTORY) != 0'i32
|
||||
else:
|
||||
var res: TStat
|
||||
var res: Stat
|
||||
return stat(dir, res) >= 0'i32 and S_ISDIR(res.st_mode)
|
||||
|
||||
proc symlinkExists*(link: string): bool {.rtl, extern: "nos$1",
|
||||
@@ -419,7 +419,7 @@ proc symlinkExists*(link: string): bool {.rtl, extern: "nos$1",
|
||||
if a != -1'i32:
|
||||
result = (a and FILE_ATTRIBUTE_REPARSE_POINT) != 0'i32
|
||||
else:
|
||||
var res: TStat
|
||||
var res: Stat
|
||||
return lstat(link, res) >= 0'i32 and S_ISLNK(res.st_mode)
|
||||
|
||||
proc fileExists*(filename: string): bool {.inline.} =
|
||||
@@ -433,7 +433,7 @@ proc dirExists*(dir: string): bool {.inline.} =
|
||||
proc getLastModificationTime*(file: string): Time {.rtl, extern: "nos$1".} =
|
||||
## Returns the `file`'s last modification time.
|
||||
when defined(posix):
|
||||
var res: TStat
|
||||
var res: Stat
|
||||
if stat(file, res) < 0'i32: raiseOSError(osLastError())
|
||||
return res.st_mtime
|
||||
else:
|
||||
@@ -446,7 +446,7 @@ proc getLastModificationTime*(file: string): Time {.rtl, extern: "nos$1".} =
|
||||
proc getLastAccessTime*(file: string): Time {.rtl, extern: "nos$1".} =
|
||||
## Returns the `file`'s last read or write access time.
|
||||
when defined(posix):
|
||||
var res: TStat
|
||||
var res: Stat
|
||||
if stat(file, res) < 0'i32: raiseOSError(osLastError())
|
||||
return res.st_atime
|
||||
else:
|
||||
@@ -461,7 +461,7 @@ proc getCreationTime*(file: string): Time {.rtl, extern: "nos$1".} =
|
||||
## Note that under posix OS's, the returned time may actually be the time at
|
||||
## which the file's attribute's were last modified.
|
||||
when defined(posix):
|
||||
var res: TStat
|
||||
var res: Stat
|
||||
if stat(file, res) < 0'i32: raiseOSError(osLastError())
|
||||
return res.st_ctime
|
||||
else:
|
||||
@@ -794,7 +794,7 @@ proc isAbsolute*(path: string): bool {.rtl, noSideEffect, extern: "nos$1".} =
|
||||
result = path[0] == '/'
|
||||
|
||||
when defined(Windows):
|
||||
proc openHandle(path: string, followSymlink=true): THandle =
|
||||
proc openHandle(path: string, followSymlink=true): Handle =
|
||||
var flags = FILE_FLAG_BACKUP_SEMANTICS or FILE_ATTRIBUTE_NORMAL
|
||||
if not followSymlink:
|
||||
flags = flags or FILE_FLAG_OPEN_REPARSE_POINT
|
||||
@@ -846,7 +846,7 @@ proc sameFile*(path1, path2: string): bool {.rtl, extern: "nos$1",
|
||||
|
||||
if not success: raiseOSError(lastErr)
|
||||
else:
|
||||
var a, b: TStat
|
||||
var a, b: Stat
|
||||
if stat(path1, a) < 0'i32 or stat(path2, b) < 0'i32:
|
||||
raiseOSError(osLastError())
|
||||
else:
|
||||
@@ -903,7 +903,7 @@ proc getFilePermissions*(filename: string): set[FilePermission] {.
|
||||
## an error. On Windows, only the ``readonly`` flag is checked, every other
|
||||
## permission is available in any case.
|
||||
when defined(posix):
|
||||
var a: TStat
|
||||
var a: Stat
|
||||
if stat(filename, a) < 0'i32: raiseOSError(osLastError())
|
||||
result = {}
|
||||
if (a.st_mode and S_IRUSR) != 0'i32: result.incl(fpUserRead)
|
||||
@@ -1232,7 +1232,7 @@ iterator walkFiles*(pattern: string): string {.tags: [ReadDirEffect].} =
|
||||
findClose(res)
|
||||
else: # here we use glob
|
||||
var
|
||||
f: TGlob
|
||||
f: Glob
|
||||
res: int
|
||||
f.gl_offs = 0
|
||||
f.gl_pathc = 0
|
||||
@@ -1297,7 +1297,7 @@ iterator walkDir*(dir: string): tuple[kind: PathComponent, path: string] {.
|
||||
if x == nil: break
|
||||
var y = $x.d_name
|
||||
if y != "." and y != "..":
|
||||
var s: TStat
|
||||
var s: Stat
|
||||
y = dir / y
|
||||
var k = pcFile
|
||||
|
||||
@@ -1842,7 +1842,7 @@ proc sleep*(milsecs: int) {.rtl, extern: "nos$1", tags: [TimeEffect].} =
|
||||
when defined(windows):
|
||||
winlean.sleep(int32(milsecs))
|
||||
else:
|
||||
var a, b: Ttimespec
|
||||
var a, b: Timespec
|
||||
a.tv_sec = Time(milsecs div 1000)
|
||||
a.tv_nsec = (milsecs mod 1000) * 1000 * 1000
|
||||
discard posix.nanosleep(a, b)
|
||||
@@ -1907,8 +1907,8 @@ when defined(Windows):
|
||||
FileId* = int64
|
||||
else:
|
||||
type
|
||||
DeviceId* = TDev
|
||||
FileId* = Tino
|
||||
DeviceId* = Dev
|
||||
FileId* = Ino
|
||||
|
||||
type
|
||||
FileInfo* = object
|
||||
@@ -1925,7 +1925,7 @@ type
|
||||
template rawToFormalFileInfo(rawInfo, formalInfo): expr =
|
||||
## Transforms the native file info structure into the one nim uses.
|
||||
## 'rawInfo' is either a 'TBY_HANDLE_FILE_INFORMATION' structure on Windows,
|
||||
## or a 'TStat' structure on posix
|
||||
## or a 'Stat' structure on posix
|
||||
when defined(Windows):
|
||||
template toTime(e): expr = winTimeToUnixTime(rdFileTime(e))
|
||||
template merge(a, b): expr = a or (b shl 32)
|
||||
@@ -1996,7 +1996,7 @@ proc getFileInfo*(handle: FileHandle): FileInfo =
|
||||
raiseOSError(osLastError())
|
||||
rawToFormalFileInfo(rawInfo, result)
|
||||
else:
|
||||
var rawInfo: TStat
|
||||
var rawInfo: Stat
|
||||
if fstat(handle, rawInfo) < 0'i32:
|
||||
raiseOSError(osLastError())
|
||||
rawToFormalFileInfo(rawInfo, result)
|
||||
@@ -2031,7 +2031,7 @@ proc getFileInfo*(path: string, followSymlink = true): FileInfo =
|
||||
rawToFormalFileInfo(rawInfo, result)
|
||||
discard closeHandle(handle)
|
||||
else:
|
||||
var rawInfo: TStat
|
||||
var rawInfo: Stat
|
||||
if followSymlink:
|
||||
if stat(path, rawInfo) < 0'i32:
|
||||
raiseOSError(osLastError())
|
||||
|
||||
@@ -26,13 +26,13 @@ when defined(linux):
|
||||
type
|
||||
ProcessObj = object of RootObj
|
||||
when defined(windows):
|
||||
fProcessHandle: THandle
|
||||
fProcessHandle: Handle
|
||||
inHandle, outHandle, errHandle: FileHandle
|
||||
id: THandle
|
||||
id: Handle
|
||||
else:
|
||||
inHandle, outHandle, errHandle: FileHandle
|
||||
inStream, outStream, errStream: Stream
|
||||
id: TPid
|
||||
id: Pid
|
||||
exitCode: cint
|
||||
|
||||
Process* = ref ProcessObj ## represents an operating system process
|
||||
@@ -334,10 +334,11 @@ when not defined(useNimRtl):
|
||||
when defined(Windows) and not defined(useNimRtl):
|
||||
# We need to implement a handle stream for Windows:
|
||||
type
|
||||
PFileHandleStream = ref TFileHandleStream
|
||||
TFileHandleStream = object of StreamObj
|
||||
handle: THandle
|
||||
PFileHandleStream = ref FileHandleStream
|
||||
FileHandleStream = object of StreamObj
|
||||
handle: Handle
|
||||
atTheEnd: bool
|
||||
{.deprecated: [TFileHandleStream: FileHandleStream].}
|
||||
|
||||
proc hsClose(s: Stream) = discard # nothing to do here
|
||||
proc hsAtEnd(s: Stream): bool = return PFileHandleStream(s).atTheEnd
|
||||
@@ -361,7 +362,7 @@ when defined(Windows) and not defined(useNimRtl):
|
||||
addr bytesWritten, nil)
|
||||
if a == 0: raiseOSError(osLastError())
|
||||
|
||||
proc newFileHandleStream(handle: THandle): PFileHandleStream =
|
||||
proc newFileHandleStream(handle: Handle): PFileHandleStream =
|
||||
new(result)
|
||||
result.handle = handle
|
||||
result.closeImpl = hsClose
|
||||
@@ -387,14 +388,14 @@ when defined(Windows) and not defined(useNimRtl):
|
||||
copyMem(addr(result[L]), cstring(x), x.len+1) # copy \0
|
||||
inc(L, x.len+1)
|
||||
|
||||
#proc open_osfhandle(osh: THandle, mode: int): int {.
|
||||
#proc open_osfhandle(osh: Handle, mode: int): int {.
|
||||
# importc: "_open_osfhandle", header: "<fcntl.h>".}
|
||||
|
||||
#var
|
||||
# O_WRONLY {.importc: "_O_WRONLY", header: "<fcntl.h>".}: int
|
||||
# O_RDONLY {.importc: "_O_RDONLY", header: "<fcntl.h>".}: int
|
||||
|
||||
proc createPipeHandles(rdHandle, wrHandle: var THandle) =
|
||||
proc createPipeHandles(rdHandle, wrHandle: var Handle) =
|
||||
var piInheritablePipe: TSECURITY_ATTRIBUTES
|
||||
piInheritablePipe.nLength = sizeof(TSECURITY_ATTRIBUTES).cint
|
||||
piInheritablePipe.lpSecurityDescriptor = nil
|
||||
@@ -402,7 +403,7 @@ when defined(Windows) and not defined(useNimRtl):
|
||||
if createPipe(rdHandle, wrHandle, piInheritablePipe, 1024) == 0'i32:
|
||||
raiseOSError(osLastError())
|
||||
|
||||
proc fileClose(h: THandle) {.inline.} =
|
||||
proc fileClose(h: Handle) {.inline.} =
|
||||
if h > 4: discard closeHandle(h)
|
||||
|
||||
proc startProcess(command: string,
|
||||
@@ -414,7 +415,7 @@ when defined(Windows) and not defined(useNimRtl):
|
||||
si: TSTARTUPINFO
|
||||
procInfo: TPROCESS_INFORMATION
|
||||
success: int
|
||||
hi, ho, he: THandle
|
||||
hi, ho, he: Handle
|
||||
new(result)
|
||||
si.cb = sizeof(si).cint
|
||||
if poParentStreams notin options:
|
||||
@@ -527,7 +528,7 @@ when defined(Windows) and not defined(useNimRtl):
|
||||
var
|
||||
si: TSTARTUPINFO
|
||||
procInfo: TPROCESS_INFORMATION
|
||||
process: THandle
|
||||
process: Handle
|
||||
L: int32
|
||||
si.cb = sizeof(si).cint
|
||||
si.hStdError = getStdHandle(STD_ERROR_HANDLE)
|
||||
@@ -595,7 +596,7 @@ elif not defined(useNimRtl):
|
||||
copyMem(result[i], addr(x[0]), x.len+1)
|
||||
inc(i)
|
||||
|
||||
type TStartProcessData = object
|
||||
type StartProcessData = object
|
||||
sysCommand: cstring
|
||||
sysArgs: cstringArray
|
||||
sysEnv: cstringArray
|
||||
@@ -604,14 +605,15 @@ elif not defined(useNimRtl):
|
||||
optionPoUsePath: bool
|
||||
optionPoParentStreams: bool
|
||||
optionPoStdErrToStdOut: bool
|
||||
{.deprecated: [TStartProcessData: StartProcessData].}
|
||||
|
||||
when not defined(useFork):
|
||||
proc startProcessAuxSpawn(data: TStartProcessData): TPid {.
|
||||
proc startProcessAuxSpawn(data: StartProcessData): Pid {.
|
||||
tags: [ExecIOEffect, ReadEnvEffect], gcsafe.}
|
||||
proc startProcessAuxFork(data: TStartProcessData): TPid {.
|
||||
proc startProcessAuxFork(data: StartProcessData): Pid {.
|
||||
tags: [ExecIOEffect, ReadEnvEffect], gcsafe.}
|
||||
{.push stacktrace: off, profiler: off.}
|
||||
proc startProcessAfterFork(data: ptr TStartProcessData) {.
|
||||
proc startProcessAfterFork(data: ptr StartProcessData) {.
|
||||
tags: [ExecIOEffect, ReadEnvEffect], cdecl, gcsafe.}
|
||||
{.pop.}
|
||||
|
||||
@@ -641,7 +643,7 @@ elif not defined(useNimRtl):
|
||||
for arg in args.items:
|
||||
sysArgsRaw.add arg
|
||||
|
||||
var pid: TPid
|
||||
var pid: Pid
|
||||
|
||||
var sysArgs = allocCStringArray(sysArgsRaw)
|
||||
defer: deallocCStringArray(sysArgs)
|
||||
@@ -653,7 +655,7 @@ elif not defined(useNimRtl):
|
||||
|
||||
defer: deallocCStringArray(sysEnv)
|
||||
|
||||
var data: TStartProcessData
|
||||
var data: StartProcessData
|
||||
data.sysCommand = sysCommand
|
||||
data.sysArgs = sysArgs
|
||||
data.sysEnv = sysEnv
|
||||
@@ -698,7 +700,7 @@ elif not defined(useNimRtl):
|
||||
discard close(pStdout[writeIdx])
|
||||
|
||||
when not defined(useFork):
|
||||
proc startProcessAuxSpawn(data: TStartProcessData): TPid =
|
||||
proc startProcessAuxSpawn(data: StartProcessData): Pid =
|
||||
var attr: Tposix_spawnattr
|
||||
var fops: Tposix_spawn_file_actions
|
||||
|
||||
@@ -708,7 +710,7 @@ elif not defined(useNimRtl):
|
||||
chck posix_spawn_file_actions_init(fops)
|
||||
chck posix_spawnattr_init(attr)
|
||||
|
||||
var mask: Tsigset
|
||||
var mask: Sigset
|
||||
chck sigemptyset(mask)
|
||||
chck posix_spawnattr_setsigmask(attr, mask)
|
||||
chck posix_spawnattr_setpgroup(attr, 0'i32)
|
||||
@@ -732,7 +734,7 @@ elif not defined(useNimRtl):
|
||||
# FIXME: chdir is global to process
|
||||
if data.workingDir.len > 0:
|
||||
setCurrentDir($data.workingDir)
|
||||
var pid: TPid
|
||||
var pid: Pid
|
||||
|
||||
if data.optionPoUsePath:
|
||||
res = posix_spawnp(pid, data.sysCommand, fops, attr, data.sysArgs, data.sysEnv)
|
||||
@@ -744,14 +746,14 @@ elif not defined(useNimRtl):
|
||||
chck res
|
||||
return pid
|
||||
|
||||
proc startProcessAuxFork(data: TStartProcessData): TPid =
|
||||
proc startProcessAuxFork(data: StartProcessData): Pid =
|
||||
if pipe(data.pErrorPipe) != 0:
|
||||
raiseOSError(osLastError())
|
||||
|
||||
defer:
|
||||
discard close(data.pErrorPipe[readIdx])
|
||||
|
||||
var pid: TPid
|
||||
var pid: Pid
|
||||
var dataCopy = data
|
||||
|
||||
when defined(useClone):
|
||||
@@ -781,7 +783,7 @@ elif not defined(useNimRtl):
|
||||
return pid
|
||||
|
||||
{.push stacktrace: off, profiler: off.}
|
||||
proc startProcessFail(data: ptr TStartProcessData) =
|
||||
proc startProcessFail(data: ptr StartProcessData) =
|
||||
var error: cint = errno
|
||||
discard write(data.pErrorPipe[writeIdx], addr error, sizeof(error))
|
||||
exitnow(1)
|
||||
@@ -789,7 +791,7 @@ elif not defined(useNimRtl):
|
||||
when defined(macosx) or defined(freebsd):
|
||||
var environ {.importc.}: cstringArray
|
||||
|
||||
proc startProcessAfterFork(data: ptr TStartProcessData) =
|
||||
proc startProcessAfterFork(data: ptr StartProcessData) =
|
||||
# Warning: no GC here!
|
||||
# Or anything that touches global structures - all called nim procs
|
||||
# must be marked with stackTrace:off. Inspect C code after making changes.
|
||||
|
||||
Reference in New Issue
Block a user