Merge remote-tracking branch 'origin/devel' into fix-test-failures
This commit is contained in:
commit
eea8d604d0
41 changed files with 358 additions and 163 deletions
|
|
@ -12,8 +12,11 @@ cd ".."
|
||||||
|
|
||||||
./bin/nim c koch
|
./bin/nim c koch
|
||||||
./koch boot -d:release
|
./koch boot -d:release
|
||||||
|
./koch geninstall
|
||||||
|
|
||||||
cp -f install.sh.template install.sh
|
set +x
|
||||||
chmod +x install.sh
|
|
||||||
|
echo
|
||||||
|
echo 'Install Nim using "./install.sh <dir>" or "sudo ./install.sh <dir>".'
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|
|
||||||
|
|
@ -747,6 +747,17 @@ proc genTupleElem(p: BProc, e: PNode, d: var TLoc) =
|
||||||
addf(r, ".Field$1", [rope(i)])
|
addf(r, ".Field$1", [rope(i)])
|
||||||
putIntoDest(p, d, ty.sons[i], r, a.s)
|
putIntoDest(p, d, ty.sons[i], r, a.s)
|
||||||
|
|
||||||
|
proc lookupFieldAgain(p: BProc, ty: PType; field: PSym; r: var Rope): PSym =
|
||||||
|
var ty = ty
|
||||||
|
assert r != nil
|
||||||
|
while ty != nil:
|
||||||
|
assert(ty.kind in {tyTuple, tyObject})
|
||||||
|
result = lookupInRecord(ty.n, field.name)
|
||||||
|
if result != nil: break
|
||||||
|
if not p.module.compileToCpp: add(r, ".Sup")
|
||||||
|
ty = getUniqueType(ty.sons[0])
|
||||||
|
if result == nil: internalError(field.info, "genCheckedRecordField")
|
||||||
|
|
||||||
proc genRecordField(p: BProc, e: PNode, d: var TLoc) =
|
proc genRecordField(p: BProc, e: PNode, d: var TLoc) =
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
var ty = genRecordFieldAux(p, e, d, a)
|
var ty = genRecordFieldAux(p, e, d, a)
|
||||||
|
|
@ -758,15 +769,7 @@ proc genRecordField(p: BProc, e: PNode, d: var TLoc) =
|
||||||
addf(r, ".Field$1", [rope(f.position)])
|
addf(r, ".Field$1", [rope(f.position)])
|
||||||
putIntoDest(p, d, f.typ, r, a.s)
|
putIntoDest(p, d, f.typ, r, a.s)
|
||||||
else:
|
else:
|
||||||
var field: PSym = nil
|
let field = lookupFieldAgain(p, ty, f, r)
|
||||||
while ty != nil:
|
|
||||||
if ty.kind notin {tyTuple, tyObject}:
|
|
||||||
internalError(e.info, "genRecordField")
|
|
||||||
field = lookupInRecord(ty.n, f.name)
|
|
||||||
if field != nil: break
|
|
||||||
if not p.module.compileToCpp: add(r, ".Sup")
|
|
||||||
ty = getUniqueType(ty.sons[0])
|
|
||||||
if field == nil: internalError(e.info, "genRecordField 2 ")
|
|
||||||
if field.loc.r == nil: internalError(e.info, "genRecordField 3")
|
if field.loc.r == nil: internalError(e.info, "genRecordField 3")
|
||||||
addf(r, ".$1", [field.loc.r])
|
addf(r, ".$1", [field.loc.r])
|
||||||
putIntoDest(p, d, field.typ, r, a.s)
|
putIntoDest(p, d, field.typ, r, a.s)
|
||||||
|
|
@ -774,7 +777,8 @@ proc genRecordField(p: BProc, e: PNode, d: var TLoc) =
|
||||||
|
|
||||||
proc genInExprAux(p: BProc, e: PNode, a, b, d: var TLoc)
|
proc genInExprAux(p: BProc, e: PNode, a, b, d: var TLoc)
|
||||||
|
|
||||||
proc genFieldCheck(p: BProc, e: PNode, obj: Rope, field: PSym) =
|
proc genFieldCheck(p: BProc, e: PNode, obj: Rope, field: PSym;
|
||||||
|
origTy: PType) =
|
||||||
var test, u, v: TLoc
|
var test, u, v: TLoc
|
||||||
for i in countup(1, sonsLen(e) - 1):
|
for i in countup(1, sonsLen(e) - 1):
|
||||||
var it = e.sons[i]
|
var it = e.sons[i]
|
||||||
|
|
@ -786,8 +790,12 @@ proc genFieldCheck(p: BProc, e: PNode, obj: Rope, field: PSym) =
|
||||||
assert(disc.kind == nkSym)
|
assert(disc.kind == nkSym)
|
||||||
initLoc(test, locNone, it.typ, OnStack)
|
initLoc(test, locNone, it.typ, OnStack)
|
||||||
initLocExpr(p, it.sons[1], u)
|
initLocExpr(p, it.sons[1], u)
|
||||||
initLoc(v, locExpr, disc.typ, OnUnknown)
|
var o = obj
|
||||||
v.r = "$1.$2" % [obj, disc.sym.loc.r]
|
let d = lookupFieldAgain(p, origTy, disc.sym, o)
|
||||||
|
initLoc(v, locExpr, d.typ, OnUnknown)
|
||||||
|
v.r = o
|
||||||
|
v.r.add(".")
|
||||||
|
v.r.add(d.loc.r)
|
||||||
genInExprAux(p, it, u, v, test)
|
genInExprAux(p, it, u, v, test)
|
||||||
let id = nodeTableTestOrSet(p.module.dataCache,
|
let id = nodeTableTestOrSet(p.module.dataCache,
|
||||||
newStrNode(nkStrLit, field.name.s), gBackendId)
|
newStrNode(nkStrLit, field.name.s), gBackendId)
|
||||||
|
|
@ -804,25 +812,14 @@ proc genFieldCheck(p: BProc, e: PNode, obj: Rope, field: PSym) =
|
||||||
|
|
||||||
proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) =
|
proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) =
|
||||||
if optFieldCheck in p.options:
|
if optFieldCheck in p.options:
|
||||||
var
|
var a: TLoc
|
||||||
a: TLoc
|
let ty = genRecordFieldAux(p, e.sons[0], d, a)
|
||||||
f, field: PSym
|
var r = rdLoc(a)
|
||||||
ty: PType
|
let f = e.sons[0].sons[1].sym
|
||||||
r: Rope
|
let field = lookupFieldAgain(p, ty, f, r)
|
||||||
ty = genRecordFieldAux(p, e.sons[0], d, a)
|
|
||||||
r = rdLoc(a)
|
|
||||||
f = e.sons[0].sons[1].sym
|
|
||||||
field = nil
|
|
||||||
while ty != nil:
|
|
||||||
assert(ty.kind in {tyTuple, tyObject})
|
|
||||||
field = lookupInRecord(ty.n, f.name)
|
|
||||||
if field != nil: break
|
|
||||||
if not p.module.compileToCpp: add(r, ".Sup")
|
|
||||||
ty = getUniqueType(ty.sons[0])
|
|
||||||
if field == nil: internalError(e.info, "genCheckedRecordField")
|
|
||||||
if field.loc.r == nil:
|
if field.loc.r == nil:
|
||||||
internalError(e.info, "genCheckedRecordField") # generate the checks:
|
internalError(e.info, "genCheckedRecordField") # generate the checks:
|
||||||
genFieldCheck(p, e, r, field)
|
genFieldCheck(p, e, r, field, ty)
|
||||||
add(r, rfmt(nil, ".$1", field.loc.r))
|
add(r, rfmt(nil, ".$1", field.loc.r))
|
||||||
putIntoDest(p, d, field.typ, r, a.s)
|
putIntoDest(p, d, field.typ, r, a.s)
|
||||||
else:
|
else:
|
||||||
|
|
@ -1150,20 +1147,15 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
else:
|
else:
|
||||||
constructLoc(p, tmp)
|
constructLoc(p, tmp)
|
||||||
discard getTypeDesc(p.module, t)
|
discard getTypeDesc(p.module, t)
|
||||||
|
let ty = getUniqueType(t)
|
||||||
for i in 1 .. <e.len:
|
for i in 1 .. <e.len:
|
||||||
let it = e.sons[i]
|
let it = e.sons[i]
|
||||||
var tmp2: TLoc
|
var tmp2: TLoc
|
||||||
tmp2.r = r
|
tmp2.r = r
|
||||||
var field: PSym = nil
|
let field = lookupFieldAgain(p, ty, it.sons[0].sym, tmp2.r)
|
||||||
var ty = getUniqueType(t)
|
if field.loc.r == nil: internalError(e.info, "genObjConstr")
|
||||||
while ty != nil:
|
|
||||||
field = lookupInRecord(ty.n, it.sons[0].sym.name)
|
|
||||||
if field != nil: break
|
|
||||||
if not p.module.compileToCpp: add(tmp2.r, ".Sup")
|
|
||||||
ty = getUniqueType(ty.sons[0])
|
|
||||||
if field == nil or field.loc.r == nil: internalError(e.info, "genObjConstr")
|
|
||||||
if it.len == 3 and optFieldCheck in p.options:
|
if it.len == 3 and optFieldCheck in p.options:
|
||||||
genFieldCheck(p, it.sons[2], tmp2.r, field)
|
genFieldCheck(p, it.sons[2], tmp2.r, field, ty)
|
||||||
add(tmp2.r, ".")
|
add(tmp2.r, ".")
|
||||||
add(tmp2.r, field.loc.r)
|
add(tmp2.r, field.loc.r)
|
||||||
tmp2.k = locTemp
|
tmp2.k = locTemp
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,9 @@ Files: "lib/posix/*.nim"
|
||||||
Files: "lib/js/*.nim"
|
Files: "lib/js/*.nim"
|
||||||
Files: "lib/packages/docutils/*.nim"
|
Files: "lib/packages/docutils/*.nim"
|
||||||
|
|
||||||
|
Files: "lib/deprecated/core/*.nim"
|
||||||
|
Files: "lib/deprecated/pure/*.nim"
|
||||||
|
Files: "lib/deprecated/pure/*.cfg"
|
||||||
|
|
||||||
[Other]
|
[Other]
|
||||||
Files: "examples/*.nim"
|
Files: "examples/*.nim"
|
||||||
|
|
|
||||||
|
|
@ -14,22 +14,14 @@ import
|
||||||
|
|
||||||
var systemModule*: PSym
|
var systemModule*: PSym
|
||||||
|
|
||||||
proc registerSysType*(t: PType)
|
|
||||||
# magic symbols in the system module:
|
|
||||||
proc getSysType*(kind: TTypeKind): PType
|
|
||||||
proc getCompilerProc*(name: string): PSym
|
|
||||||
proc registerCompilerProc*(s: PSym)
|
|
||||||
proc finishSystem*(tab: TStrTable)
|
|
||||||
proc getSysSym*(name: string): PSym
|
|
||||||
# implementation
|
|
||||||
|
|
||||||
var
|
var
|
||||||
gSysTypes: array[TTypeKind, PType]
|
gSysTypes: array[TTypeKind, PType]
|
||||||
compilerprocs: TStrTable
|
compilerprocs: TStrTable
|
||||||
|
exposed: TStrTable
|
||||||
|
|
||||||
proc nilOrSysInt*: PType = gSysTypes[tyInt]
|
proc nilOrSysInt*: PType = gSysTypes[tyInt]
|
||||||
|
|
||||||
proc registerSysType(t: PType) =
|
proc registerSysType*(t: PType) =
|
||||||
if gSysTypes[t.kind] == nil: gSysTypes[t.kind] = t
|
if gSysTypes[t.kind] == nil: gSysTypes[t.kind] = t
|
||||||
|
|
||||||
proc newSysType(kind: TTypeKind, size: int): PType =
|
proc newSysType(kind: TTypeKind, size: int): PType =
|
||||||
|
|
@ -37,7 +29,7 @@ proc newSysType(kind: TTypeKind, size: int): PType =
|
||||||
result.size = size
|
result.size = size
|
||||||
result.align = size.int16
|
result.align = size.int16
|
||||||
|
|
||||||
proc getSysSym(name: string): PSym =
|
proc getSysSym*(name: string): PSym =
|
||||||
result = strTableGet(systemModule.tab, getIdent(name))
|
result = strTableGet(systemModule.tab, getIdent(name))
|
||||||
if result == nil:
|
if result == nil:
|
||||||
rawMessage(errSystemNeeds, name)
|
rawMessage(errSystemNeeds, name)
|
||||||
|
|
@ -61,7 +53,7 @@ proc getSysMagic*(name: string, m: TMagic): PSym =
|
||||||
proc sysTypeFromName*(name: string): PType =
|
proc sysTypeFromName*(name: string): PType =
|
||||||
result = getSysSym(name).typ
|
result = getSysSym(name).typ
|
||||||
|
|
||||||
proc getSysType(kind: TTypeKind): PType =
|
proc getSysType*(kind: TTypeKind): PType =
|
||||||
result = gSysTypes[kind]
|
result = gSysTypes[kind]
|
||||||
if result == nil:
|
if result == nil:
|
||||||
case kind
|
case kind
|
||||||
|
|
@ -97,6 +89,7 @@ var
|
||||||
proc resetSysTypes* =
|
proc resetSysTypes* =
|
||||||
systemModule = nil
|
systemModule = nil
|
||||||
initStrTable(compilerprocs)
|
initStrTable(compilerprocs)
|
||||||
|
initStrTable(exposed)
|
||||||
for i in low(gSysTypes)..high(gSysTypes):
|
for i in low(gSysTypes)..high(gSysTypes):
|
||||||
gSysTypes[i] = nil
|
gSysTypes[i] = nil
|
||||||
|
|
||||||
|
|
@ -163,8 +156,8 @@ proc setIntLitType*(result: PNode) =
|
||||||
result.typ = getSysType(tyInt64)
|
result.typ = getSysType(tyInt64)
|
||||||
else: internalError(result.info, "invalid int size")
|
else: internalError(result.info, "invalid int size")
|
||||||
|
|
||||||
proc getCompilerProc(name: string): PSym =
|
proc getCompilerProc*(name: string): PSym =
|
||||||
var ident = getIdent(name, hashIgnoreStyle(name))
|
let ident = getIdent(name)
|
||||||
result = strTableGet(compilerprocs, ident)
|
result = strTableGet(compilerprocs, ident)
|
||||||
if result == nil:
|
if result == nil:
|
||||||
result = strTableGet(rodCompilerprocs, ident)
|
result = strTableGet(rodCompilerprocs, ident)
|
||||||
|
|
@ -173,9 +166,22 @@ proc getCompilerProc(name: string): PSym =
|
||||||
if result.kind == skStub: loadStub(result)
|
if result.kind == skStub: loadStub(result)
|
||||||
if result.kind == skAlias: result = result.owner
|
if result.kind == skAlias: result = result.owner
|
||||||
|
|
||||||
proc registerCompilerProc(s: PSym) =
|
proc registerCompilerProc*(s: PSym) =
|
||||||
strTableAdd(compilerprocs, s)
|
strTableAdd(compilerprocs, s)
|
||||||
|
|
||||||
proc finishSystem(tab: TStrTable) = discard
|
proc registerNimScriptSymbol*(s: PSym) =
|
||||||
|
# Nimscript symbols must be al unique:
|
||||||
|
let conflict = strTableGet(exposed, s.name)
|
||||||
|
if conflict == nil:
|
||||||
|
strTableAdd(exposed, s)
|
||||||
|
else:
|
||||||
|
localError(s.info, "symbol conflicts with other .exportNims symbol at: " &
|
||||||
|
$conflict.info)
|
||||||
|
|
||||||
|
proc getNimScriptSymbol*(name: string): PSym =
|
||||||
|
strTableGet(exposed, getIdent(name))
|
||||||
|
|
||||||
|
proc resetNimScriptSymbols*() = initStrTable(exposed)
|
||||||
|
|
||||||
initStrTable(compilerprocs)
|
initStrTable(compilerprocs)
|
||||||
|
initStrTable(exposed)
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,13 @@ proc resetModule*(fileIdx: int32) =
|
||||||
if fileIdx <% cgendata.gModules.len:
|
if fileIdx <% cgendata.gModules.len:
|
||||||
cgendata.gModules[fileIdx] = nil
|
cgendata.gModules[fileIdx] = nil
|
||||||
|
|
||||||
|
proc resetModule*(module: PSym) =
|
||||||
|
let conflict = getModule(module.position.int32)
|
||||||
|
if conflict == nil: return
|
||||||
|
doAssert conflict == module
|
||||||
|
resetModule(module.position.int32)
|
||||||
|
initStrTable(module.tab)
|
||||||
|
|
||||||
proc resetAllModules* =
|
proc resetAllModules* =
|
||||||
for i in 0..gCompiledModules.high:
|
for i in 0..gCompiledModules.high:
|
||||||
if gCompiledModules[i] != nil:
|
if gCompiledModules[i] != nil:
|
||||||
|
|
|
||||||
|
|
@ -25,18 +25,19 @@ const
|
||||||
wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC,
|
wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC,
|
||||||
wAsmNoStackFrame, wError, wDiscardable, wNoInit, wDestructor, wCodegenDecl,
|
wAsmNoStackFrame, wError, wDiscardable, wNoInit, wDestructor, wCodegenDecl,
|
||||||
wGensym, wInject, wRaises, wTags, wLocks, wDelegator, wGcSafe,
|
wGensym, wInject, wRaises, wTags, wLocks, wDelegator, wGcSafe,
|
||||||
wOverride, wConstructor}
|
wOverride, wConstructor, wExportNims}
|
||||||
converterPragmas* = procPragmas
|
converterPragmas* = procPragmas
|
||||||
methodPragmas* = procPragmas+{wBase}
|
methodPragmas* = procPragmas+{wBase}
|
||||||
templatePragmas* = {wImmediate, wDeprecated, wError, wGensym, wInject, wDirty,
|
templatePragmas* = {wImmediate, wDeprecated, wError, wGensym, wInject, wDirty,
|
||||||
wDelegator}
|
wDelegator, wExportNims}
|
||||||
macroPragmas* = {FirstCallConv..LastCallConv, wImmediate, wImportc, wExportc,
|
macroPragmas* = {FirstCallConv..LastCallConv, wImmediate, wImportc, wExportc,
|
||||||
wNodecl, wMagic, wNosideeffect, wCompilerproc, wDeprecated, wExtern,
|
wNodecl, wMagic, wNosideeffect, wCompilerproc, wDeprecated, wExtern,
|
||||||
wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wDelegator}
|
wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wDelegator,
|
||||||
|
wExportNims}
|
||||||
iteratorPragmas* = {FirstCallConv..LastCallConv, wNosideeffect, wSideeffect,
|
iteratorPragmas* = {FirstCallConv..LastCallConv, wNosideeffect, wSideeffect,
|
||||||
wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern,
|
wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern,
|
||||||
wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wRaises,
|
wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wRaises,
|
||||||
wTags, wLocks, wGcSafe}
|
wTags, wLocks, wGcSafe, wExportNims}
|
||||||
exprPragmas* = {wLine, wLocks, wNoRewrite}
|
exprPragmas* = {wLine, wLocks, wNoRewrite}
|
||||||
stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangechecks,
|
stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangechecks,
|
||||||
wBoundchecks, wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints,
|
wBoundchecks, wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints,
|
||||||
|
|
@ -54,15 +55,15 @@ const
|
||||||
wPure, wHeader, wCompilerproc, wFinal, wSize, wExtern, wShallow,
|
wPure, wHeader, wCompilerproc, wFinal, wSize, wExtern, wShallow,
|
||||||
wImportCpp, wImportObjC, wError, wIncompleteStruct, wByCopy, wByRef,
|
wImportCpp, wImportObjC, wError, wIncompleteStruct, wByCopy, wByRef,
|
||||||
wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked,
|
wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked,
|
||||||
wBorrow, wGcSafe}
|
wBorrow, wGcSafe, wExportNims}
|
||||||
fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern,
|
fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern,
|
||||||
wImportCpp, wImportObjC, wError, wGuard, wBitsize}
|
wImportCpp, wImportObjC, wError, wGuard, wBitsize}
|
||||||
varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl,
|
varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl,
|
||||||
wMagic, wHeader, wDeprecated, wCompilerproc, wDynlib, wExtern,
|
wMagic, wHeader, wDeprecated, wCompilerproc, wDynlib, wExtern,
|
||||||
wImportCpp, wImportObjC, wError, wNoInit, wCompileTime, wGlobal,
|
wImportCpp, wImportObjC, wError, wNoInit, wCompileTime, wGlobal,
|
||||||
wGensym, wInject, wCodegenDecl, wGuard, wGoto}
|
wGensym, wInject, wCodegenDecl, wGuard, wGoto, wExportNims}
|
||||||
constPragmas* = {wImportc, wExportc, wHeader, wDeprecated, wMagic, wNodecl,
|
constPragmas* = {wImportc, wExportc, wHeader, wDeprecated, wMagic, wNodecl,
|
||||||
wExtern, wImportCpp, wImportObjC, wError, wGensym, wInject}
|
wExtern, wImportCpp, wImportObjC, wError, wGensym, wInject, wExportNims}
|
||||||
letPragmas* = varPragmas
|
letPragmas* = varPragmas
|
||||||
procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNosideeffect,
|
procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNosideeffect,
|
||||||
wThread, wRaises, wLocks, wTags, wGcSafe}
|
wThread, wRaises, wLocks, wTags, wGcSafe}
|
||||||
|
|
@ -859,6 +860,9 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
|
||||||
invalidPragma(it)
|
invalidPragma(it)
|
||||||
else:
|
else:
|
||||||
sym.flags.incl sfGoto
|
sym.flags.incl sfGoto
|
||||||
|
of wExportNims:
|
||||||
|
if sym == nil: invalidPragma(it)
|
||||||
|
else: magicsys.registerNimScriptSymbol(sym)
|
||||||
of wInjectStmt:
|
of wInjectStmt:
|
||||||
if it.kind != nkExprColonExpr:
|
if it.kind != nkExprColonExpr:
|
||||||
localError(it.info, errExprExpected)
|
localError(it.info, errExprExpected)
|
||||||
|
|
|
||||||
|
|
@ -1411,6 +1411,31 @@ proc execute(c: PCtx, start: int): PNode =
|
||||||
newSeq(tos.slots, c.prc.maxSlots)
|
newSeq(tos.slots, c.prc.maxSlots)
|
||||||
result = rawExecute(c, start, tos).regToNode
|
result = rawExecute(c, start, tos).regToNode
|
||||||
|
|
||||||
|
proc execProc*(c: PCtx; sym: PSym; args: openArray[PNode]): PNode =
|
||||||
|
if sym.kind in routineKinds:
|
||||||
|
if sym.typ.len-1 != args.len:
|
||||||
|
localError(sym.info,
|
||||||
|
"NimScript: expected $# arguments, but got $#" % [
|
||||||
|
$(sym.typ.len-1), $args.len])
|
||||||
|
else:
|
||||||
|
let start = genProc(c, sym)
|
||||||
|
|
||||||
|
var tos = PStackFrame(prc: sym, comesFrom: 0, next: nil)
|
||||||
|
let maxSlots = sym.offset
|
||||||
|
newSeq(tos.slots, maxSlots)
|
||||||
|
|
||||||
|
# setup parameters:
|
||||||
|
if not isEmptyType(sym.typ.sons[0]) or sym.kind == skMacro:
|
||||||
|
putIntoReg(tos.slots[0], getNullValue(sym.typ.sons[0], sym.info))
|
||||||
|
# XXX We could perform some type checking here.
|
||||||
|
for i in 1.. <sym.typ.len:
|
||||||
|
putIntoReg(tos.slots[i], args[i-1])
|
||||||
|
|
||||||
|
result = rawExecute(c, start, tos).regToNode
|
||||||
|
else:
|
||||||
|
localError(sym.info,
|
||||||
|
"NimScript: attempt to call non-routine: " & sym.name.s)
|
||||||
|
|
||||||
proc evalStmt*(c: PCtx, n: PNode) =
|
proc evalStmt*(c: PCtx, n: PNode) =
|
||||||
let n = transformExpr(c.module, n)
|
let n = transformExpr(c.module, n)
|
||||||
let start = genStmt(c, n)
|
let start = genStmt(c, n)
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ type
|
||||||
wImmediate, wConstructor, wDestructor, wDelegator, wOverride,
|
wImmediate, wConstructor, wDestructor, wDelegator, wOverride,
|
||||||
wImportCpp, wImportObjC,
|
wImportCpp, wImportObjC,
|
||||||
wImportCompilerProc,
|
wImportCompilerProc,
|
||||||
wImportc, wExportc, wIncompleteStruct, wRequiresInit,
|
wImportc, wExportc, wExportNims, wIncompleteStruct, wRequiresInit,
|
||||||
wAlign, wNodecl, wPure, wSideeffect, wHeader,
|
wAlign, wNodecl, wPure, wSideeffect, wHeader,
|
||||||
wNosideeffect, wGcSafe, wNoreturn, wMerge, wLib, wDynlib,
|
wNosideeffect, wGcSafe, wNoreturn, wMerge, wLib, wDynlib,
|
||||||
wCompilerproc, wProcVar, wBase,
|
wCompilerproc, wProcVar, wBase,
|
||||||
|
|
@ -126,7 +126,8 @@ const
|
||||||
|
|
||||||
"immediate", "constructor", "destructor", "delegator", "override",
|
"immediate", "constructor", "destructor", "delegator", "override",
|
||||||
"importcpp", "importobjc",
|
"importcpp", "importobjc",
|
||||||
"importcompilerproc", "importc", "exportc", "incompletestruct",
|
"importcompilerproc", "importc", "exportc", "exportnims",
|
||||||
|
"incompletestruct",
|
||||||
"requiresinit", "align", "nodecl", "pure", "sideeffect",
|
"requiresinit", "align", "nodecl", "pure", "sideeffect",
|
||||||
"header", "nosideeffect", "gcsafe", "noreturn", "merge", "lib", "dynlib",
|
"header", "nosideeffect", "gcsafe", "noreturn", "merge", "lib", "dynlib",
|
||||||
"compilerproc", "procvar", "base",
|
"compilerproc", "procvar", "base",
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@ mips.linux.gcc.linkerexe = "mips-openwrt-linux-gcc"
|
||||||
cs:partial
|
cs:partial
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
path="$lib/deprecated/core"
|
||||||
|
path="$lib/deprecated/pure"
|
||||||
path="$lib/pure/collections"
|
path="$lib/pure/collections"
|
||||||
path="$lib/pure/concurrency"
|
path="$lib/pure/concurrency"
|
||||||
path="$lib/impure"
|
path="$lib/impure"
|
||||||
|
|
|
||||||
38
doc/lib.txt
38
doc/lib.txt
|
|
@ -201,12 +201,6 @@ Internet Protocols and Support
|
||||||
* `scgi <scgi.html>`_
|
* `scgi <scgi.html>`_
|
||||||
This module implements helpers for SCGI applications.
|
This module implements helpers for SCGI applications.
|
||||||
|
|
||||||
* `sockets <sockets.html>`_
|
|
||||||
This module implements a simple portable type-safe sockets layer.
|
|
||||||
|
|
||||||
* `asyncio <asyncio.html>`_
|
|
||||||
This module implements an asynchronous event loop for sockets.
|
|
||||||
|
|
||||||
* `browsers <browsers.html>`_
|
* `browsers <browsers.html>`_
|
||||||
This module implements procs for opening URLs with the user's default
|
This module implements procs for opening URLs with the user's default
|
||||||
browser.
|
browser.
|
||||||
|
|
@ -220,9 +214,6 @@ Internet Protocols and Support
|
||||||
* `smtp <smtp.html>`_
|
* `smtp <smtp.html>`_
|
||||||
This module implement a simple SMTP client.
|
This module implement a simple SMTP client.
|
||||||
|
|
||||||
* `ftpclient <ftpclient.html>`_
|
|
||||||
This module implements an FTP client.
|
|
||||||
|
|
||||||
* `cookies <cookies.html>`_
|
* `cookies <cookies.html>`_
|
||||||
This module contains helper procs for parsing and generating cookies.
|
This module contains helper procs for parsing and generating cookies.
|
||||||
|
|
||||||
|
|
@ -253,7 +244,7 @@ Internet Protocols and Support
|
||||||
This module implements a high-level sockets API. It will replace the
|
This module implements a high-level sockets API. It will replace the
|
||||||
``sockets`` module in the future.
|
``sockets`` module in the future.
|
||||||
|
|
||||||
* `rawsockets <rawsockets.html>`_
|
* `nativesockets <nativesockets.html>`_
|
||||||
This module implements a low-level sockets API.
|
This module implements a low-level sockets API.
|
||||||
|
|
||||||
* `selectors <selectors.html>`_
|
* `selectors <selectors.html>`_
|
||||||
|
|
@ -265,8 +256,6 @@ Parsers
|
||||||
|
|
||||||
* `parseopt <parseopt.html>`_
|
* `parseopt <parseopt.html>`_
|
||||||
The ``parseopt`` module implements a command line option parser.
|
The ``parseopt`` module implements a command line option parser.
|
||||||
**Deprecated since version 0.9.3:** Use the `parseopt2
|
|
||||||
<parseopt2.html>`_ module instead.
|
|
||||||
|
|
||||||
* `parseopt2 <parseopt2.html>`_
|
* `parseopt2 <parseopt2.html>`_
|
||||||
The ``parseopt2`` module implements a command line option parser. This
|
The ``parseopt2`` module implements a command line option parser. This
|
||||||
|
|
@ -397,6 +386,31 @@ Modules for JS backend
|
||||||
Declaration of the Document Object Model for the JS backend.
|
Declaration of the Document Object Model for the JS backend.
|
||||||
|
|
||||||
|
|
||||||
|
Deprecated modules
|
||||||
|
------------------
|
||||||
|
|
||||||
|
* `asyncio <asyncio.html>`_
|
||||||
|
This module implements an asynchronous event loop for sockets.
|
||||||
|
**Deprecated since version 0.11.2:**
|
||||||
|
Use the `asyncnet <asyncnet.html>`_ together with the
|
||||||
|
`asyncdispatch <asyncdispatch.html>`_ module instead.
|
||||||
|
|
||||||
|
* `ftpclient <ftpclient.html>`_
|
||||||
|
This module implements an FTP client.
|
||||||
|
**Deprecated since version 0.11.3:**
|
||||||
|
Use the `asyncftpclient <asyncftpclient.html>`_ module instead.
|
||||||
|
|
||||||
|
* `sockets <sockets.html>`_
|
||||||
|
This module implements a simple portable type-safe sockets layer.
|
||||||
|
**Deprecated since version 0.11.2:**
|
||||||
|
Use the `net <net.html>`_ or the `rawsockets <rawsockets.html>`_ module
|
||||||
|
instead.
|
||||||
|
|
||||||
|
* `rawsockets <rawsockets.html>`_
|
||||||
|
**Deprecated since version 0.11.4:**
|
||||||
|
This module has been renamed to `nativesockets <nativesockets.html>`_.
|
||||||
|
|
||||||
|
|
||||||
Impure libraries
|
Impure libraries
|
||||||
================
|
================
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -490,6 +490,11 @@ to an open array parameter.
|
||||||
The openarray type cannot be nested: multidimensional openarrays are not
|
The openarray type cannot be nested: multidimensional openarrays are not
|
||||||
supported because this is seldom needed and cannot be done efficiently.
|
supported because this is seldom needed and cannot be done efficiently.
|
||||||
|
|
||||||
|
.. code-block:: nim
|
||||||
|
proc testOpenArray(x: openArray[int]) = echo repr(x)
|
||||||
|
|
||||||
|
testOpenArray([1,2,3]) # array[]
|
||||||
|
testOpenArray(@[1,2,3]) # seq[]
|
||||||
|
|
||||||
Varargs
|
Varargs
|
||||||
-------
|
-------
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
set -e
|
|
||||||
set -x
|
|
||||||
|
|
||||||
if [ "$1" != "" ]; then
|
|
||||||
exec ./koch install "$1"
|
|
||||||
else
|
|
||||||
exec ./koch install
|
|
||||||
fi
|
|
||||||
9
koch.nim
9
koch.nim
|
|
@ -41,6 +41,7 @@ Options:
|
||||||
Possible Commands:
|
Possible Commands:
|
||||||
boot [options] bootstraps with given command line options
|
boot [options] bootstraps with given command line options
|
||||||
install [bindir] installs to given directory; Unix only!
|
install [bindir] installs to given directory; Unix only!
|
||||||
|
geninstall generate ./install.sh; Unix only!
|
||||||
clean cleans Nim project; removes generated files
|
clean cleans Nim project; removes generated files
|
||||||
web [options] generates the website and the full documentation
|
web [options] generates the website and the full documentation
|
||||||
website [options] generates only the website
|
website [options] generates only the website
|
||||||
|
|
@ -127,9 +128,12 @@ proc nsis(args: string) =
|
||||||
exec(("tools" / "niminst" / "niminst --var:version=$# --var:mingw=mingw$#" &
|
exec(("tools" / "niminst" / "niminst --var:version=$# --var:mingw=mingw$#" &
|
||||||
" nsis compiler/installer.ini") % [VersionAsString, $(sizeof(pointer)*8)])
|
" nsis compiler/installer.ini") % [VersionAsString, $(sizeof(pointer)*8)])
|
||||||
|
|
||||||
|
proc geninstall(args="") =
|
||||||
|
exec("$# cc -r $# --var:version=$# --var:mingw=none --main:compiler/nim.nim scripts compiler/installer.ini $#" %
|
||||||
|
[findNim(), compileNimInst, VersionAsString, args])
|
||||||
|
|
||||||
proc install(args: string) =
|
proc install(args: string) =
|
||||||
exec("$# cc -r $# --var:version=$# --var:mingw=none --main:compiler/nim.nim scripts compiler/installer.ini" %
|
geninstall()
|
||||||
[findNim(), compileNimInst, VersionAsString])
|
|
||||||
exec("sh ./install.sh $#" % args)
|
exec("sh ./install.sh $#" % args)
|
||||||
|
|
||||||
proc web(args: string) =
|
proc web(args: string) =
|
||||||
|
|
@ -373,6 +377,7 @@ of cmdArgument:
|
||||||
of "zip": zip(op.cmdLineRest)
|
of "zip": zip(op.cmdLineRest)
|
||||||
of "xz": xz(op.cmdLineRest)
|
of "xz": xz(op.cmdLineRest)
|
||||||
of "nsis": nsis(op.cmdLineRest)
|
of "nsis": nsis(op.cmdLineRest)
|
||||||
|
of "geninstall": geninstall(op.cmdLineRest)
|
||||||
of "install": install(op.cmdLineRest)
|
of "install": install(op.cmdLineRest)
|
||||||
of "test", "tests": tests(op.cmdLineRest)
|
of "test", "tests": tests(op.cmdLineRest)
|
||||||
of "update":
|
of "update":
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ include "system/inclrtl"
|
||||||
import sockets, strutils, parseutils, times, os, asyncio
|
import sockets, strutils, parseutils, times, os, asyncio
|
||||||
|
|
||||||
from asyncnet import nil
|
from asyncnet import nil
|
||||||
from rawsockets import nil
|
from nativesockets import nil
|
||||||
from asyncdispatch import PFuture
|
from asyncdispatch import PFuture
|
||||||
## **Note**: This module is deprecated since version 0.11.3.
|
## **Note**: This module is deprecated since version 0.11.3.
|
||||||
## You should use the async version of this module
|
## You should use the async version of this module
|
||||||
|
|
@ -55,7 +55,7 @@ type
|
||||||
user*, pass*: string
|
user*, pass*: string
|
||||||
address*: string
|
address*: string
|
||||||
when SockType is asyncnet.AsyncSocket:
|
when SockType is asyncnet.AsyncSocket:
|
||||||
port*: rawsockets.Port
|
port*: nativesockets.Port
|
||||||
else:
|
else:
|
||||||
port*: Port
|
port*: Port
|
||||||
|
|
||||||
14
lib/deprecated/pure/rawsockets.nim
Normal file
14
lib/deprecated/pure/rawsockets.nim
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
import nativesockets
|
||||||
|
export nativesockets
|
||||||
|
|
||||||
|
{.warning: "rawsockets module is deprecated, use nativesockets instead".}
|
||||||
|
|
||||||
|
template newRawSocket*(domain, sockType, protocol: cint): expr =
|
||||||
|
{.warning: "newRawSocket is deprecated, use newNativeSocket instead".}
|
||||||
|
newNativeSocket(domain, sockType, protocol)
|
||||||
|
|
||||||
|
template newRawSocket*(domain: Domain = AF_INET,
|
||||||
|
sockType: SockType = SOCK_STREAM,
|
||||||
|
protocol: Protocol = IPPROTO_TCP): expr =
|
||||||
|
{.warning: "newRawSocket is deprecated, use newNativeSocket instead".}
|
||||||
|
newNativeSocket(domain, sockType, protocol)
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
## **Warning:** Since version 0.10.2 this module is deprecated.
|
## **Warning:** Since version 0.10.2 this module is deprecated.
|
||||||
## Use the `net <net.html>`_ or the
|
## Use the `net <net.html>`_ or the
|
||||||
## `rawsockets <rawsockets.html>`_ module instead.
|
## `nativesockets <nativesockets.html>`_ module instead.
|
||||||
##
|
##
|
||||||
## This module implements portable sockets, it supports a mix of different types
|
## This module implements portable sockets, it supports a mix of different types
|
||||||
## of sockets. Sockets are buffered by default meaning that data will be
|
## of sockets. Sockets are buffered by default meaning that data will be
|
||||||
|
|
@ -11,7 +11,7 @@ include "system/inclrtl"
|
||||||
|
|
||||||
import os, oids, tables, strutils, macros, times
|
import os, oids, tables, strutils, macros, times
|
||||||
|
|
||||||
import rawsockets, net
|
import nativesockets, net
|
||||||
|
|
||||||
export Port, SocketFlag
|
export Port, SocketFlag
|
||||||
|
|
||||||
|
|
@ -475,7 +475,7 @@ when defined(windows) or defined(nimdoc):
|
||||||
addr bytesRet, nil, nil) == 0
|
addr bytesRet, nil, nil) == 0
|
||||||
|
|
||||||
proc initAll() =
|
proc initAll() =
|
||||||
let dummySock = newRawSocket()
|
let dummySock = newNativeSocket()
|
||||||
if not initPointer(dummySock, connectExPtr, WSAID_CONNECTEX):
|
if not initPointer(dummySock, connectExPtr, WSAID_CONNECTEX):
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
if not initPointer(dummySock, acceptExPtr, WSAID_ACCEPTEX):
|
if not initPointer(dummySock, acceptExPtr, WSAID_ACCEPTEX):
|
||||||
|
|
@ -528,7 +528,7 @@ when defined(windows) or defined(nimdoc):
|
||||||
RemoteSockaddr, RemoteSockaddrLength)
|
RemoteSockaddr, RemoteSockaddrLength)
|
||||||
|
|
||||||
proc connect*(socket: AsyncFD, address: string, port: Port,
|
proc connect*(socket: AsyncFD, address: string, port: Port,
|
||||||
domain = rawsockets.AF_INET): Future[void] =
|
domain = nativesockets.AF_INET): Future[void] =
|
||||||
## Connects ``socket`` to server at ``address:port``.
|
## Connects ``socket`` to server at ``address:port``.
|
||||||
##
|
##
|
||||||
## Returns a ``Future`` which will complete when the connection succeeds
|
## Returns a ``Future`` which will complete when the connection succeeds
|
||||||
|
|
@ -827,7 +827,7 @@ when defined(windows) or defined(nimdoc):
|
||||||
verifyPresence(socket)
|
verifyPresence(socket)
|
||||||
var retFuture = newFuture[tuple[address: string, client: AsyncFD]]("acceptAddr")
|
var retFuture = newFuture[tuple[address: string, client: AsyncFD]]("acceptAddr")
|
||||||
|
|
||||||
var clientSock = newRawSocket()
|
var clientSock = newNativeSocket()
|
||||||
if clientSock == osInvalidSocket: raiseOSError(osLastError())
|
if clientSock == osInvalidSocket: raiseOSError(osLastError())
|
||||||
|
|
||||||
const lpOutputLen = 1024
|
const lpOutputLen = 1024
|
||||||
|
|
@ -900,17 +900,17 @@ when defined(windows) or defined(nimdoc):
|
||||||
|
|
||||||
return retFuture
|
return retFuture
|
||||||
|
|
||||||
proc newAsyncRawSocket*(domain, sockType, protocol: cint): AsyncFD =
|
proc newAsyncNativeSocket*(domain, sockType, protocol: cint): AsyncFD =
|
||||||
## Creates a new socket and registers it with the dispatcher implicitly.
|
## Creates a new socket and registers it with the dispatcher implicitly.
|
||||||
result = newRawSocket(domain, sockType, protocol).AsyncFD
|
result = newNativeSocket(domain, sockType, protocol).AsyncFD
|
||||||
result.SocketHandle.setBlocking(false)
|
result.SocketHandle.setBlocking(false)
|
||||||
register(result)
|
register(result)
|
||||||
|
|
||||||
proc newAsyncRawSocket*(domain: Domain = rawsockets.AF_INET,
|
proc newAsyncNativeSocket*(domain: Domain = nativesockets.AF_INET,
|
||||||
sockType: SockType = SOCK_STREAM,
|
sockType: SockType = SOCK_STREAM,
|
||||||
protocol: Protocol = IPPROTO_TCP): AsyncFD =
|
protocol: Protocol = IPPROTO_TCP): AsyncFD =
|
||||||
## Creates a new socket and registers it with the dispatcher implicitly.
|
## Creates a new socket and registers it with the dispatcher implicitly.
|
||||||
result = newRawSocket(domain, sockType, protocol).AsyncFD
|
result = newNativeSocket(domain, sockType, protocol).AsyncFD
|
||||||
result.SocketHandle.setBlocking(false)
|
result.SocketHandle.setBlocking(false)
|
||||||
register(result)
|
register(result)
|
||||||
|
|
||||||
|
|
@ -973,18 +973,18 @@ else:
|
||||||
var data = PData(fd: fd, readCBs: @[], writeCBs: @[])
|
var data = PData(fd: fd, readCBs: @[], writeCBs: @[])
|
||||||
p.selector.register(fd.SocketHandle, {}, data.RootRef)
|
p.selector.register(fd.SocketHandle, {}, data.RootRef)
|
||||||
|
|
||||||
proc newAsyncRawSocket*(domain: cint, sockType: cint,
|
proc newAsyncNativeSocket*(domain: cint, sockType: cint,
|
||||||
protocol: cint): AsyncFD =
|
protocol: cint): AsyncFD =
|
||||||
result = newRawSocket(domain, sockType, protocol).AsyncFD
|
result = newNativeSocket(domain, sockType, protocol).AsyncFD
|
||||||
result.SocketHandle.setBlocking(false)
|
result.SocketHandle.setBlocking(false)
|
||||||
when defined(macosx):
|
when defined(macosx):
|
||||||
result.SocketHandle.setSockOptInt(SOL_SOCKET, SO_NOSIGPIPE, 1)
|
result.SocketHandle.setSockOptInt(SOL_SOCKET, SO_NOSIGPIPE, 1)
|
||||||
register(result)
|
register(result)
|
||||||
|
|
||||||
proc newAsyncRawSocket*(domain: Domain = AF_INET,
|
proc newAsyncNativeSocket*(domain: Domain = AF_INET,
|
||||||
sockType: SockType = SOCK_STREAM,
|
sockType: SockType = SOCK_STREAM,
|
||||||
protocol: Protocol = IPPROTO_TCP): AsyncFD =
|
protocol: Protocol = IPPROTO_TCP): AsyncFD =
|
||||||
result = newRawSocket(domain, sockType, protocol).AsyncFD
|
result = newNativeSocket(domain, sockType, protocol).AsyncFD
|
||||||
result.SocketHandle.setBlocking(false)
|
result.SocketHandle.setBlocking(false)
|
||||||
when defined(macosx):
|
when defined(macosx):
|
||||||
result.SocketHandle.setSockOptInt(SOL_SOCKET, SO_NOSIGPIPE, 1)
|
result.SocketHandle.setSockOptInt(SOL_SOCKET, SO_NOSIGPIPE, 1)
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@
|
||||||
##
|
##
|
||||||
|
|
||||||
import asyncdispatch
|
import asyncdispatch
|
||||||
import rawsockets
|
import nativesockets
|
||||||
import net
|
import net
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
@ -112,8 +112,8 @@ proc newAsyncSocket*(domain: Domain = AF_INET, sockType: SockType = SOCK_STREAM,
|
||||||
##
|
##
|
||||||
## This procedure will also create a brand new file descriptor for
|
## This procedure will also create a brand new file descriptor for
|
||||||
## this socket.
|
## this socket.
|
||||||
result = newAsyncSocket(newAsyncRawSocket(domain, sockType, protocol), domain,
|
result = newAsyncSocket(newAsyncNativeSocket(domain, sockType, protocol),
|
||||||
sockType, protocol, buffered)
|
domain, sockType, protocol, buffered)
|
||||||
|
|
||||||
proc newAsyncSocket*(domain, sockType, protocol: cint,
|
proc newAsyncSocket*(domain, sockType, protocol: cint,
|
||||||
buffered = true): AsyncSocket =
|
buffered = true): AsyncSocket =
|
||||||
|
|
@ -121,8 +121,9 @@ proc newAsyncSocket*(domain, sockType, protocol: cint,
|
||||||
##
|
##
|
||||||
## This procedure will also create a brand new file descriptor for
|
## This procedure will also create a brand new file descriptor for
|
||||||
## this socket.
|
## this socket.
|
||||||
result = newAsyncSocket(newAsyncRawSocket(domain, sockType, protocol),
|
result = newAsyncSocket(newAsyncNativeSocket(domain, sockType, protocol),
|
||||||
Domain(domain), SockType(sockType), Protocol(protocol), buffered)
|
Domain(domain), SockType(sockType),
|
||||||
|
Protocol(protocol), buffered)
|
||||||
|
|
||||||
when defined(ssl):
|
when defined(ssl):
|
||||||
proc getSslError(handle: SslPtr, err: cint): cint =
|
proc getSslError(handle: SslPtr, err: cint): cint =
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,14 @@ proc containsOrIncl*(c: var CritBitTree[void], key: string): bool =
|
||||||
var n = rawInsert(c, key)
|
var n = rawInsert(c, key)
|
||||||
result = c.count == oldCount
|
result = c.count == oldCount
|
||||||
|
|
||||||
|
proc inc*(c: var CritBitTree[int]; key: string) =
|
||||||
|
## counts the 'key'.
|
||||||
|
let oldCount = c.count
|
||||||
|
var n = rawInsert(c, key)
|
||||||
|
if c.count == oldCount:
|
||||||
|
# not a new key:
|
||||||
|
inc n.val
|
||||||
|
|
||||||
proc incl*(c: var CritBitTree[void], key: string) =
|
proc incl*(c: var CritBitTree[void], key: string) =
|
||||||
## includes `key` in `c`.
|
## includes `key` in `c`.
|
||||||
discard rawInsert(c, key)
|
discard rawInsert(c, key)
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@
|
||||||
|
|
||||||
import net, strutils, uri, parseutils, strtabs, base64, os, mimetypes, math
|
import net, strutils, uri, parseutils, strtabs, base64, os, mimetypes, math
|
||||||
import asyncnet, asyncdispatch
|
import asyncnet, asyncdispatch
|
||||||
import rawsockets
|
import nativesockets
|
||||||
|
|
||||||
type
|
type
|
||||||
Response* = tuple[
|
Response* = tuple[
|
||||||
|
|
@ -764,10 +764,10 @@ proc newConnection(client: AsyncHttpClient, url: Uri) {.async.} =
|
||||||
let port =
|
let port =
|
||||||
if url.port == "":
|
if url.port == "":
|
||||||
if url.scheme.toLower() == "https":
|
if url.scheme.toLower() == "https":
|
||||||
rawsockets.Port(443)
|
nativesockets.Port(443)
|
||||||
else:
|
else:
|
||||||
rawsockets.Port(80)
|
nativesockets.Port(80)
|
||||||
else: rawsockets.Port(url.port.parseInt)
|
else: nativesockets.Port(url.port.parseInt)
|
||||||
|
|
||||||
if url.scheme.toLower() == "https":
|
if url.scheme.toLower() == "https":
|
||||||
when defined(ssl):
|
when defined(ssl):
|
||||||
|
|
|
||||||
|
|
@ -93,8 +93,8 @@ when useWinVersion:
|
||||||
IOC_IN* = int(-2147483648)
|
IOC_IN* = int(-2147483648)
|
||||||
FIONBIO* = IOC_IN.int32 or ((sizeof(int32) and IOCPARM_MASK) shl 16) or
|
FIONBIO* = IOC_IN.int32 or ((sizeof(int32) and IOCPARM_MASK) shl 16) or
|
||||||
(102 shl 8) or 126
|
(102 shl 8) or 126
|
||||||
rawAfInet = winlean.AF_INET
|
nativeAfInet = winlean.AF_INET
|
||||||
rawAfInet6 = winlean.AF_INET6
|
nativeAfInet6 = winlean.AF_INET6
|
||||||
|
|
||||||
proc ioctlsocket*(s: SocketHandle, cmd: clong,
|
proc ioctlsocket*(s: SocketHandle, cmd: clong,
|
||||||
argptr: ptr clong): cint {.
|
argptr: ptr clong): cint {.
|
||||||
|
|
@ -102,8 +102,8 @@ when useWinVersion:
|
||||||
else:
|
else:
|
||||||
let
|
let
|
||||||
osInvalidSocket* = posix.INVALID_SOCKET
|
osInvalidSocket* = posix.INVALID_SOCKET
|
||||||
rawAfInet = posix.AF_INET
|
nativeAfInet = posix.AF_INET
|
||||||
rawAfInet6 = posix.AF_INET6
|
nativeAfInet6 = posix.AF_INET6
|
||||||
|
|
||||||
proc `==`*(a, b: Port): bool {.borrow.}
|
proc `==`*(a, b: Port): bool {.borrow.}
|
||||||
## ``==`` for ports.
|
## ``==`` for ports.
|
||||||
|
|
@ -157,12 +157,14 @@ else:
|
||||||
result = cint(ord(p))
|
result = cint(ord(p))
|
||||||
|
|
||||||
|
|
||||||
proc newRawSocket*(domain: Domain = AF_INET, sockType: SockType = SOCK_STREAM,
|
proc newNativeSocket*(domain: Domain = AF_INET,
|
||||||
protocol: Protocol = IPPROTO_TCP): SocketHandle =
|
sockType: SockType = SOCK_STREAM,
|
||||||
|
protocol: Protocol = IPPROTO_TCP): SocketHandle =
|
||||||
## Creates a new socket; returns `InvalidSocket` if an error occurs.
|
## Creates a new socket; returns `InvalidSocket` if an error occurs.
|
||||||
socket(toInt(domain), toInt(sockType), toInt(protocol))
|
socket(toInt(domain), toInt(sockType), toInt(protocol))
|
||||||
|
|
||||||
proc newRawSocket*(domain: cint, sockType: cint, protocol: cint): SocketHandle =
|
proc newNativeSocket*(domain: cint, sockType: cint,
|
||||||
|
protocol: cint): SocketHandle =
|
||||||
## Creates a new socket; returns `InvalidSocket` if an error occurs.
|
## Creates a new socket; returns `InvalidSocket` if an error occurs.
|
||||||
##
|
##
|
||||||
## Use this overload if one of the enums specified above does
|
## Use this overload if one of the enums specified above does
|
||||||
|
|
@ -201,7 +203,9 @@ proc getAddrInfo*(address: string, port: Port, domain: Domain = AF_INET,
|
||||||
hints.ai_family = toInt(domain)
|
hints.ai_family = toInt(domain)
|
||||||
hints.ai_socktype = toInt(sockType)
|
hints.ai_socktype = toInt(sockType)
|
||||||
hints.ai_protocol = toInt(protocol)
|
hints.ai_protocol = toInt(protocol)
|
||||||
hints.ai_flags = AI_V4MAPPED
|
# https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=198092
|
||||||
|
when not defined(freebsd):
|
||||||
|
hints.ai_flags = AI_V4MAPPED
|
||||||
var gaiResult = getaddrinfo(address, $port, addr(hints), result)
|
var gaiResult = getaddrinfo(address, $port, addr(hints), result)
|
||||||
if gaiResult != 0'i32:
|
if gaiResult != 0'i32:
|
||||||
when useWinVersion:
|
when useWinVersion:
|
||||||
|
|
@ -229,17 +233,17 @@ proc ntohs*(x: int16): int16 =
|
||||||
when cpuEndian == bigEndian: result = x
|
when cpuEndian == bigEndian: result = x
|
||||||
else: result = (x shr 8'i16) or (x shl 8'i16)
|
else: result = (x shr 8'i16) or (x shl 8'i16)
|
||||||
|
|
||||||
proc htonl*(x: int32): int32 =
|
template htonl*(x: int32): expr =
|
||||||
## Converts 32-bit integers from host to network byte order. On machines
|
## Converts 32-bit integers from host to network byte order. On machines
|
||||||
## where the host byte order is the same as network byte order, this is
|
## where the host byte order is the same as network byte order, this is
|
||||||
## a no-op; otherwise, it performs a 4-byte swap operation.
|
## a no-op; otherwise, it performs a 4-byte swap operation.
|
||||||
result = rawsockets.ntohl(x)
|
nativesockets.ntohl(x)
|
||||||
|
|
||||||
proc htons*(x: int16): int16 =
|
template htons*(x: int16): expr =
|
||||||
## Converts 16-bit positive integers from host to network byte order.
|
## Converts 16-bit positive integers from host to network byte order.
|
||||||
## On machines where the host byte order is the same as network byte
|
## On machines where the host byte order is the same as network byte
|
||||||
## order, this is a no-op; otherwise, it performs a 2-byte swap operation.
|
## order, this is a no-op; otherwise, it performs a 2-byte swap operation.
|
||||||
result = rawsockets.ntohs(x)
|
nativesockets.ntohs(x)
|
||||||
|
|
||||||
proc getServByName*(name, proto: string): Servent {.tags: [ReadIOEffect].} =
|
proc getServByName*(name, proto: string): Servent {.tags: [ReadIOEffect].} =
|
||||||
## Searches the database from the beginning and finds the first entry for
|
## Searches the database from the beginning and finds the first entry for
|
||||||
|
|
@ -280,7 +284,7 @@ proc getHostByAddr*(ip: string): Hostent {.tags: [ReadIOEffect].} =
|
||||||
|
|
||||||
when useWinVersion:
|
when useWinVersion:
|
||||||
var s = winlean.gethostbyaddr(addr(myaddr), sizeof(myaddr).cuint,
|
var s = winlean.gethostbyaddr(addr(myaddr), sizeof(myaddr).cuint,
|
||||||
cint(rawsockets.AF_INET))
|
cint(AF_INET))
|
||||||
if s == nil: raiseOSError(osLastError())
|
if s == nil: raiseOSError(osLastError())
|
||||||
else:
|
else:
|
||||||
var s = posix.gethostbyaddr(addr(myaddr), sizeof(myaddr).Socklen,
|
var s = posix.gethostbyaddr(addr(myaddr), sizeof(myaddr).Socklen,
|
||||||
|
|
@ -330,9 +334,9 @@ proc getSockDomain*(socket: SocketHandle): Domain =
|
||||||
if getsockname(socket, cast[ptr SockAddr](addr(name)),
|
if getsockname(socket, cast[ptr SockAddr](addr(name)),
|
||||||
addr(namelen)) == -1'i32:
|
addr(namelen)) == -1'i32:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
if name.sa_family == rawAfInet:
|
if name.sa_family == nativeAfInet:
|
||||||
result = AF_INET
|
result = AF_INET
|
||||||
elif name.sa_family == rawAfInet6:
|
elif name.sa_family == nativeAfInet6:
|
||||||
result = AF_INET6
|
result = AF_INET6
|
||||||
else:
|
else:
|
||||||
raiseOSError(osLastError(), "unknown socket family in getSockFamily")
|
raiseOSError(osLastError(), "unknown socket family in getSockFamily")
|
||||||
|
|
@ -340,9 +344,9 @@ proc getSockDomain*(socket: SocketHandle): Domain =
|
||||||
|
|
||||||
proc getAddrString*(sockAddr: ptr SockAddr): string =
|
proc getAddrString*(sockAddr: ptr SockAddr): string =
|
||||||
## return the string representation of address within sockAddr
|
## return the string representation of address within sockAddr
|
||||||
if sockAddr.sa_family == rawAfInet:
|
if sockAddr.sa_family == nativeAfInet:
|
||||||
result = $inet_ntoa(cast[ptr Sockaddr_in](sockAddr).sin_addr)
|
result = $inet_ntoa(cast[ptr Sockaddr_in](sockAddr).sin_addr)
|
||||||
elif sockAddr.sa_family == rawAfInet6:
|
elif sockAddr.sa_family == nativeAfInet6:
|
||||||
when not useWinVersion:
|
when not useWinVersion:
|
||||||
# TODO: Windows
|
# TODO: Windows
|
||||||
result = newString(posix.INET6_ADDRSTRLEN)
|
result = newString(posix.INET6_ADDRSTRLEN)
|
||||||
|
|
@ -368,7 +372,7 @@ proc getSockName*(socket: SocketHandle): Port =
|
||||||
if getsockname(socket, cast[ptr SockAddr](addr(name)),
|
if getsockname(socket, cast[ptr SockAddr](addr(name)),
|
||||||
addr(namelen)) == -1'i32:
|
addr(namelen)) == -1'i32:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
result = Port(rawsockets.ntohs(name.sin_port))
|
result = Port(nativesockets.ntohs(name.sin_port))
|
||||||
|
|
||||||
proc getLocalAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
|
proc getLocalAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
|
||||||
## returns the socket's local address and port number.
|
## returns the socket's local address and port number.
|
||||||
|
|
@ -385,7 +389,8 @@ proc getLocalAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
|
||||||
if getsockname(socket, cast[ptr SockAddr](addr(name)),
|
if getsockname(socket, cast[ptr SockAddr](addr(name)),
|
||||||
addr(namelen)) == -1'i32:
|
addr(namelen)) == -1'i32:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
result = ($inet_ntoa(name.sin_addr), Port(rawsockets.ntohs(name.sin_port)))
|
result = ($inet_ntoa(name.sin_addr),
|
||||||
|
Port(nativesockets.ntohs(name.sin_port)))
|
||||||
of AF_INET6:
|
of AF_INET6:
|
||||||
var name: Sockaddr_in6
|
var name: Sockaddr_in6
|
||||||
when useWinVersion:
|
when useWinVersion:
|
||||||
|
|
@ -401,7 +406,7 @@ proc getLocalAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
|
||||||
if inet_ntop(name.sin6_family.cint,
|
if inet_ntop(name.sin6_family.cint,
|
||||||
addr name, buf.cstring, sizeof(buf).int32).isNil:
|
addr name, buf.cstring, sizeof(buf).int32).isNil:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
result = ($buf, Port(rawsockets.ntohs(name.sin6_port)))
|
result = ($buf, Port(nativesockets.ntohs(name.sin6_port)))
|
||||||
else:
|
else:
|
||||||
raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr")
|
raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr")
|
||||||
|
|
||||||
|
|
@ -420,7 +425,8 @@ proc getPeerAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
|
||||||
if getpeername(socket, cast[ptr SockAddr](addr(name)),
|
if getpeername(socket, cast[ptr SockAddr](addr(name)),
|
||||||
addr(namelen)) == -1'i32:
|
addr(namelen)) == -1'i32:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
result = ($inet_ntoa(name.sin_addr), Port(rawsockets.ntohs(name.sin_port)))
|
result = ($inet_ntoa(name.sin_addr),
|
||||||
|
Port(nativesockets.ntohs(name.sin_port)))
|
||||||
of AF_INET6:
|
of AF_INET6:
|
||||||
var name: Sockaddr_in6
|
var name: Sockaddr_in6
|
||||||
when useWinVersion:
|
when useWinVersion:
|
||||||
|
|
@ -436,7 +442,7 @@ proc getPeerAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
|
||||||
if inet_ntop(name.sin6_family.cint,
|
if inet_ntop(name.sin6_family.cint,
|
||||||
addr name, buf.cstring, sizeof(buf).int32).isNil:
|
addr name, buf.cstring, sizeof(buf).int32).isNil:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
result = ($buf, Port(rawsockets.ntohs(name.sin6_port)))
|
result = ($buf, Port(nativesockets.ntohs(name.sin6_port)))
|
||||||
else:
|
else:
|
||||||
raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr")
|
raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr")
|
||||||
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
## This module implements a high-level cross-platform sockets interface.
|
## This module implements a high-level cross-platform sockets interface.
|
||||||
|
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.}
|
||||||
import rawsockets, os, strutils, unsigned, parseutils, times
|
import nativesockets, os, strutils, unsigned, parseutils, times
|
||||||
export Port, `$`, `==`
|
export Port, `$`, `==`
|
||||||
|
|
||||||
const useWinVersion = defined(Windows) or defined(nimdoc)
|
const useWinVersion = defined(Windows) or defined(nimdoc)
|
||||||
|
|
@ -145,7 +145,7 @@ proc newSocket*(domain, sockType, protocol: cint, buffered = true): Socket =
|
||||||
## Creates a new socket.
|
## Creates a new socket.
|
||||||
##
|
##
|
||||||
## If an error occurs EOS will be raised.
|
## If an error occurs EOS will be raised.
|
||||||
let fd = newRawSocket(domain, sockType, protocol)
|
let fd = newNativeSocket(domain, sockType, protocol)
|
||||||
if fd == osInvalidSocket:
|
if fd == osInvalidSocket:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
result = newSocket(fd, domain.Domain, sockType.SockType, protocol.Protocol,
|
result = newSocket(fd, domain.Domain, sockType.SockType, protocol.Protocol,
|
||||||
|
|
@ -156,7 +156,7 @@ proc newSocket*(domain: Domain = AF_INET, sockType: SockType = SOCK_STREAM,
|
||||||
## Creates a new socket.
|
## Creates a new socket.
|
||||||
##
|
##
|
||||||
## If an error occurs EOS will be raised.
|
## If an error occurs EOS will be raised.
|
||||||
let fd = newRawSocket(domain, sockType, protocol)
|
let fd = newNativeSocket(domain, sockType, protocol)
|
||||||
if fd == osInvalidSocket:
|
if fd == osInvalidSocket:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
result = newSocket(fd, domain, sockType, protocol, buffered)
|
result = newSocket(fd, domain, sockType, protocol, buffered)
|
||||||
|
|
@ -354,7 +354,7 @@ proc listen*(socket: Socket, backlog = SOMAXCONN) {.tags: [ReadIOEffect].} =
|
||||||
## queue of pending connections.
|
## queue of pending connections.
|
||||||
##
|
##
|
||||||
## Raises an EOS error upon failure.
|
## Raises an EOS error upon failure.
|
||||||
if rawsockets.listen(socket.fd, backlog) < 0'i32:
|
if nativesockets.listen(socket.fd, backlog) < 0'i32:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
|
|
||||||
proc bindAddr*(socket: Socket, port = Port(0), address = "") {.
|
proc bindAddr*(socket: Socket, port = Port(0), address = "") {.
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,63 @@ proc toRational*[T:SomeInteger](x: T): Rational[T] =
|
||||||
result.num = x
|
result.num = x
|
||||||
result.den = 1
|
result.den = 1
|
||||||
|
|
||||||
|
proc toRationalSub(x: float, n: int): Rational[int] =
|
||||||
|
var
|
||||||
|
a = 0
|
||||||
|
b, c, d = 1
|
||||||
|
result = 0 // 1 # rational 0
|
||||||
|
while b <= n and d <= n:
|
||||||
|
let ac = (a+c)
|
||||||
|
let bd = (b+d)
|
||||||
|
# scale by 1000 so not overflow for high precision
|
||||||
|
let mediant = (ac/1000) / (bd/1000)
|
||||||
|
if x == mediant:
|
||||||
|
if bd <= n:
|
||||||
|
result.num = ac
|
||||||
|
result.den = bd
|
||||||
|
return result
|
||||||
|
elif d > b:
|
||||||
|
result.num = c
|
||||||
|
result.den = d
|
||||||
|
return result
|
||||||
|
else:
|
||||||
|
result.num = a
|
||||||
|
result.den = b
|
||||||
|
return result
|
||||||
|
elif x > mediant:
|
||||||
|
a = ac
|
||||||
|
b = bd
|
||||||
|
else:
|
||||||
|
c = ac
|
||||||
|
d = bd
|
||||||
|
if (b > n):
|
||||||
|
return initRational(c, d)
|
||||||
|
return initRational(a, b)
|
||||||
|
|
||||||
|
proc toRational*(x: float, n: int = high(int)): Rational[int] =
|
||||||
|
## Calculate the best rational numerator and denominator
|
||||||
|
## that approximates to `x`, where the denominator is
|
||||||
|
## smaller than `n` (default is the largest possible
|
||||||
|
## int to give maximum resolution)
|
||||||
|
##
|
||||||
|
## The algorithm is based on the Farey sequence named
|
||||||
|
## after John Farey
|
||||||
|
##
|
||||||
|
## .. code-block:: Nim
|
||||||
|
## import math, rationals
|
||||||
|
## for i in 1..10:
|
||||||
|
## let t = (10 ^ (i+3)).int
|
||||||
|
## let x = toRational(PI, t)
|
||||||
|
## let newPI = x.num / x.den
|
||||||
|
## echo x, " ", newPI, " error: ", PI - newPI, " ", t
|
||||||
|
if x > 1:
|
||||||
|
result = toRationalSub(1.0/x, n)
|
||||||
|
swap(result.num, result.den)
|
||||||
|
elif x == 1.0:
|
||||||
|
result = 1 // 1
|
||||||
|
else:
|
||||||
|
result = toRationalSub(x, n)
|
||||||
|
|
||||||
proc toFloat*[T](x: Rational[T]): float =
|
proc toFloat*[T](x: Rational[T]): float =
|
||||||
## Convert a rational number `x` to a float.
|
## Convert a rational number `x` to a float.
|
||||||
x.num / x.den
|
x.num / x.den
|
||||||
|
|
@ -288,3 +345,8 @@ when isMainModule:
|
||||||
assert toRational(5) == 5//1
|
assert toRational(5) == 5//1
|
||||||
assert abs(toFloat(y) - 0.4814814814814815) < 1.0e-7
|
assert abs(toFloat(y) - 0.4814814814814815) < 1.0e-7
|
||||||
assert toInt(z) == 0
|
assert toInt(z) == 0
|
||||||
|
|
||||||
|
assert toRational(0.98765432) == 12345679 // 12500000
|
||||||
|
assert toRational(0.1, 1000000) == 1 // 10
|
||||||
|
assert toRational(0.9, 1000000) == 9 // 10
|
||||||
|
assert toRational(PI) == 80143857 // 25510582
|
||||||
|
|
|
||||||
|
|
@ -173,6 +173,9 @@ proc clear*(s: StringTableRef, mode: StringTableMode) =
|
||||||
s.mode = mode
|
s.mode = mode
|
||||||
s.counter = 0
|
s.counter = 0
|
||||||
s.data.setLen(startSize)
|
s.data.setLen(startSize)
|
||||||
|
for i in 0..<s.data.len:
|
||||||
|
if not isNil(s.data[i].key):
|
||||||
|
s.data[i].key = nil
|
||||||
|
|
||||||
proc newStringTable*(keyValuePairs: varargs[string],
|
proc newStringTable*(keyValuePairs: varargs[string],
|
||||||
mode: StringTableMode): StringTableRef {.
|
mode: StringTableMode): StringTableRef {.
|
||||||
|
|
@ -248,3 +251,6 @@ when isMainModule:
|
||||||
x.mget("11") = "23"
|
x.mget("11") = "23"
|
||||||
assert x["11"] == "23"
|
assert x["11"] == "23"
|
||||||
|
|
||||||
|
x.clear(modeCaseInsensitive)
|
||||||
|
x["11"] = "22"
|
||||||
|
assert x["11"] == "22"
|
||||||
|
|
|
||||||
|
|
@ -169,7 +169,8 @@ proc cmpIgnoreStyle*(a, b: string): int {.noSideEffect,
|
||||||
inc(j)
|
inc(j)
|
||||||
|
|
||||||
|
|
||||||
proc strip*(s: string, leading = true, trailing = true, chars: set[char] = Whitespace): string
|
proc strip*(s: string, leading = true, trailing = true,
|
||||||
|
chars: set[char] = Whitespace): string
|
||||||
{.noSideEffect, rtl, extern: "nsuStrip".} =
|
{.noSideEffect, rtl, extern: "nsuStrip".} =
|
||||||
## Strips `chars` from `s` and returns the resulting string.
|
## Strips `chars` from `s` and returns the resulting string.
|
||||||
##
|
##
|
||||||
|
|
@ -504,7 +505,8 @@ proc repeat*(c: char, count: Natural): string {.noSideEffect,
|
||||||
##
|
##
|
||||||
## .. code-block:: nim
|
## .. code-block:: nim
|
||||||
## proc tabexpand(indent: int, text: string, tabsize: int = 4) =
|
## proc tabexpand(indent: int, text: string, tabsize: int = 4) =
|
||||||
## echo '\t'.repeat(indent div tabsize), ' '.repeat(indent mod tabsize), text
|
## echo '\t'.repeat(indent div tabsize), ' '.repeat(indent mod tabsize),
|
||||||
|
## text
|
||||||
##
|
##
|
||||||
## tabexpand(4, "At four")
|
## tabexpand(4, "At four")
|
||||||
## tabexpand(5, "At five")
|
## tabexpand(5, "At five")
|
||||||
|
|
@ -533,11 +535,13 @@ template spaces*(n: Natural): string = repeat(' ',n)
|
||||||
## echo text1 & spaces(max(0, width - text1.len)) & "|"
|
## echo text1 & spaces(max(0, width - text1.len)) & "|"
|
||||||
## echo text2 & spaces(max(0, width - text2.len)) & "|"
|
## echo text2 & spaces(max(0, width - text2.len)) & "|"
|
||||||
|
|
||||||
proc repeatChar*(count: Natural, c: char = ' '): string {.deprecated.} = repeat(c, count)
|
proc repeatChar*(count: Natural, c: char = ' '): string {.deprecated.} =
|
||||||
## deprecated: use repeat() or spaces()
|
## deprecated: use repeat() or spaces()
|
||||||
|
repeat(c, count)
|
||||||
|
|
||||||
proc repeatStr*(count: Natural, s: string): string {.deprecated.} = repeat(s, count)
|
proc repeatStr*(count: Natural, s: string): string {.deprecated.} =
|
||||||
## deprecated: use repeat(string, count) or string.repeat(count)
|
## deprecated: use repeat(string, count) or string.repeat(count)
|
||||||
|
repeat(s, count)
|
||||||
|
|
||||||
proc align*(s: string, count: Natural, padding = ' '): string {.
|
proc align*(s: string, count: Natural, padding = ' '): string {.
|
||||||
noSideEffect, rtl, extern: "nsuAlignString".} =
|
noSideEffect, rtl, extern: "nsuAlignString".} =
|
||||||
|
|
@ -850,8 +854,8 @@ proc rfind*(s: string, sub: char, start: int = -1): int {.noSideEffect,
|
||||||
if sub == s[i]: return i
|
if sub == s[i]: return i
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
proc count*(s: string, sub: string, overlapping: bool = false): int {.noSideEffect,
|
proc count*(s: string, sub: string, overlapping: bool = false): int {.
|
||||||
rtl, extern: "nsuCountString".} =
|
noSideEffect, rtl, extern: "nsuCountString".} =
|
||||||
## Count the occurrences of a substring `sub` in the string `s`.
|
## Count the occurrences of a substring `sub` in the string `s`.
|
||||||
## Overlapping occurrences of `sub` only count when `overlapping`
|
## Overlapping occurrences of `sub` only count when `overlapping`
|
||||||
## is set to true.
|
## is set to true.
|
||||||
|
|
@ -1449,7 +1453,8 @@ proc removeSuffix*(s: var string, chars: set[char] = Newlines) {.
|
||||||
|
|
||||||
s.setLen(last + 1)
|
s.setLen(last + 1)
|
||||||
|
|
||||||
proc removeSuffix*(s: var string, c: char) {.rtl, extern: "nsuRemoveSuffixChar".} =
|
proc removeSuffix*(s: var string, c: char) {.
|
||||||
|
rtl, extern: "nsuRemoveSuffixChar".} =
|
||||||
## Removes a single character (in-place) from a string.
|
## Removes a single character (in-place) from a string.
|
||||||
## .. code-block:: nim
|
## .. code-block:: nim
|
||||||
## var
|
## var
|
||||||
|
|
@ -1515,7 +1520,8 @@ when isMainModule:
|
||||||
doAssert strip("sfoofoofoos", chars = {'s'}) == "foofoofoo"
|
doAssert strip("sfoofoofoos", chars = {'s'}) == "foofoofoo"
|
||||||
doAssert strip("barfoofoofoobar", chars = {'b', 'a', 'r'}) == "foofoofoo"
|
doAssert strip("barfoofoofoobar", chars = {'b', 'a', 'r'}) == "foofoofoo"
|
||||||
doAssert strip("stripme but don't strip this stripme",
|
doAssert strip("stripme but don't strip this stripme",
|
||||||
chars = {'s', 't', 'r', 'i', 'p', 'm', 'e'}) == " but don't strip this "
|
chars = {'s', 't', 'r', 'i', 'p', 'm', 'e'}) ==
|
||||||
|
" but don't strip this "
|
||||||
doAssert strip("sfoofoofoos", leading = false, chars = {'s'}) == "sfoofoofoo"
|
doAssert strip("sfoofoofoos", leading = false, chars = {'s'}) == "sfoofoofoo"
|
||||||
doAssert strip("sfoofoofoos", trailing = false, chars = {'s'}) == "foofoofoos"
|
doAssert strip("sfoofoofoos", trailing = false, chars = {'s'}) == "foofoofoos"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,8 @@ proc moveFile(src, dest: string) {.
|
||||||
tags: [ReadIOEffect, WriteIOEffect], raises: [OSError].} = builtin
|
tags: [ReadIOEffect, WriteIOEffect], raises: [OSError].} = builtin
|
||||||
proc copyFile(src, dest: string) {.
|
proc copyFile(src, dest: string) {.
|
||||||
tags: [ReadIOEffect, WriteIOEffect], raises: [OSError].} = builtin
|
tags: [ReadIOEffect, WriteIOEffect], raises: [OSError].} = builtin
|
||||||
proc createDir(dir: string) {.tags: [WriteIOEffect], raises: [OSError].} = builtin
|
proc createDir(dir: string) {.tags: [WriteIOEffect], raises: [OSError].} =
|
||||||
|
builtin
|
||||||
proc getOsError: string = builtin
|
proc getOsError: string = builtin
|
||||||
proc setCurrentDir(dir: string) = builtin
|
proc setCurrentDir(dir: string) = builtin
|
||||||
proc getCurrentDir(): string = builtin
|
proc getCurrentDir(): string = builtin
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ const
|
||||||
type
|
type
|
||||||
Handle* = int
|
Handle* = int
|
||||||
LONG* = int32
|
LONG* = int32
|
||||||
ULONG* = int
|
ULONG* = int32
|
||||||
PULONG* = ptr int
|
PULONG* = ptr int
|
||||||
WINBOOL* = int32
|
WINBOOL* = int32
|
||||||
DWORD* = int32
|
DWORD* = int32
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ discard """
|
||||||
file: "tasyncawait.nim"
|
file: "tasyncawait.nim"
|
||||||
output: "5000"
|
output: "5000"
|
||||||
"""
|
"""
|
||||||
import asyncdispatch, rawsockets, net, strutils, os
|
import asyncdispatch, nativesockets, net, strutils, os
|
||||||
|
|
||||||
var msgCount = 0
|
var msgCount = 0
|
||||||
|
|
||||||
|
|
@ -18,7 +18,7 @@ proc sendMessages(client: TAsyncFD) {.async.} =
|
||||||
|
|
||||||
proc launchSwarm(port: TPort) {.async.} =
|
proc launchSwarm(port: TPort) {.async.} =
|
||||||
for i in 0 .. <swarmSize:
|
for i in 0 .. <swarmSize:
|
||||||
var sock = newAsyncRawSocket()
|
var sock = newAsyncNativeSocket()
|
||||||
|
|
||||||
await connect(sock, "localhost", port)
|
await connect(sock, "localhost", port)
|
||||||
await sendMessages(sock)
|
await sendMessages(sock)
|
||||||
|
|
@ -38,7 +38,7 @@ proc readMessages(client: TAsyncFD) {.async.} =
|
||||||
doAssert false
|
doAssert false
|
||||||
|
|
||||||
proc createServer(port: TPort) {.async.} =
|
proc createServer(port: TPort) {.async.} =
|
||||||
var server = newAsyncRawSocket()
|
var server = newAsyncNativeSocket()
|
||||||
block:
|
block:
|
||||||
var name: Sockaddr_in
|
var name: Sockaddr_in
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ when defined(windows) or defined(nimdoc):
|
||||||
quit("Error: unhandled exception: Connection refused")
|
quit("Error: unhandled exception: Connection refused")
|
||||||
else:
|
else:
|
||||||
proc testAsyncConnect() {.async.} =
|
proc testAsyncConnect() {.async.} =
|
||||||
var s = newAsyncRawSocket()
|
var s = newAsyncNativeSocket()
|
||||||
|
|
||||||
await s.connect(testHost, testPort)
|
await s.connect(testHost, testPort)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ discard """
|
||||||
import
|
import
|
||||||
asyncdispatch,
|
asyncdispatch,
|
||||||
asyncnet,
|
asyncnet,
|
||||||
rawsockets,
|
nativesockets,
|
||||||
os
|
os
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -21,7 +21,7 @@ when defined(windows) or defined(nimdoc):
|
||||||
quit("Error: unhandled exception: Connection reset by peer")
|
quit("Error: unhandled exception: Connection reset by peer")
|
||||||
else:
|
else:
|
||||||
proc createListenSocket(host: string, port: Port): TAsyncFD =
|
proc createListenSocket(host: string, port: Port): TAsyncFD =
|
||||||
result = newAsyncRawSocket()
|
result = newAsyncNativeSocket()
|
||||||
|
|
||||||
SocketHandle(result).setSockOptInt(SOL_SOCKET, SO_REUSEADDR, 1)
|
SocketHandle(result).setSockOptInt(SOL_SOCKET, SO_REUSEADDR, 1)
|
||||||
|
|
||||||
|
|
|
||||||
30
tests/ccgbugs/twrong_discriminant_check.nim
Normal file
30
tests/ccgbugs/twrong_discriminant_check.nim
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
discard """
|
||||||
|
output: "(kind: None)"
|
||||||
|
"""
|
||||||
|
|
||||||
|
when true:
|
||||||
|
# bug #2637
|
||||||
|
|
||||||
|
type
|
||||||
|
OptionKind = enum
|
||||||
|
None,
|
||||||
|
Some
|
||||||
|
|
||||||
|
Option*[T] = object
|
||||||
|
case kind: OptionKind
|
||||||
|
of None:
|
||||||
|
discard
|
||||||
|
of Some:
|
||||||
|
value*: T
|
||||||
|
|
||||||
|
proc none*[T](): Option[T] =
|
||||||
|
Option[T](kind: None)
|
||||||
|
|
||||||
|
proc none*(T: typedesc): Option[T] = none[T]()
|
||||||
|
|
||||||
|
|
||||||
|
proc test(): Option[int] =
|
||||||
|
int.none
|
||||||
|
|
||||||
|
echo test()
|
||||||
|
|
||||||
|
|
@ -2,4 +2,4 @@ discard """
|
||||||
cmd: "nim cpp $file"
|
cmd: "nim cpp $file"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import rawsockets
|
import nativesockets
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import rawsockets, asyncdispatch, macros
|
import nativesockets, asyncdispatch, macros
|
||||||
var p = newDispatcher()
|
var p = newDispatcher()
|
||||||
var sock = newAsyncRawSocket()
|
var sock = newAsyncNativeSocket()
|
||||||
|
|
||||||
proc convertReturns(node, retFutureSym: NimNode): NimNode {.compileTime.} =
|
proc convertReturns(node, retFutureSym: NimNode): NimNode {.compileTime.} =
|
||||||
case node.kind
|
case node.kind
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ discard """
|
||||||
import mexporta
|
import mexporta
|
||||||
|
|
||||||
# bug #1029:
|
# bug #1029:
|
||||||
from rawsockets import accept
|
from nativesockets import accept
|
||||||
|
|
||||||
# B.TMyObject has been imported implicitly here:
|
# B.TMyObject has been imported implicitly here:
|
||||||
var x: TMyObject
|
var x: TMyObject
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,9 @@ News
|
||||||
Changes affecting backwards compatibility
|
Changes affecting backwards compatibility
|
||||||
-----------------------------------------
|
-----------------------------------------
|
||||||
|
|
||||||
|
- The ``rawsockets`` module has been renamed to ``nativesockets`` to avoid
|
||||||
|
confusion with TCP/IP raw sockets, so ``newNativeSocket`` should be used
|
||||||
|
instead of ``newRawSocket``.
|
||||||
- The ``miliseconds`` property of ``times.TimeInterval`` is now ``milliseconds``.
|
- The ``miliseconds`` property of ``times.TimeInterval`` is now ``milliseconds``.
|
||||||
Code accessing that property is deprecated and code using ``miliseconds``
|
Code accessing that property is deprecated and code using ``miliseconds``
|
||||||
during object initialization or as a named parameter of ``initInterval()``
|
during object initialization or as a named parameter of ``initInterval()``
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue