Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 34 additions & 13 deletions lib/impure/nre.nim
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,14 @@ when defined(nimPreviewSlimSystem):
export options

type
Regex* = ref object
RegexDesc = object
pattern*: string
pcreObj: ptr pcre.Pcre ## not nil
pcreExtra: ptr pcre.ExtraData ## nil

captureNameToId: Table[string, int]

Regex* = ref RegexDesc
## Represents the pattern that things are matched against, constructed with
## `re(string)`. Examples: `re"foo"`, `re(r"(*ANYCRLF)(?x)foo #
## comment".`
Expand Down Expand Up @@ -145,11 +152,6 @@ type
## `DOLLAR_ENDONLY`, `FIRSTLINE`, `NO_AUTO_CAPTURE`,
## `JAVASCRIPT_COMPAT`, `U`, `NO_STUDY`. In other PCRE wrappers, you
## will need to pass these as separate flags to PCRE.
pattern*: string
pcreObj: ptr pcre.Pcre ## not nil
pcreExtra: ptr pcre.ExtraData ## nil

captureNameToId: Table[string, int]

RegexMatch* = object
## Usually seen as Option[RegexMatch], it represents the result of an
Expand Down Expand Up @@ -216,12 +218,28 @@ type
## for whatever reason. The message contains the error
## code.

proc destroyRegex(pattern: Regex) =
`=destroy`(pattern.pattern)
pcre.free_substring(cast[cstring](pattern.pcreObj))
if pattern.pcreExtra != nil:
pcre.free_study(pattern.pcreExtra)
`=destroy`(pattern.captureNameToId)
when defined(gcDestructors):
when defined(nimAllowNonVarDestructor) and defined(nimPreviewNonVarDestructor):
proc `=destroy`(pattern: RegexDesc) =
`=destroy`(pattern.pattern)
pcre.free_substring(cast[cstring](pattern.pcreObj))
if pattern.pcreExtra != nil:
pcre.free_study(pattern.pcreExtra)
`=destroy`(pattern.captureNameToId)
else:
proc `=destroy`(pattern: var RegexDesc) =
`=destroy`(pattern.pattern)
pcre.free_substring(cast[cstring](pattern.pcreObj))
if pattern.pcreExtra != nil:
pcre.free_study(pattern.pcreExtra)
`=destroy`(pattern.captureNameToId)
else:
proc destroyRegex(pattern: Regex) =
`=destroy`(pattern.pattern)
pcre.free_substring(cast[cstring](pattern.pcreObj))
if pattern.pcreExtra != nil:
pcre.free_study(pattern.pcreExtra)
`=destroy`(pattern.captureNameToId)

proc getinfo[T](pattern: Regex, opt: cint): T =
let retcode = pcre.fullinfo(pattern.pcreObj, pattern.pcreExtra, opt, addr result)
Expand Down Expand Up @@ -251,7 +269,10 @@ proc getNameToNumberTable(pattern: Regex): Table[string, int] =
result[name] = num

proc initRegex(pattern: string, flags: int, study = true): Regex =
new(result, destroyRegex)
when defined(gcDestructors):
result = Regex()
else:
new(result, destroyRegex)
result.pattern = pattern

var errorMsg: cstring
Expand Down
38 changes: 26 additions & 12 deletions lib/system.nim
Original file line number Diff line number Diff line change
Expand Up @@ -125,18 +125,32 @@ proc unsafeAddr*[T](x: T): ptr T {.magic: "Addr", noSideEffect.} =

const ThisIsSystem = true

proc new*[T](a: var ref T, finalizer: proc (x: ref T) {.nimcall.}) {.
magic: "NewFinalize", noSideEffect.}
## Creates a new object of type `T` and returns a safe (traced)
## reference to it in `a`.
##
## When the garbage collector frees the object, `finalizer` is called.
## The `finalizer` may not keep a reference to the
## object pointed to by `x`. The `finalizer` cannot prevent the GC from
## freeing the object.
##
## **Note**: The `finalizer` refers to the type `T`, not to the object!
## This means that for each object of type `T` the finalizer will be called!
when not defined(gcArc) and not defined(gcOrc) and not defined(gcAtomicArc):
proc new*[T](a: var ref T, finalizer: proc (x: ref T) {.nimcall.}) {.
magic: "NewFinalize", noSideEffect.}
## Creates a new object of type `T` and returns a safe (traced)
## reference to it in `a`.
##
## When the garbage collector frees the object, `finalizer` is called.
## The `finalizer` may not keep a reference to the
## object pointed to by `x`. The `finalizer` cannot prevent the GC from
## freeing the object.
##
## **Note**: The `finalizer` refers to the type `T`, not to the object!
## This means that for each object of type `T` the finalizer will be called!
else:
proc new*[T](a: var ref T, finalizer: proc (x: ref T) {.nimcall.}) {.
magic: "NewFinalize", noSideEffect, deprecated: "`finalizer` is not supported by arc/orc".}
## Creates a new object of type `T` and returns a safe (traced)
## reference to it in `a`.
##
## When the garbage collector frees the object, `finalizer` is called.
## The `finalizer` may not keep a reference to the
## object pointed to by `x`. The `finalizer` cannot prevent the GC from
## freeing the object.
##
## **Note**: The `finalizer` refers to the type `T`, not to the object!
## This means that for each object of type `T` the finalizer will be called!

proc `=wasMoved`*[T](obj: var T) {.magic: "WasMoved", noSideEffect.} =
## Generic `wasMoved`:idx: implementation that can be overridden.
Expand Down