From 569c1ce5ec7cedd2c28d3272aae92062638cad0d Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 21 Jul 2011 00:57:39 +0200 Subject: [PATCH] bugfix: proper cache for generic instantiations --- compiler/cgen.nim | 2 +- compiler/sem.nim | 10 +- compiler/semcall.nim | 8 - compiler/semdata.nim | 12 +- compiler/seminst.nim | 54 ++-- compiler/semthreads.nim | 13 +- compiler/trees.nim | 33 +- doc/lib.txt | 3 + doc/nimrodc.txt | 2 +- doc/theindex.txt | 454 ++++++++++++++------------- lib/pure/{xmlgen.nim => htmlgen.nim} | 7 +- lib/pure/matchers.nim | 51 +++ lib/pure/os.nim | 78 +---- lib/pure/osproc.nim | 12 - lib/pure/parseopt.nim | 10 +- lib/pure/parseutils.nim | 2 +- lib/pure/regexprs.nim | 179 ----------- lib/pure/strutils.nim | 123 ++++---- lib/system/threads.nim | 2 +- tests/accept/run/tgenericprocvar.nim | 19 ++ todo.txt | 2 +- tools/sunset.tmpl | 2 +- web/news.txt | 22 +- web/nimrod.ini | 2 +- 24 files changed, 459 insertions(+), 643 deletions(-) rename lib/pure/{xmlgen.nim => htmlgen.nim} (98%) create mode 100644 lib/pure/matchers.nim delete mode 100755 lib/pure/regexprs.nim create mode 100644 tests/accept/run/tgenericprocvar.nim diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 02fcce9800..68e377f8b8 100755 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -15,7 +15,7 @@ import options, intsets, nversion, nimsets, msgs, crc, bitsets, idents, lists, types, ccgutils, os, times, ropes, math, passes, rodread, wordrecg, treetab, cgmeth, - rodutils + rodutils, renderer when options.hasTinyCBackend: import tccgen diff --git a/compiler/sem.nim b/compiler/sem.nim index 19b3cc9e2e..c2fbfff728 100755 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -134,15 +134,13 @@ proc semConstBoolExpr(c: PContext, n: PNode): PNode = include semtypes, semexprs, semgnrc, semstmts proc addCodeForGenerics(c: PContext, n: PNode) = - for i in countup(c.lastGenericIdx, sonsLen(c.generics) - 1): - var it = c.generics.sons[i].sons[1] - if it.kind != nkSym: InternalError("addCodeForGenerics") - var prc = it.sym + for i in countup(lastGenericIdx, Len(generics) - 1): + var prc = generics[i].instSym if prc.kind in {skProc, skMethod, skConverter} and prc.magic == mNone: if prc.ast == nil or prc.ast.sons[codePos] == nil: InternalError(prc.info, "no code for " & prc.name.s) addSon(n, prc.ast) - c.lastGenericIdx = sonsLen(c.generics) + lastGenericIdx = Len(generics) proc semExprNoFlags(c: PContext, n: PNode): PNode = result = semExpr(c, n, {}) @@ -174,7 +172,7 @@ proc myOpenCached(module: PSym, filename: string, proc SemStmtAndGenerateGenerics(c: PContext, n: PNode): PNode = result = semStmt(c, n) # BUGFIX: process newly generated generics here, not at the end! - if sonsLen(c.generics) > 0: + if lastGenericIdx < Len(generics): var a = newNodeI(nkStmtList, n.info) addCodeForGenerics(c, a) if sonsLen(a) > 0: diff --git a/compiler/semcall.nim b/compiler/semcall.nim index cf277728d3..f20349c0fe 100755 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -119,12 +119,4 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = # candidateCount != 1: return explicitGenericInstError(n) else: assert false - - when false: - var x: TCandidate - initCandidate(x, s, n) - var newInst = generateInstance(c, s, x.bindings, n.info) - - markUsed(n, s) - result = newSymNode(newInst, n.info) diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 9051e4726d..306638d6cc 100755 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -33,16 +33,17 @@ type nestedBlockCounter*: int # whether we are in a block or not next*: PProcCon # used for stacking procedure contexts + TInstantiatedSymbol* {.final.} = object + genericSym*, instSym*: PSym + concreteTypes*: seq[PType] + PContext* = ref TContext TContext* = object of TPassContext # a context represents a module module*: PSym # the module sym belonging to the context p*: PProcCon # procedure context InstCounter*: int # to prevent endless instantiations - generics*: PNode # a list of the things to compile; list of - # nkExprEqExpr nodes which contain the - # generic symbol and the instantiated symbol + threadEntries*: TSymSeq # list of thread entries to check - lastGenericIdx*: int # used for the generics stack tab*: TSymTab # each module has its own symbol table AmbiguousSymbols*: TIntSet # ids of all ambiguous symbols (cannot # store this info in the syms themselves!) @@ -58,6 +59,8 @@ type var gInstTypes*: TIdTable # map PType to PType +var generics*: seq[TInstantiatedSymbol] = @[] # a list of the things to compile +var lastGenericIdx*: int # used for the generics stack proc newContext*(module: PSym, nimfile: string): PContext @@ -124,7 +127,6 @@ proc newContext(module: PSym, nimfile: string): PContext = initLinkedList(result.libs) append(result.optionStack, newOptionEntry()) result.module = module - result.generics = newNode(nkStmtList) result.threadEntries = @[] result.converters = @[] result.filename = nimfile diff --git a/compiler/seminst.nim b/compiler/seminst.nim index 3d0b672bc4..6cb3252901 100755 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -9,15 +9,17 @@ # This module implements the instantiation of generic procs. -proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable) = - if (n.kind != nkGenericParams): +proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable, + entry: var TInstantiatedSymbol) = + if n.kind != nkGenericParams: InternalError(n.info, "instantiateGenericParamList; no generic params") - for i in countup(0, sonsLen(n) - 1): + newSeq(entry.concreteTypes, n.len) + for i in countup(0, n.len - 1): var a = n.sons[i] if a.kind != nkSym: InternalError(a.info, "instantiateGenericParamList; no symbol") var q = a.sym - if not (q.typ.kind in {tyTypeDesc, tyGenericParam}): continue + if q.typ.kind notin {tyTypeDesc, tyGenericParam}: continue var s = newSym(skType, q.name, getCurrOwner()) s.info = q.info incl(s.flags, sfUsed) @@ -29,24 +31,23 @@ proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable) = InternalError(a.info, "instantiateGenericParamList: " & q.name.s) s.typ = t addDecl(c, s) + entry.concreteTypes[i] = t -proc GenericCacheGet(c: PContext, genericSym, instSym: PSym): PSym = - result = nil - for i in countup(0, sonsLen(c.generics) - 1): - if c.generics.sons[i].kind != nkExprEqExpr: - InternalError(genericSym.info, "GenericCacheGet") - var a = c.generics.sons[i].sons[0].sym - if genericSym.id == a.id: - var b = c.generics.sons[i].sons[1].sym - if equalParams(b.typ.n, instSym.typ.n) == paramsEqual: - #echo "found in cache: ", getProcHeader(instSym) - return b +proc sameInstantiation(a, b: TInstantiatedSymbol): bool = + if a.genericSym.id == b.genericSym.id and + a.concreteTypes.len == b.concreteTypes.len: + for i in 0 .. < a.concreteTypes.len: + if not sameType(a.concreteTypes[i], b.concreteTypes[i]): return + result = true -proc GenericCacheAdd(c: PContext, genericSym, instSym: PSym) = - var n = newNode(nkExprEqExpr) - addSon(n, newSymNode(genericSym)) - addSon(n, newSymNode(instSym)) - addSon(c.generics, n) +proc GenericCacheGet(c: PContext, entry: var TInstantiatedSymbol): PSym = + for i in countup(0, Len(generics) - 1): + if sameInstantiation(entry, generics[i]): + result = generics[i].instSym + # checking for the concrete parameter list is wrong and unnecessary! + #if equalParams(b.typ.n, instSym.typ.n) == paramsEqual: + #echo "found in cache: ", getProcHeader(result) + return proc removeDefaultParamValues(n: PNode) = # we remove default params, because they cannot be instantiated properly @@ -81,11 +82,14 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, result.ast = n pushOwner(result) openScope(c.tab) - if (n.sons[genericParamsPos].kind == nkEmpty): + if n.sons[genericParamsPos].kind == nkEmpty: InternalError(n.info, "generateInstance") n.sons[namePos] = newSymNode(result) pushInfoContext(info) - instantiateGenericParamList(c, n.sons[genericParamsPos], pt) + var entry: TInstantiatedSymbol + entry.instSym = result + entry.genericSym = fn + instantiateGenericParamList(c, n.sons[genericParamsPos], pt, entry) n.sons[genericParamsPos] = ast.emptyNode # semantic checking for the parameters: if n.sons[paramsPos].kind != nkEmpty: @@ -96,10 +100,10 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, result.typ = newTypeS(tyProc, c) addSon(result.typ, nil) result.typ.callConv = fn.typ.callConv - var oldPrc = GenericCacheGet(c, fn, result) - if oldPrc == nil: + var oldPrc = GenericCacheGet(c, entry) + if oldPrc == nil: # add it here, so that recursive generic procs are possible: - GenericCacheAdd(c, fn, result) + generics.add(entry) addDecl(c, result) if n.sons[codePos].kind != nkEmpty: pushProcCon(c, result) diff --git a/compiler/semthreads.nim b/compiler/semthreads.nim index b6bdc9e600..5e52aea72a 100755 --- a/compiler/semthreads.nim +++ b/compiler/semthreads.nim @@ -358,6 +358,8 @@ proc analyse(c: PProcCtx, n: PNode): TThreadOwner = of nkAsmStmt, nkPragma, nkIteratorDef, nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef: result = toVoid + of nkExprColonExpr: + result = analyse(c, n.sons[1]) else: InternalError(n.info, "analysis not implemented for: " & $n.kind) proc analyseThreadProc*(prc: PSym) = @@ -368,17 +370,6 @@ proc analyseThreadProc*(prc: PSym) = c.mapping[formal.id] = toTheirs # thread receives foreign data! discard analyse(c, prc.ast.sons[codePos]) -when false: - proc analyseThreadCreationCall(n: PNode) = - # thread proc is second param of ``createThread``: - if n[2].kind != nkSym or n[2].sym.kind != skProc: - Message(n.info, warnAnalysisLoophole, renderTree(n)) - return - analyseProc(n[2].sym) - - proc AnalyseThread*(threadCreation: PNode) = - analyseThreadCreationCall(threadCreation) - proc needsGlobalAnalysis*: bool = result = gGlobalOptions * {optThreads, optThreadAnalysis} == {optThreads, optThreadAnalysis} diff --git a/compiler/trees.nim b/compiler/trees.nim index 76a30e3ac2..7b90296ad6 100755 --- a/compiler/trees.nim +++ b/compiler/trees.nim @@ -12,19 +12,6 @@ import ast, astalgo, lexer, msgs, strutils, wordrecg -proc getMagic*(op: PNode): TMagic - -proc isConstExpr*(n: PNode): bool -proc flattenTree*(root: PNode, op: TMagic): PNode -proc TreeToSym*(t: PNode): PSym -proc SwapOperands*(op: PNode) -proc getOpSym*(op: PNode): PSym -proc getProcSym*(call: PNode): PSym -proc ExprStructuralEquivalent*(a, b: PNode): bool -proc sameTree*(a, b: PNode): bool -proc cyclicTree*(n: PNode): bool -# implementation - proc hasSon(father, son: PNode): bool = for i in countup(0, sonsLen(father) - 1): if father.sons[i] == son: @@ -45,11 +32,11 @@ proc cyclicTreeAux(n, s: PNode): bool = result = false delSon(s, m) -proc cyclicTree(n: PNode): bool = +proc cyclicTree*(n: PNode): bool = var s = newNodeI(nkEmpty, n.info) result = cyclicTreeAux(n, s) -proc ExprStructuralEquivalent(a, b: PNode): bool = +proc ExprStructuralEquivalent*(a, b: PNode): bool = result = false if a == b: result = true @@ -69,7 +56,7 @@ proc ExprStructuralEquivalent(a, b: PNode): bool = if not ExprStructuralEquivalent(a.sons[i], b.sons[i]): return result = true -proc sameTree(a, b: PNode): bool = +proc sameTree*(a, b: PNode): bool = result = false if a == b: result = true @@ -93,10 +80,10 @@ proc sameTree(a, b: PNode): bool = if not sameTree(a.sons[i], b.sons[i]): return result = true -proc getProcSym(call: PNode): PSym = +proc getProcSym*(call: PNode): PSym = result = call.sons[0].sym -proc getOpSym(op: PNode): PSym = +proc getOpSym*(op: PNode): PSym = if not (op.kind in {nkCall, nkHiddenCallConv, nkCommand, nkCallStrLit}): result = nil else: @@ -104,7 +91,7 @@ proc getOpSym(op: PNode): PSym = if op.sons[0].Kind == nkSym: result = op.sons[0].sym else: result = nil -proc getMagic(op: PNode): TMagic = +proc getMagic*(op: PNode): TMagic = case op.kind of nkCall, nkHiddenCallConv, nkCommand, nkCallStrLit, nkPrefix, nkPostfix, nkInfix: @@ -113,10 +100,10 @@ proc getMagic(op: PNode): TMagic = else: result = mNone else: result = mNone -proc TreeToSym(t: PNode): PSym = +proc TreeToSym*(t: PNode): PSym = result = t.sym -proc isConstExpr(n: PNode): bool = +proc isConstExpr*(n: PNode): bool = result = (n.kind in {nkCharLit..nkInt64Lit, nkStrLit..nkTripleStrLit, nkFloatLit..nkFloat64Lit, nkNilLit}) or (nfAllConst in n.flags) @@ -128,14 +115,14 @@ proc flattenTreeAux(d, a: PNode, op: TMagic) = else: addSon(d, copyTree(a)) -proc flattenTree(root: PNode, op: TMagic): PNode = +proc flattenTree*(root: PNode, op: TMagic): PNode = result = copyNode(root) if (getMagic(root) == op): # BUGFIX: forget to copy prc addSon(result, copyNode(root.sons[0])) flattenTreeAux(result, root, op) -proc SwapOperands(op: PNode) = +proc SwapOperands*(op: PNode) = var tmp = op.sons[1] op.sons[1] = op.sons[2] op.sons[2] = tmp diff --git a/doc/lib.txt b/doc/lib.txt index c63d5b0aae..12890d33d2 100755 --- a/doc/lib.txt +++ b/doc/lib.txt @@ -99,6 +99,9 @@ String handling It finds the sequence of ASCII characters that is the closest approximation to the Unicode string. +* `matchers `_ + This module contains various string matchers for email addresses, etc. + Generic Operating System Services --------------------------------- diff --git a/doc/nimrodc.txt b/doc/nimrodc.txt index 375a651094..71f5c03876 100755 --- a/doc/nimrodc.txt +++ b/doc/nimrodc.txt @@ -175,7 +175,7 @@ Emit pragma The `emit`:idx: pragma can be used to directly affect the output of the compiler's code generator. So it makes your code unportable to other code generators/backends. Its usage is highly discouraged! However, it can be -extremely useful for interfacing with C++ or Objective C code. +extremely useful for interfacing with `C++`:idx: or `Objective C`:idx: code. Example: diff --git a/doc/theindex.txt b/doc/theindex.txt index 9a5dde744d..be5d485626 100755 --- a/doc/theindex.txt +++ b/doc/theindex.txt @@ -22,15 +22,15 @@ Index `$`:idx: * `macros.html#115 `_ * `sockets.html#111 `_ - * `system.html#445 `_ - * `system.html#446 `_ - * `system.html#447 `_ - * `system.html#448 `_ * `system.html#449 `_ * `system.html#450 `_ * `system.html#451 `_ * `system.html#452 `_ - * `system.html#503 `_ + * `system.html#453 `_ + * `system.html#454 `_ + * `system.html#455 `_ + * `system.html#456 `_ + * `system.html#507 `_ * `complex.html#134 `_ * `times.html#109 `_ * `times.html#110 `_ @@ -75,9 +75,9 @@ Index * `system.html#379 `_ * `system.html#380 `_ * `system.html#381 `_ - * `system.html#487 `_ - * `system.html#488 `_ - * `system.html#489 `_ + * `system.html#491 `_ + * `system.html#492 `_ + * `system.html#493 `_ * `pegs.html#116 `_ * `ropes.html#109 `_ * `ropes.html#110 `_ @@ -165,11 +165,11 @@ Index `..`:idx: * `system.html#137 `_ * `system.html#139 `_ - * `system.html#462 `_ + * `system.html#466 `_ `/`:idx: * `system.html#328 `_ - * `system.html#578 `_ + * `system.html#582 `_ * `os.html#125 `_ * `complex.html#111 `_ * `complex.html#112 `_ @@ -202,7 +202,7 @@ Index * `system.html#360 `_ * `system.html#361 `_ * `system.html#362 `_ - * `system.html#502 `_ + * `system.html#506 `_ * `times.html#112 `_ `<%`:idx: @@ -229,7 +229,7 @@ Index * `system.html#352 `_ * `system.html#353 `_ * `system.html#354 `_ - * `system.html#501 `_ + * `system.html#505 `_ `<=`:idx: `times.html#113 `_ @@ -268,35 +268,35 @@ Index * `system.html#345 `_ * `system.html#346 `_ * `system.html#347 `_ - * `system.html#490 `_ - * `system.html#500 `_ + * `system.html#494 `_ + * `system.html#504 `_ * `complex.html#102 `_ * `unicode.html#105 `_ * `colors.html#102 `_ `=~`:idx: - `re.html#120 `_ + `complex.html#103 `_ `=~`:idx: - `regexprs.html#111 `_ + `re.html#120 `_ `=~`:idx: `pegs.html#157 `_ `=~`:idx: - `complex.html#103 `_ + `regexprs.html#111 `_ `>`:idx: `system.html#365 `_ `>%`:idx: - `system.html#444 `_ + `system.html#448 `_ `>=`:idx: `system.html#364 `_ `>=%`:idx: - `system.html#443 `_ + `system.html#447 `_ `?`:idx: `pegs.html#111 `_ @@ -309,70 +309,70 @@ Index `pegs.html#114 `_ `[]`:idx: - `ropes.html#115 `_ + * `json.html#130 `_ + * `json.html#131 `_ + + `[]`:idx: + * `graphics.html#116 `_ + * `graphics.html#117 `_ + + `[]`:idx: + * `typeinfo.html#111 `_ + * `typeinfo.html#119 `_ + * `typeinfo.html#120 `_ + + `[]`:idx: + * `system.html#583 `_ + * `system.html#585 `_ + * `system.html#587 `_ + * `system.html#589 `_ + + `[]`:idx: + `xmltree.html#114 `_ `[]`:idx: * `tables.html#106 `_ * `tables.html#119 `_ * `tables.html#131 `_ - `[]`:idx: - `xmltree.html#114 `_ - - `[]`:idx: - * `graphics.html#116 `_ - * `graphics.html#117 `_ - `[]`:idx: `strtabs.html#107 `_ `[]`:idx: - * `json.html#130 `_ - * `json.html#131 `_ + `ropes.html#115 `_ `[]`:idx: `macros.html#112 `_ - `[]`:idx: - * `system.html#579 `_ - * `system.html#581 `_ - * `system.html#583 `_ - * `system.html#585 `_ - - `[]`:idx: - * `typeinfo.html#111 `_ - * `typeinfo.html#119 `_ - * `typeinfo.html#120 `_ + `[]=`:idx: + `strtabs.html#109 `_ `[]=`:idx: `json.html#135 `_ + `[]=`:idx: + * `graphics.html#118 `_ + * `graphics.html#119 `_ + + `[]=`:idx: + * `system.html#584 `_ + * `system.html#586 `_ + * `system.html#588 `_ + * `system.html#590 `_ + `[]=`:idx: * `typeinfo.html#112 `_ * `typeinfo.html#118 `_ * `typeinfo.html#121 `_ `[]=`:idx: - * `graphics.html#118 `_ - * `graphics.html#119 `_ - - `[]=`:idx: - * `system.html#580 `_ - * `system.html#582 `_ - * `system.html#584 `_ - * `system.html#586 `_ + `macros.html#113 `_ `[]=`:idx: * `tables.html#108 `_ * `tables.html#121 `_ * `tables.html#133 `_ - `[]=`:idx: - `macros.html#113 `_ - - `[]=`:idx: - `strtabs.html#109 `_ - `[ESC]`:idx: `manual.html#134 `_ @@ -395,10 +395,10 @@ Index `sockets.html#122 `_ `accumulateResult`:idx: - `system.html#518 `_ + `system.html#522 `_ `Acquire`:idx: - `threads.html#112 `_ + `threads.html#113 `_ `acronym`:idx: `xmlgen.html#108 `_ @@ -416,7 +416,7 @@ Index * `system.html#383 `_ * `system.html#398 `_ * `system.html#399 `_ - * `system.html#523 `_ + * `system.html#527 `_ * `parsesql.html#108 `_ * `ropes.html#113 `_ * `ropes.html#114 `_ @@ -491,6 +491,12 @@ Index `ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP`:idx: `mysql.html#318 `_ + `allocShared`:idx: + `system.html#440 `_ + + `allocShared0`:idx: + `system.html#441 `_ + `AltSep`:idx: `os.html#104 `_ @@ -567,7 +573,7 @@ Index `manual.html#212 `_ `assert`:idx: - `system.html#441 `_ + `system.html#445 `_ `assign`:idx: `typeinfo.html#143 `_ @@ -576,10 +582,10 @@ Index `macros.html#101 `_ `atomicDec`:idx: - `system.html#570 `_ + `system.html#574 `_ `atomicInc`:idx: - `system.html#569 `_ + `system.html#573 `_ `attr`:idx: `xmltree.html#129 `_ @@ -777,6 +783,9 @@ Index `ChangeFileExt`:idx: `os.html#137 `_ + `channelId`:idx: + `inboxes.html#111 `_ + `char`:idx: `system.html#110 `_ @@ -918,14 +927,9 @@ Index `clonglong`:idx: `system.html#414 `_ - `Close`:idx: - * `system.html#539 `_ - * `db_postgres.html#117 `_ - * `db_mysql.html#116 `_ - * `db_sqlite.html#117 `_ - `close`:idx: * `sockets.html#123 `_ + * `inboxes.html#110 `_ * `osproc.html#108 `_ * `lexbase.html#105 `_ * `parsecfg.html#105 `_ @@ -941,6 +945,12 @@ Index * `sphinx.html#159 `_ * `encodings.html#106 `_ + `Close`:idx: + * `system.html#543 `_ + * `db_postgres.html#117 `_ + * `db_mysql.html#116 `_ + * `db_sqlite.html#117 `_ + `closure`:idx: `manual.html#183 `_ @@ -1470,7 +1480,7 @@ Index * `re.html#122 `_ * `system.html#140 `_ * `system.html#366 `_ - * `system.html#492 `_ + * `system.html#496 `_ * `strutils.html#151 `_ * `strutils.html#152 `_ * `strutils.html#153 `_ @@ -1537,13 +1547,13 @@ Index `math.html#112 `_ `countdown`:idx: - `system.html#460 `_ + `system.html#464 `_ `countProcessors`:idx: `osproc.html#119 `_ `countup`:idx: - `system.html#461 `_ + `system.html#465 `_ `cpuEndian`:idx: `system.html#392 `_ @@ -1622,8 +1632,8 @@ Index `system.html#418 `_ `cstringArrayToSeq`:idx: - * `system.html#567 `_ - * `system.html#568 `_ + * `system.html#571 `_ + * `system.html#572 `_ `CSV`:idx: `parsecsv.html#101 `_ @@ -2010,7 +2020,7 @@ Index * `db_sqlite.html#107 `_ `dbgLineHook`:idx: - `system.html#519 `_ + `system.html#523 `_ `dbsize`:idx: `redis.html#209 `_ @@ -2027,6 +2037,9 @@ Index `dealloc`:idx: `system.html#439 `_ + `deallocShared`:idx: + `system.html#443 `_ + `debug build`:idx: `nimrodc.html#101 `_ @@ -2088,12 +2101,12 @@ Index `dfn`:idx: `xmlgen.html#125 `_ - `digits`:idx: - `pegs.html#138 `_ - `Digits`:idx: `strutils.html#104 `_ + `digits`:idx: + `pegs.html#138 `_ + `directory`:idx: `os.html#165 `_ @@ -2101,7 +2114,7 @@ Index `os.html#103 `_ `disableCache`:idx: - `ropes.html#107 `_ + `ropes.html#108 `_ `discard`:idx: `manual.html#193 `_ @@ -2188,8 +2201,8 @@ Index `system.html#157 `_ `each`:idx: - * `system.html#494 `_ - * `system.html#495 `_ + * `system.html#498 `_ + * `system.html#499 `_ `EADDRINUSE`:idx: `zmq.html#107 `_ @@ -2213,7 +2226,7 @@ Index `cgi.html#104 `_ `echo`:idx: - `system.html#524 `_ + `system.html#528 `_ `echoServ`:idx: `redis.html#200 `_ @@ -2376,7 +2389,7 @@ Index `zmq.html#114 `_ `enableCache`:idx: - `ropes.html#108 `_ + `ropes.html#107 `_ `ENamespaceErr`:idx: `xmldom.html#110 `_ @@ -2391,7 +2404,7 @@ Index `endb.html#102 `_ `EndOfFile`:idx: - * `system.html#540 `_ + * `system.html#544 `_ * `lexbase.html#101 `_ `endsWith`:idx: @@ -2727,13 +2740,13 @@ Index `manual.html#263 `_ `fieldPairs`:idx: - * `system.html#498 `_ - * `system.html#499 `_ + * `system.html#502 `_ + * `system.html#503 `_ `fields`:idx: * `typeinfo.html#117 `_ - * `system.html#496 `_ - * `system.html#497 `_ + * `system.html#500 `_ + * `system.html#501 `_ `fieldset`:idx: `xmlgen.html#130 `_ @@ -2823,7 +2836,7 @@ Index `mysql.html#218 `_ `fileHandle`:idx: - `system.html#566 `_ + `system.html#570 `_ `fileNewer`:idx: `os.html#118 `_ @@ -2857,7 +2870,7 @@ Index * `regexprs.html#110 `_ * `re.html#116 `_ * `re.html#117 `_ - * `system.html#491 `_ + * `system.html#495 `_ * `strutils.html#147 `_ * `strutils.html#148 `_ * `strutils.html#149 `_ @@ -2914,7 +2927,7 @@ Index `redis.html#213 `_ `FlushFile`:idx: - `system.html#542 `_ + `system.html#546 `_ `for`:idx: * `manual.html#222 `_ @@ -2953,35 +2966,35 @@ Index `manual.html#215 `_ `GC_disable`:idx: - `system.html#504 `_ - - `GC_disableMarkAndSweep`:idx: - `system.html#510 `_ - - `GC_enable`:idx: - `system.html#505 `_ - - `GC_enableMarkAndSweep`:idx: - `system.html#509 `_ - - `GC_fullCollect`:idx: - `system.html#506 `_ - - `GC_getStatistics`:idx: - `system.html#511 `_ - - `GC_ref`:idx: - * `system.html#512 `_ - * `system.html#513 `_ - * `system.html#514 `_ - - `GC_setStrategy`:idx: `system.html#508 `_ - `GC_unref`:idx: - * `system.html#515 `_ + `GC_disableMarkAndSweep`:idx: + `system.html#514 `_ + + `GC_enable`:idx: + `system.html#509 `_ + + `GC_enableMarkAndSweep`:idx: + `system.html#513 `_ + + `GC_fullCollect`:idx: + `system.html#510 `_ + + `GC_getStatistics`:idx: + `system.html#515 `_ + + `GC_ref`:idx: * `system.html#516 `_ * `system.html#517 `_ + * `system.html#518 `_ + + `GC_setStrategy`:idx: + `system.html#512 `_ + + `GC_unref`:idx: + * `system.html#519 `_ + * `system.html#520 `_ + * `system.html#521 `_ `generalized raw string literal`:idx: `manual.html#137 `_ @@ -3081,10 +3094,10 @@ Index `encodings.html#104 `_ `getCurrentException`:idx: - `system.html#573 `_ + `system.html#577 `_ `getCurrentExceptionMsg`:idx: - `system.html#574 `_ + `system.html#578 `_ `getCurrentLine`:idx: `lexbase.html#106 `_ @@ -3125,19 +3138,19 @@ Index `os.html#170 `_ `getFilePos`:idx: - `system.html#565 `_ + `system.html#569 `_ `getFileSize`:idx: - * `system.html#557 `_ + * `system.html#561 `_ * `os.html#186 `_ + `get_float`:idx: + `sphinx.html#186 `_ + `getFloat`:idx: * `typeinfo.html#135 `_ * `json.html#109 `_ - `get_float`:idx: - `sphinx.html#186 `_ - `getFloat32`:idx: `typeinfo.html#136 `_ @@ -3145,7 +3158,7 @@ Index `typeinfo.html#137 `_ `getFreeMem`:idx: - `system.html#458 `_ + `system.html#462 `_ `getGatewayInterface`:idx: `cgi.html#114 `_ @@ -3243,7 +3256,7 @@ Index `sphinx.html#182 `_ `getOccupiedMem`:idx: - `system.html#457 `_ + `system.html#461 `_ `getopt`:idx: `parseopt.html#108 `_ @@ -3264,7 +3277,7 @@ Index `redis.html#127 `_ `getRefcount`:idx: - `system.html#453 `_ + `system.html#457 `_ `getRemoteAddr`:idx: `cgi.html#127 `_ @@ -3360,13 +3373,13 @@ Index `times.html#105 `_ `getTotalMem`:idx: - `system.html#459 `_ + `system.html#463 `_ `get_tty_password`:idx: `mysql.html#282 `_ `getTypeInfo`:idx: - `system.html#587 `_ + `system.html#591 `_ `GetValue`:idx: * `db_postgres.html#113 `_ @@ -3572,12 +3585,12 @@ Index `ident=`:idx: `macros.html#132 `_ - `IdentChars`:idx: - `strutils.html#106 `_ - `identChars`:idx: `pegs.html#140 `_ + `IdentChars`:idx: + `strutils.html#106 `_ + `identifier`:idx: `manual.html#105 `_ @@ -3650,7 +3663,7 @@ Index `manual.html#113 `_ `inf`:idx: - `system.html#454 `_ + `system.html#458 `_ `InfChecks`:idx: `manual.html#155 `_ @@ -3679,7 +3692,7 @@ Index `intsets.html#106 `_ `InitLock`:idx: - `threads.html#110 `_ + `threads.html#111 `_ `initOptParser`:idx: `parseopt.html#103 `_ @@ -3790,12 +3803,12 @@ Index `isNil`:idx: * `typeinfo.html#114 `_ - * `system.html#481 `_ - * `system.html#482 `_ - * `system.html#483 `_ - * `system.html#484 `_ * `system.html#485 `_ * `system.html#486 `_ + * `system.html#487 `_ + * `system.html#488 `_ + * `system.html#489 `_ + * `system.html#490 `_ `is_not`:idx: `system.html#370 `_ @@ -3834,12 +3847,12 @@ Index `mysql.html#255 `_ `items`:idx: - * `system.html#475 `_ - * `system.html#476 `_ - * `system.html#477 `_ - * `system.html#478 `_ * `system.html#479 `_ * `system.html#480 `_ + * `system.html#481 `_ + * `system.html#482 `_ + * `system.html#483 `_ + * `system.html#484 `_ * `ropes.html#117 `_ * `xmltree.html#115 `_ * `json.html#141 `_ @@ -3938,12 +3951,12 @@ Index * `sets.html#113 `_ * `queues.html#103 `_ - `Letters`:idx: - `strutils.html#103 `_ - `letters`:idx: `pegs.html#137 `_ + `Letters`:idx: + `strutils.html#103 `_ + `li`:idx: `xmlgen.html#148 `_ @@ -3963,7 +3976,7 @@ Index `libcurl.html#276 `_ `likely`:idx: - `system.html#575 `_ + `system.html#579 `_ `lIndex`:idx: `redis.html#152 `_ @@ -3978,8 +3991,8 @@ Index `nimrodc.html#110 `_ `lines`:idx: - * `system.html#571 `_ - * `system.html#572 `_ + * `system.html#575 `_ + * `system.html#576 `_ `lineTrace`:idx: `nimrodc.html#112 `_ @@ -4077,6 +4090,9 @@ Index `Macros`:idx: `manual.html#229 `_ + `mainThreadId`:idx: + `threads.html#109 `_ + `make_password_from_salt`:idx: `mysql.html#281 `_ @@ -4124,12 +4140,12 @@ Index `max`:idx: * `system.html#334 `_ - * `system.html#469 `_ - * `system.html#470 `_ - * `system.html#471 `_ - * `system.html#472 `_ * `system.html#473 `_ * `system.html#474 `_ + * `system.html#475 `_ + * `system.html#476 `_ + * `system.html#477 `_ + * `system.html#478 `_ `MAX_BIGINT_WIDTH`:idx: `mysql.html#194 `_ @@ -4207,12 +4223,12 @@ Index `min`:idx: * `system.html#333 `_ - * `system.html#463 `_ - * `system.html#464 `_ - * `system.html#465 `_ - * `system.html#466 `_ * `system.html#467 `_ * `system.html#468 `_ + * `system.html#469 `_ + * `system.html#470 `_ + * `system.html#471 `_ + * `system.html#472 `_ `mix`:idx: `colors.html#107 `_ @@ -4805,19 +4821,19 @@ Index `xmldom.html#158 `_ `nan`:idx: - `system.html#456 `_ + `system.html#460 `_ `NaNChecks`:idx: `manual.html#154 `_ - `Natural`:idx: - `system.html#142 `_ - `natural`:idx: `pegs.html#143 `_ + `Natural`:idx: + `system.html#142 `_ + `neginf`:idx: - `system.html#455 `_ + `system.html#459 `_ `nestList`:idx: `macros.html#152 `_ @@ -4885,7 +4901,7 @@ Index `xmltree.html#108 `_ `newException`:idx: - `system.html#525 `_ + `system.html#529 `_ `newFileStream`:idx: * `streams.html#120 `_ @@ -4925,13 +4941,13 @@ Index `newJString`:idx: `json.html#122 `_ - `newLine`:idx: - `pegs.html#123 `_ - `newline`:idx: * `manual.html#121 `_ * `pegs.html#122 `_ + `newLine`:idx: + `pegs.html#123 `_ + `NewLines`:idx: * `strutils.html#108 `_ * `lexbase.html#102 `_ @@ -5092,6 +5108,7 @@ Index `mysql.html#189 `_ `open`:idx: + * `inboxes.html#109 `_ * `lexbase.html#104 `_ * `parsecfg.html#104 `_ * `parsexml.html#107 `_ @@ -5106,9 +5123,9 @@ Index * `encodings.html#105 `_ `Open`:idx: - * `system.html#535 `_ - * `system.html#536 `_ - * `system.html#537 `_ + * `system.html#539 `_ + * `system.html#540 `_ + * `system.html#541 `_ * `db_postgres.html#118 `_ * `db_mysql.html#117 `_ * `db_sqlite.html#118 `_ @@ -5159,10 +5176,10 @@ Index `os.html#110 `_ `out of memory`:idx: - `system.html#521 `_ + `system.html#525 `_ `outOfMemHook`:idx: - `system.html#522 `_ + `system.html#526 `_ `outputStream`:idx: `osproc.html#117 `_ @@ -5229,12 +5246,12 @@ Index `parseFile`:idx: `json.html#145 `_ - `ParseFloat`:idx: - `strutils.html#134 `_ - `parseFloat`:idx: `parseutils.html#115 `_ + `ParseFloat`:idx: + `strutils.html#134 `_ + `parseHex`:idx: `parseutils.html#101 `_ @@ -5248,12 +5265,12 @@ Index `parseIdent`:idx: `parseutils.html#103 `_ - `parseInt`:idx: - `parseutils.html#113 `_ - `ParseInt`:idx: `strutils.html#132 `_ + `parseInt`:idx: + `parseutils.html#113 `_ + `parseIp4`:idx: `sockets.html#118 `_ @@ -5451,6 +5468,8 @@ Index `peek`:idx: * `inboxes.html#104 `_ * `inboxes.html#105 `_ + * `inboxes.html#114 `_ + * `inboxes.html#115 `_ `peekExitCode`:idx: `osproc.html#115 `_ @@ -5604,7 +5623,7 @@ Index `zmq.html#117 `_ `pop`:idx: - `system.html#493 `_ + `system.html#497 `_ `port`:idx: `httpserver.html#105 `_ @@ -5703,7 +5722,7 @@ Index `manual.html#243 `_ `programming by contracts`:idx: - `system.html#440 `_ + `system.html#444 `_ `PRope`:idx: `ropes.html#102 `_ @@ -5816,13 +5835,13 @@ Index `PUSED_MEM`:idx: `mysql.html#322 `_ - `PUSH`:idx: - `zmq.html#130 `_ - `push`:idx: * `math.html#140 `_ * `math.html#141 `_ + `PUSH`:idx: + `zmq.html#130 `_ + `push/pop`:idx: `manual.html#259 `_ @@ -5851,15 +5870,15 @@ Index `zmq.html#121 `_ `quit`:idx: - * `system.html#528 `_ - * `system.html#577 `_ + * `system.html#532 `_ + * `system.html#581 `_ * `redis.html#202 `_ `QuitFailure`:idx: - `system.html#527 `_ + `system.html#531 `_ `QuitSuccess`:idx: - `system.html#526 `_ + `system.html#530 `_ `quotation mark`:idx: `manual.html#128 `_ @@ -5868,7 +5887,7 @@ Index `strutils.html#150 `_ `raiseHook`:idx: - `system.html#520 `_ + `system.html#524 `_ `raiseParseErr`:idx: `json.html#121 `_ @@ -5907,23 +5926,23 @@ Index `streams.html#106 `_ `readBuffer`:idx: - `system.html#560 `_ + `system.html#564 `_ `ReadBytes`:idx: - `system.html#558 `_ + `system.html#562 `_ `readChar`:idx: - * `system.html#541 `_ + * `system.html#545 `_ * `streams.html#105 `_ `ReadChars`:idx: - `system.html#559 `_ + `system.html#563 `_ `readData`:idx: `cgi.html#109 `_ `readFile`:idx: - `system.html#543 `_ + `system.html#547 `_ `readFloat32`:idx: `streams.html#111 `_ @@ -5944,7 +5963,7 @@ Index `streams.html#107 `_ `readLine`:idx: - * `system.html#554 `_ + * `system.html#558 `_ * `streams.html#114 `_ `ReadLineFromStdin`:idx: @@ -5962,6 +5981,9 @@ Index `realloc`:idx: `system.html#438 `_ + `reallocShared`:idx: + `system.html#442 `_ + `reBinary`:idx: * `regexprs.html#116 `_ * `re.html#136 `_ @@ -5977,6 +5999,8 @@ Index * `sockets.html#137 `_ * `sockets.html#138 `_ * `inboxes.html#103 `_ + * `inboxes.html#116 `_ + * `inboxes.html#117 `_ * `zmq.html#165 `_ `recvAsync`:idx: @@ -6055,7 +6079,7 @@ Index * `re.html#134 `_ `Release`:idx: - `threads.html#113 `_ + `threads.html#114 `_ `release build`:idx: `nimrodc.html#102 `_ @@ -6106,7 +6130,7 @@ Index * `re.html#137 `_ `reopen`:idx: - `system.html#538 `_ + `system.html#542 `_ `REP`:idx: `zmq.html#126 `_ @@ -6313,6 +6337,8 @@ Index * `sockets.html#142 `_ * `inboxes.html#101 `_ * `inboxes.html#102 `_ + * `inboxes.html#112 `_ + * `inboxes.html#113 `_ * `ssl.html#104 `_ * `zmq.html#164 `_ * `zmq.html#174 `_ @@ -6435,7 +6461,7 @@ Index `os.html#171 `_ `setFilePos`:idx: - `system.html#564 `_ + `system.html#568 `_ `SET_FLAG`:idx: `mysql.html#135 `_ @@ -7345,15 +7371,15 @@ Index `manual.html#177 `_ `stderr`:idx: - `system.html#534 `_ + `system.html#538 `_ `stdin`:idx: * `lib.html#101 `_ - * `system.html#532 `_ + * `system.html#536 `_ * `rdstdin.html#101 `_ `stdout`:idx: - `system.html#533 `_ + `system.html#537 `_ `stdtmpl`:idx: `filters.html#104 `_ @@ -7495,7 +7521,7 @@ Index `osproc.html#109 `_ `swap`:idx: - `system.html#442 `_ + `system.html#446 `_ `symAddr`:idx: `dynlib.html#104 `_ @@ -7570,6 +7596,12 @@ Index `TCfgParser`:idx: `parsecfg.html#103 `_ + `TChannel`:idx: + `inboxes.html#107 `_ + + `TChannelId`:idx: + `inboxes.html#108 `_ + `TCharSet`:idx: `strutils.html#101 `_ @@ -7815,13 +7847,13 @@ Index `xmldom.html#119 `_ `TFile`:idx: - `system.html#529 `_ + `system.html#533 `_ `TFileHandle`:idx: - `system.html#531 `_ + `system.html#535 `_ `TFileMode`:idx: - `system.html#530 `_ + `system.html#534 `_ `TFilePermission`:idx: `os.html#169 `_ @@ -7845,7 +7877,7 @@ Index `strtabs.html#106 `_ `TGC_Strategy`:idx: - `system.html#507 `_ + `system.html#511 `_ `th`:idx: `xmlgen.html#175 `_ @@ -7908,7 +7940,7 @@ Index `dynlib.html#101 `_ `TLock`:idx: - `threads.html#109 `_ + `threads.html#110 `_ `TMessage`:idx: `smtp.html#102 `_ @@ -8133,7 +8165,7 @@ Index * `tut2.html#108 `_ `TryAcquire`:idx: - `threads.html#111 `_ + `threads.html#112 `_ `TryExec`:idx: * `db_postgres.html#108 `_ @@ -8361,7 +8393,7 @@ Index `os.html#112 `_ `unlikely`:idx: - `system.html#576 `_ + `system.html#580 `_ `UnloadLib`:idx: `dynlib.html#103 `_ @@ -8506,37 +8538,37 @@ Index `strutils.html#140 `_ `write`:idx: - * `system.html#545 `_ - * `system.html#546 `_ - * `system.html#547 `_ - * `system.html#548 `_ * `system.html#549 `_ * `system.html#550 `_ * `system.html#551 `_ * `system.html#552 `_ * `system.html#553 `_ + * `system.html#554 `_ + * `system.html#555 `_ + * `system.html#556 `_ + * `system.html#557 `_ * `streams.html#103 `_ * `streams.html#104 `_ * `ropes.html#118 `_ `writeBuffer`:idx: - `system.html#563 `_ + `system.html#567 `_ `writeBytes`:idx: - `system.html#561 `_ + `system.html#565 `_ `writeChars`:idx: - `system.html#562 `_ + `system.html#566 `_ `writeContentType`:idx: `cgi.html#144 `_ `writeFile`:idx: - `system.html#544 `_ + `system.html#548 `_ `writeln`:idx: - * `system.html#555 `_ - * `system.html#556 `_ + * `system.html#559 `_ + * `system.html#560 `_ `writeStatusOkTextContent`:idx: `scgi.html#107 `_ diff --git a/lib/pure/xmlgen.nim b/lib/pure/htmlgen.nim similarity index 98% rename from lib/pure/xmlgen.nim rename to lib/pure/htmlgen.nim index d1fdcdd576..e836bac941 100755 --- a/lib/pure/xmlgen.nim +++ b/lib/pure/htmlgen.nim @@ -1,7 +1,7 @@ # # # Nimrod's Runtime Library -# (c) Copyright 2010 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -21,10 +21,6 @@ ## ##

Nimrod

## -## **Deprecated since version 0.8.8.** Use the macro ``<>`` in xmltree -## instead. - -{.deprecated.} import macros, strutils @@ -58,7 +54,6 @@ proc xmlCheckedTag*(e: PNimrodNode, tag: string, # will be modified, so that each attribute is only given one value var req = split(reqAttr) var opt = split(optAttr) - echo "##", optAttr, "##", opt.len result = newNimNode(nnkBracket, e) result.add(newStrLitNode("<")) result.add(newStrLitNode(tag)) diff --git a/lib/pure/matchers.nim b/lib/pure/matchers.nim new file mode 100644 index 0000000000..f495387374 --- /dev/null +++ b/lib/pure/matchers.nim @@ -0,0 +1,51 @@ +# +# +# Nimrod's Runtime Library +# (c) Copyright 2011 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## This module contains various string matchers for email addresses, etc. +{.deadCodeElim: on.} + +{.push debugger:off .} # the user does not want to trace a part + # of the standard library! + +include "system/inclrtl" + +import strutils + +proc validEmailAddress*(s: string): bool {.noSideEffect, + rtl, extern: "nsuValidEmailAddress".} = + ## returns true if `s` seems to be a valid e-mail address. + ## The checking also uses a domain list. + const + chars = Letters + Digits + {'!','#','$','%','&', + '\'','*','+','/','=','?','^','_','`','{','}','|','~','-','.'} + var i = 0 + if s[i] notin chars or s[i] == '.': return false + while s[i] in chars: + if s[i] == '.' and s[i+1] == '.': return false + inc(i) + if s[i] != '@': return false + var j = len(s)-1 + if s[j] notin letters: return false + while j >= i and s[j] in letters: dec(j) + inc(i) # skip '@' + while s[i] in {'0'..'9', 'a'..'z', '-', '.'}: inc(i) + if s[i] != '\0': return false + + var x = substr(s, j+1) + if len(x) == 2 and x[0] in Letters and x[1] in Letters: return true + case toLower(x) + of "com", "org", "net", "gov", "mil", "biz", "info", "mobi", "name", + "aero", "jobs", "museum": return true + return false + +when isMainModule: + assert "wuseldusel@codehome.com".validEmailAddress + +{.pop.} + diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 2b2cb1ba77..f33950376e 100755 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -351,23 +351,6 @@ proc `/` * (head, tail: string): string {.noSideEffect.} = ## The same as ``joinPath(head, tail)`` return joinPath(head, tail) -proc SplitPath*(path: string, head, tail: var string) {.noSideEffect, - deprecated.} = - ## **Deprecated since version 0.8.2**: use the version that returns a tuple - ## instead - var - sepPos = -1 - for i in countdown(len(path)-1, 0): - if path[i] in {dirsep, altsep}: - sepPos = i - break - if sepPos >= 0: - head = substr(path, 0, sepPos-1) - tail = substr(path, sepPos+1) - else: - head = "" - tail = path # make a string copy here - proc SplitPath*(path: string): tuple[head, tail: string] {. noSideEffect, rtl, extern: "nos$1".} = ## Splits a directory into (head, tail), so that @@ -466,13 +449,6 @@ proc splitFile*(path: string): tuple[dir, name, ext: string] {. result.name = substr(path, sepPos+1, dotPos-1) result.ext = substr(path, dotPos) -proc extractDir*(path: string): string {.noSideEffect, deprecated.} = - ## Extracts the directory of a given path. This is almost the - ## same as the `head` result of `splitPath`, except that - ## ``extractDir("/usr/lib/") == "/usr/lib/"``. - ## **Deprecated since version 0.8.2**: Use ``splitFile(path).dir`` instead. - result = splitFile(path).dir - proc extractFilename*(path: string): string {. noSideEffect, rtl, extern: "nos$1".} = ## Extracts the filename of a given `path`. This is the same as @@ -495,37 +471,7 @@ proc expandFilename*(filename: string): string {.rtl, extern: "nos$1".} = if res == nil: OSError() result = $res c_free(res) - -proc SplitFilename*(filename: string, name, extension: var string) {. - noSideEffect, deprecated.} = - ## Splits a filename into (name, extension), so that - ## ``name & extension == filename``. - ## - ## Example: After ``SplitFilename("usr/local/nimrodc.html", name, ext)``, - ## `name` is "usr/local/nimrodc" and `ext` is ".html". - ## If the file has no extension, extension is the empty string. - ## **Deprecated since version 0.8.2**: Use ``splitFile(filename)`` instead. - var extPos = searchExtPos(filename) - if extPos >= 0: - name = substr(filename, 0, extPos-1) - extension = substr(filename, extPos) - else: - name = filename # make a string copy here - extension = "" - -proc extractFileExt*(filename: string): string {.noSideEffect, deprecated.} = - ## Extracts the file extension of a given `filename`. This is the - ## same as the `extension` result of `splitFilename`. - ## **Deprecated since version 0.8.2**: Use ``splitFile(filename).ext`` - ## instead. - result = splitFile(filename).ext - -proc extractFileTrunk*(filename: string): string {.noSideEffect, deprecated.} = - ## Extracts the file name of a given `filename`. This removes any - ## directory information and the file extension. - ## **Deprecated since version 0.8.2**: Use ``splitFile(path).name`` instead. - result = splitFile(filename).name - + proc ChangeFileExt*(filename, ext: string): string {. noSideEffect, rtl, extern: "nos$1".} = ## Changes the file extension to `ext`. @@ -551,11 +497,6 @@ proc addFileExt*(filename, ext: string): string {. if extPos < 0: result = filename & normExt(ext) else: result = filename -proc AppendFileExt*(filename, ext: string): string {. - noSideEffect, deprecated.} = - ## **Deprecated since version 0.8.2**: Use `addFileExt` instead. - result = addFileExt(filename, ext) - proc cmpPaths*(pathA, pathB: string): int {. noSideEffect, rtl, extern: "nos$1".} = ## Compares two paths. @@ -661,10 +602,6 @@ proc removeFile*(file: string) {.rtl, extern: "nos$1".} = ## Removes the `file`. If this fails, `EOS` is raised. if cremove(file) != 0'i32: OSError() -proc executeShellCommand*(command: string): int {.deprecated.} = - ## **Deprecated since version 0.8.2**: Use `execShellCmd` instead. - result = csystem(command) - proc execShellCmd*(command: string): int {.rtl, extern: "nos$1".} = ## Executes a `shell command`:idx:. ## @@ -781,15 +718,6 @@ proc putEnv*(key, val: string) = if SetEnvironmentVariableA(key, val) == 0'i32: OSError() -iterator iterOverEnvironment*(): tuple[key, value: string] {.deprecated.} = - ## Iterate over all environments variables. In the first component of the - ## tuple is the name of the current variable stored, in the second its value. - ## **Deprecated since version 0.8.2**: Use `envPairs` instead. - getEnvVarsC() - for i in 0..high(environment): - var p = find(environment[i], '=') - yield (substr(environment[i], 0, p-1), substr(environment[i], p+1)) - iterator envPairs*(): tuple[key, value: string] = ## Iterate over all `environments variables`:idx:. In the first component ## of the tuple is the name of the current variable stored, in the second @@ -837,10 +765,6 @@ type pcDir, ## path refers to a directory pcLinkToDir ## path refers to a symbolic link to a directory -const - pcDirectory* {.deprecated.} = pcDir ## deprecated alias - pcLinkToDirectory* {.deprecated.} = pcLinkToDir ## deprecated alias - iterator walkDir*(dir: string): tuple[kind: TPathComponent, path: string] = ## walks over the directory `dir` and yields for each directory or file in ## `dir`. The component type and full path for each item is returned. diff --git a/lib/pure/osproc.nim b/lib/pure/osproc.nim index 2816158818..6add08d269 100755 --- a/lib/pure/osproc.nim +++ b/lib/pure/osproc.nim @@ -46,22 +46,10 @@ proc execProcess*(command: string, ## A convenience procedure that executes ``command`` with ``startProcess`` ## and returns its output as a string. -proc executeProcess*(command: string, - options: set[TProcessOption] = {poStdErrToStdOut, - poUseShell}): string {. - deprecated.} = - ## **Deprecated since version 0.8.2**: Use `execProcess` instead. - result = execProcess(command, options) - proc execCmd*(command: string): int {.rtl, extern: "nosp$1".} ## Executes ``command`` and returns its error code. Standard input, output, ## error streams are inherited from the calling process. -proc executeCommand*(command: string): int {.deprecated.} = - ## **Deprecated since version 0.8.2**: Use `execCmd` instead. - result = execCmd(command) - - proc startProcess*(command: string, workingDir: string = "", args: openarray[string] = [], diff --git a/lib/pure/parseopt.nim b/lib/pure/parseopt.nim index c4625c1610..1981c92427 100755 --- a/lib/pure/parseopt.nim +++ b/lib/pure/parseopt.nim @@ -1,7 +1,7 @@ # # # Nimrod's Runtime Library -# (c) Copyright 2010 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -53,10 +53,6 @@ when defined(os.ParamCount): result.key = "" result.val = "" - proc init*(cmdline: string = ""): TOptParser {.deprecated.} = - ## **Deprecated since version 0.8.2**: Use `initOptParser` instead. - result = initOptParser(cmdline) - proc parseWord(s: string, i: int, w: var string, delim: TCharSet = {'\x09', ' ', '\0'}): int = result = i @@ -128,10 +124,6 @@ proc cmdLineRest*(p: TOptParser): string {. ## retrieves the rest of the command line that has not been parsed yet. result = strip(substr(p.cmd, p.pos, len(p.cmd) - 1)) -proc getRestOfCommandLine*(p: TOptParser): string {.deprecated.} = - ## **Deprecated since version 0.8.2**: Use `cmdLineRest` instead. - result = cmdLineRest(p) - when defined(initOptParser): iterator getopt*(): tuple[kind: TCmdLineKind, key, val: string] = diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim index a7776bd5fd..d3346ecde8 100755 --- a/lib/pure/parseutils.nim +++ b/lib/pure/parseutils.nim @@ -1,7 +1,7 @@ # # # Nimrod's Runtime Library -# (c) Copyright 2010 Andreas Rumpf +# (c) Copyright 2011 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. diff --git a/lib/pure/regexprs.nim b/lib/pure/regexprs.nim deleted file mode 100755 index 2969098f58..0000000000 --- a/lib/pure/regexprs.nim +++ /dev/null @@ -1,179 +0,0 @@ -# -# -# Nimrod's Runtime Library -# (c) Copyright 2009 Andreas Rumpf -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## Regular expression support for Nimrod. -## Currently this module is implemented by providing a wrapper around the -## `PRCE (Perl-Compatible Regular Expressions) `_ -## C library. This means that your application will depend on the PRCE -## library's licence when using this module, which should not be a problem -## though. -## PRCE's licence follows: -## -## .. include:: ../doc/regexprs.txt -## - -# This is not just a convenient wrapper for the pcre library; the -# API will stay the same if the implementation should change. - -{.deprecated.} - -import - pcre, strutils - -type - EInvalidRegEx* = object of EInvalidValue - ## is raised if the pattern is no valid regular expression. - -const - MaxSubpatterns* = 10 - ## defines the maximum number of subpatterns that can be captured. - ## More subpatterns cannot be captured! - -proc match*(s, pattern: string, matches: var openarray[string], - start: int = 0): bool - ## returns ``true`` if ``s[start..]`` matches the ``pattern`` and - ## the captured substrings in the array ``matches``. If it does not - ## match, nothing is written into ``matches`` and ``false`` is - ## returned. - -proc match*(s, pattern: string, start: int = 0): bool - ## returns ``true`` if ``s`` matches the ``pattern`` beginning from ``start``. - -proc matchLen*(s, pattern: string, matches: var openarray[string], - start: int = 0): int - ## the same as ``match``, but it returns the length of the match, - ## if there is no match, -1 is returned. Note that a match length - ## of zero can happen. - -proc find*(s, pattern: string, matches: var openarray[string], - start: int = 0): bool - ## returns ``true`` if ``pattern`` occurs in ``s`` and the captured - ## substrings in the array ``matches``. If it does not match, nothing - ## is written into ``matches``. - -proc find*(s, pattern: string, start: int = 0): bool - ## returns ``true`` if ``pattern`` occurs in ``s``. - -proc rawCompile(pattern: string, flags: cint): PPcre = - var - msg: CString - offset: cint - com = pcre.Compile(pattern, flags, addr(msg), addr(offset), nil) - if com == nil: - var e: ref EInvalidRegEx - new(e) - e.msg = $msg & "\n" & pattern & "\n" & repeatChar(offset) & "^\n" - raise e - return com - -proc matchOrFind(s: string, pattern: PPcre, matches: var openarray[string], - start: cint): cint = - var - rawMatches: array [0..maxSubpatterns * 3 - 1, cint] - res = int(pcre.Exec(pattern, nil, s, len(s), start, 0, - cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3)) - dealloc(pattern) - if res < 0: return res - for i in 0..res-1: - var - a = rawMatches[i * 2] - b = rawMatches[i * 2 + 1] - if a >= 0'i32: matches[i] = substr(s, a, int(b)-1) - else: matches[i] = "" - return res - -proc matchOrFind(s: string, pattern: PPcre, start: cint): cint = - var - rawMatches: array [0..maxSubpatterns * 3 - 1, cint] - res = pcre.Exec(pattern, nil, s, len(s), start, 0, - cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3) - dealloc(pattern) - return res - -proc match(s, pattern: string, matches: var openarray[string], - start: int = 0): bool = - return matchOrFind(s, rawCompile(pattern, PCRE.ANCHORED), - matches, start) >= 0'i32 - -proc matchLen(s, pattern: string, matches: var openarray[string], - start: int = 0): int = - return matchOrFind(s, rawCompile(pattern, PCRE.ANCHORED), matches, start) - -proc find(s, pattern: string, matches: var openarray[string], - start: int = 0): bool = - return matchOrFind(s, rawCompile(pattern, PCRE.MULTILINE), - matches, start) >= 0'i32 - -proc match(s, pattern: string, start: int = 0): bool = - return matchOrFind(s, rawCompile(pattern, PCRE.ANCHORED), start) >= 0'i32 - -proc find(s, pattern: string, start: int = 0): bool = - return matchOrFind(s, rawCompile(pattern, PCRE.MULTILINE), start) >= 0'i32 - -template `=~` *(s, pattern: expr): expr = - ## This calls ``match`` with an implicit declared ``matches`` array that - ## can be used in the scope of the ``=~`` call: - ## - ## .. code-block:: nimrod - ## - ## if line =~ r"\s*(\w+)\s*\=\s*(\w+)": - ## # matches a key=value pair: - ## echo("Key: ", matches[1]) - ## echo("Value: ", matches[2]) - ## elif line =~ r"\s*(\#.*)": - ## # matches a comment - ## # note that the implicit ``matches`` array is different from the - ## # ``matches`` array of the first branch - ## echo("comment: ", matches[1]) - ## else: - ## echo("syntax error") - ## - when not definedInScope(matches): - var matches: array[0..maxSubPatterns-1, string] - match(s, pattern, matches) - - -const ## common regular expressions - reIdentifier* = r"\b[a-zA-Z_][a-zA-Z_0-9]*\b" ## describes an identifier - reNatural* = r"\b\d+\b" ## describes a natural number - reInteger* = r"\b[-+]?\d+\b" ## describes an integer - reHex* = r"\b0[xX][0-9a-fA-F]+\b" ## describes a hexadecimal number - reBinary* = r"\b0[bB][01]+\b" ## describes a binary number (example: 0b11101) - reOctal* = r"\b0[oO][0-7]+\b" ## describes an octal number (example: 0o777) - reFloat* = r"\b[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?\b" - ## describes a floating point number - reEmail* = r"\b[a-zA-Z0-9!#$%&'*+/=?^_`{|}~\-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)" & - r"*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+(?:[a-zA-Z]{2}|com|org|" & - r"net|gov|mil|biz|info|mobi|name|aero|jobs|museum)\b" - ## describes a common email address - reURL* = r"\b(http(s)?|ftp|gopher|telnet|file|notes|ms\-help):" & - r"((//)|(\\\\))+[\w\d:#@%/;$()~_?\+\-\=\\\.\&]*\b" - ## describes an URL - -proc verbose*(pattern: string): string {.noSideEffect.} = - ## deletes whitespace from a pattern that is not escaped or in a character - ## class. This is modelled after Perl's ``/x`` modifier. - result = "" - var i = 0 - while i < pattern.len: - case pattern[i] - of ' ', '\t': - inc i - of '\\': - add result, '\\' - add result, pattern[i+1] - inc i, 2 - of '[': - while pattern[i] != ']' and pattern[i] != '\0': - add result, pattern[i] - inc i - else: - add result, pattern[i] - inc i - diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 58e1e5feda..9b4b09fae8 100755 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -480,40 +480,40 @@ proc align*(s: string, count: int): string {. for i in spaces..count-1: result[i] = s[i-spaces] else: result = s - -iterator tokenize*(s: string, seps: set[char] = Whitespace): tuple[ - token: string, isSep: bool] = - ## Tokenizes the string `s` into substrings. - ## - ## Substrings are separated by a substring containing only `seps`. - ## Examples: - ## - ## .. code-block:: nimrod - ## for word in tokenize(" this is an example "): - ## writeln(stdout, word) - ## - ## Results in: - ## - ## .. code-block:: nimrod - ## (" ", true) - ## ("this", false) - ## (" ", true) - ## ("is", false) - ## (" ", true) - ## ("an", false) - ## (" ", true) - ## ("example", false) - ## (" ", true) - var i = 0 - while true: - var j = i - var isSep = s[j] in seps - while j < s.len and (s[j] in seps) == isSep: inc(j) - if j > i: - yield (substr(s, i, j-1), isSep) - else: - break - i = j + +iterator tokenize*(s: string, seps: set[char] = Whitespace): tuple[ + token: string, isSep: bool] = + ## Tokenizes the string `s` into substrings. + ## + ## Substrings are separated by a substring containing only `seps`. + ## Examples: + ## + ## .. code-block:: nimrod + ## for word in tokenize(" this is an example "): + ## writeln(stdout, word) + ## + ## Results in: + ## + ## .. code-block:: nimrod + ## (" ", true) + ## ("this", false) + ## (" ", true) + ## ("is", false) + ## (" ", true) + ## ("an", false) + ## (" ", true) + ## ("example", false) + ## (" ", true) + var i = 0 + while true: + var j = i + var isSep = s[j] in seps + while j < s.len and (s[j] in seps) == isSep: inc(j) + if j > i: + yield (substr(s, i, j-1), isSep) + else: + break + i = j proc wordWrap*(s: string, maxLineWidth = 80, splitLongWords = true, @@ -544,6 +544,33 @@ proc wordWrap*(s: string, maxLineWidth = 80, SpaceLeft = SpaceLeft - len(Word) result.add(word) +proc unindent*(s: string, eatAllIndent = false): string {. + noSideEffect, rtl, extern: "nsuUnindent".} = + ## unindents `s`. + result = newStringOfCap(s.len) + var i = 0 + var pattern = true + var indent = 0 + while s[i] == ' ': inc i + var level = if i == 0: -1 else: i + while i < s.len: + if s[i] == ' ': + if i > 0 and s[i-1] in {'\l', '\c'}: + pattern = true + indent = 0 + if pattern: + inc(indent) + if indent > level and not eatAllIndent: + result.add(s[i]) + if level < 0: level = indent + else: + # a space somewhere: do not delete + result.add(s[i]) + else: + pattern = false + result.add(s[i]) + inc i + proc startsWith*(s, prefix: string): bool {.noSideEffect, rtl, extern: "nsuStartsWith".} = ## Returns true iff ``s`` starts with ``prefix``. @@ -827,34 +854,6 @@ proc escape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect, of '\"': add(result, "\\\"") else: add(result, c) add(result, suffix) - -proc validEmailAddress*(s: string): bool {.noSideEffect, - rtl, extern: "nsuValidEmailAddress".} = - ## returns true if `s` seems to be a valid e-mail address. - ## The checking also uses a domain list. - ## Note: This will be moved to another module soon. - const - chars = Letters + Digits + {'!','#','$','%','&', - '\'','*','+','/','=','?','^','_','`','{','}','|','~','-','.'} - var i = 0 - if s[i] notin chars or s[i] == '.': return false - while s[i] in chars: - if s[i] == '.' and s[i+1] == '.': return false - inc(i) - if s[i] != '@': return false - var j = len(s)-1 - if s[j] notin letters: return false - while j >= i and s[j] in letters: dec(j) - inc(i) # skip '@' - while s[i] in {'0'..'9', 'a'..'z', '-', '.'}: inc(i) - if s[i] != '\0': return false - - var x = substr(s, j+1) - if len(x) == 2 and x[0] in Letters and x[1] in Letters: return true - case toLower(x) - of "com", "org", "net", "gov", "mil", "biz", "info", "mobi", "name", - "aero", "jobs", "museum": return true - return false proc validIdentifier*(s: string): bool {.noSideEffect, rtl, extern: "nsuValidIdentifier".} = diff --git a/lib/system/threads.nim b/lib/system/threads.nim index ccca85cb72..a458dffe95 100755 --- a/lib/system/threads.nim +++ b/lib/system/threads.nim @@ -254,7 +254,7 @@ type ## that should not be part of a message! Use ## a ``TThreadId`` for that. emptyFn: proc () - dataFn: proc (p: TMsg) + dataFn: proc (m: TMsg) data: TMsg TThreadId*[TMsg] = ptr TThread[TMsg] ## the current implementation uses ## a pointer as a thread ID. diff --git a/tests/accept/run/tgenericprocvar.nim b/tests/accept/run/tgenericprocvar.nim new file mode 100644 index 0000000000..7fdc58ca46 --- /dev/null +++ b/tests/accept/run/tgenericprocvar.nim @@ -0,0 +1,19 @@ +discard """ + output: "0false" +""" + +# Test multiple generic instantiation of generic proc vars: + +proc threadProcWrapper[TMsg]() = + var x: TMsg + stdout.write($x) + +#var x = threadProcWrapper[int] +#x() + +#var y = threadProcWrapper[bool] +#y() + +threadProcWrapper[int]() +threadProcWrapper[bool]() + diff --git a/todo.txt b/todo.txt index 494603083f..4ac2a57033 100755 --- a/todo.txt +++ b/todo.txt @@ -3,9 +3,9 @@ Version 0.8.14 - ``var T`` as a return type; easy to prove that location does not escape its stack frame -- strutils.unindent - document Nimrod's two phase symbol lookup for generics - make ^ available as operator +- optional indentation for 'case' statement - make threadvar efficient again on linux after testing - test the sort implementation again - export re-entrant and non-reentrant locks and condition vars diff --git a/tools/sunset.tmpl b/tools/sunset.tmpl index faa40a2953..6127da568a 100755 --- a/tools/sunset.tmpl +++ b/tools/sunset.tmpl @@ -65,7 +65,7 @@