fixes merge conflict
This commit is contained in:
commit
12bd1c494c
16 changed files with 235 additions and 213 deletions
|
|
@ -42,8 +42,7 @@ proc newLine(p: var TTmplParser) =
|
||||||
|
|
||||||
proc scanPar(p: var TTmplParser, d: int) =
|
proc scanPar(p: var TTmplParser, d: int) =
|
||||||
var i = d
|
var i = d
|
||||||
let hi = p.x.len - 1
|
while i < p.x.len:
|
||||||
while i <= hi:
|
|
||||||
case p.x[i]
|
case p.x[i]
|
||||||
of '(': inc(p.par)
|
of '(': inc(p.par)
|
||||||
of ')': dec(p.par)
|
of ')': dec(p.par)
|
||||||
|
|
@ -63,22 +62,19 @@ const
|
||||||
|
|
||||||
proc parseLine(p: var TTmplParser) =
|
proc parseLine(p: var TTmplParser) =
|
||||||
var j = 0
|
var j = 0
|
||||||
let hi = p.x.len - 1
|
let len = p.x.len
|
||||||
|
|
||||||
if hi == 0:
|
while j < len and p.x[j] == ' ': inc(j)
|
||||||
return
|
|
||||||
|
|
||||||
while j <= hi and p.x[j] == ' ': inc(j)
|
if len >= 2 and p.x[0] == p.nimDirective and p.x[1] == '?':
|
||||||
|
|
||||||
if p.x.len >= 2 and p.x[0] == p.nimDirective and p.x[1] == '?':
|
|
||||||
newLine(p)
|
newLine(p)
|
||||||
elif j < p.x.len and p.x[j] == p.nimDirective:
|
elif j < len and p.x[j] == p.nimDirective:
|
||||||
newLine(p)
|
newLine(p)
|
||||||
inc(j)
|
inc(j)
|
||||||
while j <= hi and p.x[j] == ' ': inc(j)
|
while j < len and p.x[j] == ' ': inc(j)
|
||||||
let d = j
|
let d = j
|
||||||
var keyw = ""
|
var keyw = ""
|
||||||
while j <= hi and p.x[j] in PatternChars:
|
while j < len and p.x[j] in PatternChars:
|
||||||
add(keyw, p.x[j])
|
add(keyw, p.x[j])
|
||||||
inc(j)
|
inc(j)
|
||||||
|
|
||||||
|
|
@ -132,7 +128,7 @@ proc parseLine(p: var TTmplParser) =
|
||||||
llStreamWrite(p.outp, "(\"")
|
llStreamWrite(p.outp, "(\"")
|
||||||
inc(p.emitPar)
|
inc(p.emitPar)
|
||||||
p.state = psTempl
|
p.state = psTempl
|
||||||
while j <= hi:
|
while j < len:
|
||||||
case p.x[j]
|
case p.x[j]
|
||||||
of '\x01'..'\x1F', '\x80'..'\xFF':
|
of '\x01'..'\x1F', '\x80'..'\xFF':
|
||||||
llStreamWrite(p.outp, "\\x")
|
llStreamWrite(p.outp, "\\x")
|
||||||
|
|
@ -160,7 +156,7 @@ proc parseLine(p: var TTmplParser) =
|
||||||
llStreamWrite(p.outp, '(')
|
llStreamWrite(p.outp, '(')
|
||||||
inc(j)
|
inc(j)
|
||||||
var curly = 0
|
var curly = 0
|
||||||
while j <= hi:
|
while j < len:
|
||||||
case p.x[j]
|
case p.x[j]
|
||||||
of '{':
|
of '{':
|
||||||
inc(j)
|
inc(j)
|
||||||
|
|
@ -185,7 +181,7 @@ proc parseLine(p: var TTmplParser) =
|
||||||
llStreamWrite(p.outp, p.conc)
|
llStreamWrite(p.outp, p.conc)
|
||||||
llStreamWrite(p.outp, p.toStr)
|
llStreamWrite(p.outp, p.toStr)
|
||||||
llStreamWrite(p.outp, '(')
|
llStreamWrite(p.outp, '(')
|
||||||
while j <= hi and p.x[j] in PatternChars:
|
while j < len and p.x[j] in PatternChars:
|
||||||
llStreamWrite(p.outp, p.x[j])
|
llStreamWrite(p.outp, p.x[j])
|
||||||
inc(j)
|
inc(j)
|
||||||
llStreamWrite(p.outp, ')')
|
llStreamWrite(p.outp, ')')
|
||||||
|
|
|
||||||
|
|
@ -263,7 +263,8 @@ proc newConfigRef*(): ConfigRef =
|
||||||
linkOptions: "",
|
linkOptions: "",
|
||||||
compileOptions: "",
|
compileOptions: "",
|
||||||
ccompilerpath: "",
|
ccompilerpath: "",
|
||||||
toCompile: @[]
|
toCompile: @[],
|
||||||
|
arguments: ""
|
||||||
)
|
)
|
||||||
setTargetFromSystem(result.target)
|
setTargetFromSystem(result.target)
|
||||||
# enable colors by default on terminals
|
# enable colors by default on terminals
|
||||||
|
|
@ -562,20 +563,6 @@ proc isDynlibOverride*(conf: ConfigRef; lib: string): bool =
|
||||||
result = optDynlibOverrideAll in conf.globalOptions or
|
result = optDynlibOverrideAll in conf.globalOptions or
|
||||||
conf.dllOverrides.hasKey(lib.canonDynlibName)
|
conf.dllOverrides.hasKey(lib.canonDynlibName)
|
||||||
|
|
||||||
proc binaryStrSearch*(x: openArray[string], y: string): int =
|
|
||||||
var a = 0
|
|
||||||
var b = len(x) - 1
|
|
||||||
while a <= b:
|
|
||||||
var mid = (a + b) div 2
|
|
||||||
var c = cmpIgnoreCase(x[mid], y)
|
|
||||||
if c < 0:
|
|
||||||
a = mid + 1
|
|
||||||
elif c > 0:
|
|
||||||
b = mid - 1
|
|
||||||
else:
|
|
||||||
return mid
|
|
||||||
result = - 1
|
|
||||||
|
|
||||||
proc parseIdeCmd*(s: string): IdeCmd =
|
proc parseIdeCmd*(s: string): IdeCmd =
|
||||||
case s:
|
case s:
|
||||||
of "sug": ideSug
|
of "sug": ideSug
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
strutils
|
strutils
|
||||||
|
from algorithm import binarySearch
|
||||||
|
|
||||||
type
|
type
|
||||||
TokenClass* = enum
|
TokenClass* = enum
|
||||||
|
|
@ -365,32 +366,10 @@ proc generalStrLit(g: var GeneralTokenizer, position: int): int =
|
||||||
result = pos
|
result = pos
|
||||||
|
|
||||||
proc isKeyword(x: openArray[string], y: string): int =
|
proc isKeyword(x: openArray[string], y: string): int =
|
||||||
var a = 0
|
binarySearch(x, y)
|
||||||
var b = len(x) - 1
|
|
||||||
while a <= b:
|
|
||||||
var mid = (a + b) div 2
|
|
||||||
var c = cmp(x[mid], y)
|
|
||||||
if c < 0:
|
|
||||||
a = mid + 1
|
|
||||||
elif c > 0:
|
|
||||||
b = mid - 1
|
|
||||||
else:
|
|
||||||
return mid
|
|
||||||
result = - 1
|
|
||||||
|
|
||||||
proc isKeywordIgnoreCase(x: openArray[string], y: string): int =
|
proc isKeywordIgnoreCase(x: openArray[string], y: string): int =
|
||||||
var a = 0
|
binarySearch(x, y, cmpIgnoreCase)
|
||||||
var b = len(x) - 1
|
|
||||||
while a <= b:
|
|
||||||
var mid = (a + b) div 2
|
|
||||||
var c = cmpIgnoreCase(x[mid], y)
|
|
||||||
if c < 0:
|
|
||||||
a = mid + 1
|
|
||||||
elif c > 0:
|
|
||||||
b = mid - 1
|
|
||||||
else:
|
|
||||||
return mid
|
|
||||||
result = - 1
|
|
||||||
|
|
||||||
type
|
type
|
||||||
TokenizerFlag = enum
|
TokenizerFlag = enum
|
||||||
|
|
|
||||||
|
|
@ -208,6 +208,7 @@ proc nextSplitPoint*(s: string, start: int): int =
|
||||||
dec(result) # last valid index
|
dec(result) # last valid index
|
||||||
|
|
||||||
proc esc*(target: OutputTarget, s: string, splitAfter = -1): string =
|
proc esc*(target: OutputTarget, s: string, splitAfter = -1): string =
|
||||||
|
## Escapes the HTML.
|
||||||
result = ""
|
result = ""
|
||||||
if splitAfter >= 0:
|
if splitAfter >= 0:
|
||||||
var partLen = 0
|
var partLen = 0
|
||||||
|
|
@ -769,43 +770,45 @@ proc renderTocEntries*(d: var RstGenerator, j: var int, lvl: int,
|
||||||
result.add(tmp)
|
result.add(tmp)
|
||||||
|
|
||||||
proc renderImage(d: PDoc, n: PRstNode, result: var string) =
|
proc renderImage(d: PDoc, n: PRstNode, result: var string) =
|
||||||
template valid(s): bool =
|
|
||||||
s.len > 0 and allCharsInSet(s, {'.','/',':','%','_','\\','\128'..'\xFF'} +
|
|
||||||
Digits + Letters + WhiteSpace)
|
|
||||||
let
|
let
|
||||||
arg = getArgument(n)
|
arg = getArgument(n)
|
||||||
isObject = arg.toLowerAscii().endsWith(".svg")
|
|
||||||
var
|
var
|
||||||
options = ""
|
options = ""
|
||||||
content = ""
|
|
||||||
var s = getFieldValue(n, "scale")
|
|
||||||
if s.valid: dispA(d.target, options, if isObject: "" else: " scale=\"$1\"",
|
|
||||||
" scale=$1", [strip(s)])
|
|
||||||
|
|
||||||
s = getFieldValue(n, "height")
|
var s = esc(d.target, getFieldValue(n, "scale").strip())
|
||||||
if s.valid: dispA(d.target, options, " height=\"$1\"", " height=$1", [strip(s)])
|
if s.len > 0:
|
||||||
|
dispA(d.target, options, " scale=\"$1\"", " scale=$1", [s])
|
||||||
|
|
||||||
s = getFieldValue(n, "width")
|
s = esc(d.target, getFieldValue(n, "height").strip())
|
||||||
if s.valid: dispA(d.target, options, " width=\"$1\"", " width=$1", [strip(s)])
|
if s.len > 0:
|
||||||
|
dispA(d.target, options, " height=\"$1\"", " height=$1", [s])
|
||||||
|
|
||||||
s = getFieldValue(n, "alt")
|
s = esc(d.target, getFieldValue(n, "width").strip())
|
||||||
if s.valid:
|
if s.len > 0:
|
||||||
# <object> displays its content if it cannot render the image
|
dispA(d.target, options, " width=\"$1\"", " width=$1", [s])
|
||||||
if isObject: dispA(d.target, content, "$1", "", [strip(s)])
|
|
||||||
else: dispA(d.target, options, " alt=\"$1\"", "", [strip(s)])
|
|
||||||
|
|
||||||
s = getFieldValue(n, "align")
|
s = esc(d.target, getFieldValue(n, "alt").strip())
|
||||||
if s.valid: dispA(d.target, options, " align=\"$1\"", "", [strip(s)])
|
if s.len > 0:
|
||||||
|
dispA(d.target, options, " alt=\"$1\"", "", [s])
|
||||||
|
|
||||||
|
s = esc(d.target, getFieldValue(n, "align").strip())
|
||||||
|
if s.len > 0:
|
||||||
|
dispA(d.target, options, " align=\"$1\"", "", [s])
|
||||||
|
|
||||||
if options.len > 0: options = dispF(d.target, "$1", "[$1]", [options])
|
if options.len > 0: options = dispF(d.target, "$1", "[$1]", [options])
|
||||||
|
|
||||||
if arg.valid:
|
var htmlOut = ""
|
||||||
let htmlOut = if isObject:
|
if arg.endsWith(".mp4") or arg.endsWith(".ogg") or
|
||||||
"<object data=\"$1\" type=\"image/svg+xml\"$2 >" & content & "</object>"
|
arg.endsWith(".webm"):
|
||||||
|
htmlOut = """
|
||||||
|
<video src="$1"$2 autoPlay='true' loop='true' muted='true'>
|
||||||
|
Sorry, your browser doesn't support embedded videos
|
||||||
|
</video>
|
||||||
|
"""
|
||||||
else:
|
else:
|
||||||
"<img src=\"$1\"$2 />"
|
htmlOut = "<img src=\"$1\"$2/>"
|
||||||
dispA(d.target, result, htmlOut, "\\includegraphics$2{$1}",
|
dispA(d.target, result, htmlOut, "\\includegraphics$2{$1}",
|
||||||
[arg, options])
|
[esc(d.target, arg), options])
|
||||||
if len(n) >= 3: renderRstToOut(d, n.sons[2], result)
|
if len(n) >= 3: renderRstToOut(d, n.sons[2], result)
|
||||||
|
|
||||||
proc renderSmiley(d: PDoc, n: PRstNode, result: var string) =
|
proc renderSmiley(d: PDoc, n: PRstNode, result: var string) =
|
||||||
|
|
@ -881,7 +884,8 @@ proc buildLinesHTMLTable(d: PDoc; params: CodeBlockParams, code: string):
|
||||||
inc d.listingCounter
|
inc d.listingCounter
|
||||||
let id = $d.listingCounter
|
let id = $d.listingCounter
|
||||||
if not params.numberLines:
|
if not params.numberLines:
|
||||||
result = (d.config.getOrDefault"doc.listing_start" % [id, $params.lang],
|
result = (d.config.getOrDefault"doc.listing_start" %
|
||||||
|
[id, sourceLanguageToStr[params.lang]],
|
||||||
d.config.getOrDefault"doc.listing_end" % id)
|
d.config.getOrDefault"doc.listing_end" % id)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -894,7 +898,8 @@ proc buildLinesHTMLTable(d: PDoc; params: CodeBlockParams, code: string):
|
||||||
line.inc
|
line.inc
|
||||||
codeLines.dec
|
codeLines.dec
|
||||||
result.beginTable.add("</pre></td><td>" & (
|
result.beginTable.add("</pre></td><td>" & (
|
||||||
d.config.getOrDefault"doc.listing_start" % [id, $params.lang]))
|
d.config.getOrDefault"doc.listing_start" %
|
||||||
|
[id, sourceLanguageToStr[params.lang]]))
|
||||||
result.endTable = (d.config.getOrDefault"doc.listing_end" % id) &
|
result.endTable = (d.config.getOrDefault"doc.listing_end" % id) &
|
||||||
"</td></tr></tbody></table>" & (
|
"</td></tr></tbody></table>" & (
|
||||||
d.config.getOrDefault"doc.listing_button" % id)
|
d.config.getOrDefault"doc.listing_button" % id)
|
||||||
|
|
@ -944,7 +949,7 @@ proc renderCodeBlock(d: PDoc, n: PRstNode, result: var string) =
|
||||||
proc renderContainer(d: PDoc, n: PRstNode, result: var string) =
|
proc renderContainer(d: PDoc, n: PRstNode, result: var string) =
|
||||||
var tmp = ""
|
var tmp = ""
|
||||||
renderRstToOut(d, n.sons[2], tmp)
|
renderRstToOut(d, n.sons[2], tmp)
|
||||||
var arg = strip(getArgument(n))
|
var arg = esc(d.target, strip(getArgument(n)))
|
||||||
if arg == "":
|
if arg == "":
|
||||||
dispA(d.target, result, "<div>$1</div>", "$1", [tmp])
|
dispA(d.target, result, "<div>$1</div>", "$1", [tmp])
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -84,17 +84,27 @@ proc binarySearch*[T, K](a: openArray[T], key: K,
|
||||||
if (len and (len - 1)) == 0:
|
if (len and (len - 1)) == 0:
|
||||||
# when `len` is a power of 2, a faster shr can be used.
|
# when `len` is a power of 2, a faster shr can be used.
|
||||||
var step = len shr 1
|
var step = len shr 1
|
||||||
|
var cmpRes: int
|
||||||
while step > 0:
|
while step > 0:
|
||||||
let i = result or step
|
let i = result or step
|
||||||
if cmp(a[i], key) < 1:
|
cmpRes = cmp(a[i], key)
|
||||||
|
if cmpRes == 0:
|
||||||
|
return i
|
||||||
|
|
||||||
|
if cmpRes < 1:
|
||||||
result = i
|
result = i
|
||||||
step = step shr 1
|
step = step shr 1
|
||||||
if cmp(a[result], key) != 0: result = -1
|
if cmp(a[result], key) != 0: result = -1
|
||||||
else:
|
else:
|
||||||
var b = len
|
var b = len
|
||||||
|
var cmpRes: int
|
||||||
while result < b:
|
while result < b:
|
||||||
var mid = (result + b) shr 1
|
var mid = (result + b) shr 1
|
||||||
if cmp(a[mid], key) < 0:
|
cmpRes = cmp(a[mid], key)
|
||||||
|
if cmpRes == 0:
|
||||||
|
return mid
|
||||||
|
|
||||||
|
if cmpRes < 0:
|
||||||
result = mid + 1
|
result = mid + 1
|
||||||
else:
|
else:
|
||||||
b = mid
|
b = mid
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
## the ``graphics`` module.
|
## the ``graphics`` module.
|
||||||
|
|
||||||
import strutils
|
import strutils
|
||||||
|
from algorithm import binarySearch
|
||||||
|
|
||||||
type
|
type
|
||||||
Color* = distinct int ## a color stored as RGB
|
Color* = distinct int ## a color stored as RGB
|
||||||
|
|
@ -371,37 +372,28 @@ proc `$`*(c: Color): string =
|
||||||
## converts a color into its textual representation. Example: ``#00FF00``.
|
## converts a color into its textual representation. Example: ``#00FF00``.
|
||||||
result = '#' & toHex(int(c), 6)
|
result = '#' & toHex(int(c), 6)
|
||||||
|
|
||||||
proc binaryStrSearch(x: openArray[tuple[name: string, col: Color]],
|
proc colorNameCmp(x: tuple[name: string, col: Color], y: string): int =
|
||||||
y: string): int =
|
result = cmpIgnoreCase(x.name, y)
|
||||||
var a = 0
|
|
||||||
var b = len(x) - 1
|
|
||||||
while a <= b:
|
|
||||||
var mid = (a + b) div 2
|
|
||||||
var c = cmp(x[mid].name, y)
|
|
||||||
if c < 0: a = mid + 1
|
|
||||||
elif c > 0: b = mid - 1
|
|
||||||
else: return mid
|
|
||||||
result = - 1
|
|
||||||
|
|
||||||
proc parseColor*(name: string): Color =
|
proc parseColor*(name: string): Color =
|
||||||
## parses `name` to a color value. If no valid color could be
|
## parses `name` to a color value. If no valid color could be
|
||||||
## parsed ``EInvalidValue`` is raised.
|
## parsed ``EInvalidValue`` is raised. Case insensitive.
|
||||||
if name[0] == '#':
|
if name[0] == '#':
|
||||||
result = Color(parseHexInt(name))
|
result = Color(parseHexInt(name))
|
||||||
else:
|
else:
|
||||||
var idx = binaryStrSearch(colorNames, name)
|
var idx = binarySearch(colorNames, name, colorNameCmp)
|
||||||
if idx < 0: raise newException(ValueError, "unknown color: " & name)
|
if idx < 0: raise newException(ValueError, "unknown color: " & name)
|
||||||
result = colorNames[idx][1]
|
result = colorNames[idx][1]
|
||||||
|
|
||||||
proc isColor*(name: string): bool =
|
proc isColor*(name: string): bool =
|
||||||
## returns true if `name` is a known color name or a hexadecimal color
|
## returns true if `name` is a known color name or a hexadecimal color
|
||||||
## prefixed with ``#``.
|
## prefixed with ``#``. Case insensitive.
|
||||||
if name[0] == '#':
|
if name[0] == '#':
|
||||||
for i in 1 .. name.len-1:
|
for i in 1 .. name.len-1:
|
||||||
if name[i] notin {'0'..'9', 'a'..'f', 'A'..'F'}: return false
|
if name[i] notin {'0'..'9', 'a'..'f', 'A'..'F'}: return false
|
||||||
result = true
|
result = true
|
||||||
else:
|
else:
|
||||||
result = binaryStrSearch(colorNames, name) >= 0
|
result = binarySearch(colorNames, name, colorNameCmp) >= 0
|
||||||
|
|
||||||
proc rgb*(r, g, b: range[0..255]): Color =
|
proc rgb*(r, g, b: range[0..255]): Color =
|
||||||
## constructs a color from RGB values.
|
## constructs a color from RGB values.
|
||||||
|
|
|
||||||
|
|
@ -362,15 +362,13 @@ when not defined(ssl):
|
||||||
type SSLContext = ref object
|
type SSLContext = ref object
|
||||||
var defaultSSLContext {.threadvar.}: SSLContext
|
var defaultSSLContext {.threadvar.}: SSLContext
|
||||||
|
|
||||||
|
proc getDefaultSSL(): SSLContext =
|
||||||
|
result = defaultSslContext
|
||||||
when defined(ssl):
|
when defined(ssl):
|
||||||
defaultSSLContext = newContext(verifyMode = CVerifyNone)
|
if result == nil:
|
||||||
template contextOrDefault(ctx: SSLContext): SSLContext =
|
|
||||||
var result = ctx
|
|
||||||
if ctx == nil:
|
|
||||||
if defaultSSLContext == nil:
|
|
||||||
defaultSSLContext = newContext(verifyMode = CVerifyNone)
|
defaultSSLContext = newContext(verifyMode = CVerifyNone)
|
||||||
result = defaultSSLContext
|
result = defaultSSLContext
|
||||||
result
|
doAssert result != nil, "failure to initialize the SSL context"
|
||||||
|
|
||||||
proc newProxy*(url: string, auth = ""): Proxy =
|
proc newProxy*(url: string, auth = ""): Proxy =
|
||||||
## Constructs a new ``TProxy`` object.
|
## Constructs a new ``TProxy`` object.
|
||||||
|
|
@ -480,9 +478,9 @@ proc format(p: MultipartData): tuple[contentType, body: string] =
|
||||||
result.body.add("--" & bound & "--\c\L")
|
result.body.add("--" & bound & "--\c\L")
|
||||||
|
|
||||||
proc request*(url: string, httpMethod: string, extraHeaders = "",
|
proc request*(url: string, httpMethod: string, extraHeaders = "",
|
||||||
body = "", sslContext = defaultSSLContext, timeout = -1,
|
body = "", sslContext = getDefaultSSL(), timeout = -1,
|
||||||
userAgent = defUserAgent, proxy: Proxy = nil): Response
|
userAgent = defUserAgent, proxy: Proxy = nil): Response
|
||||||
{.deprecated.} =
|
{.deprecated: "use HttpClient.request instead".} =
|
||||||
## | Requests ``url`` with the custom method string specified by the
|
## | Requests ``url`` with the custom method string specified by the
|
||||||
## | ``httpMethod`` parameter.
|
## | ``httpMethod`` parameter.
|
||||||
## | Extra headers can be specified and must be separated by ``\c\L``
|
## | Extra headers can be specified and must be separated by ``\c\L``
|
||||||
|
|
@ -580,7 +578,7 @@ proc request*(url: string, httpMethod: string, extraHeaders = "",
|
||||||
result = parseResponse(s, httpMethod != "HEAD", timeout)
|
result = parseResponse(s, httpMethod != "HEAD", timeout)
|
||||||
|
|
||||||
proc request*(url: string, httpMethod = HttpGET, extraHeaders = "",
|
proc request*(url: string, httpMethod = HttpGET, extraHeaders = "",
|
||||||
body = "", sslContext = defaultSSLContext, timeout = -1,
|
body = "", sslContext = getDefaultSSL(), timeout = -1,
|
||||||
userAgent = defUserAgent, proxy: Proxy = nil): Response
|
userAgent = defUserAgent, proxy: Proxy = nil): Response
|
||||||
{.deprecated.} =
|
{.deprecated.} =
|
||||||
## | Requests ``url`` with the specified ``httpMethod``.
|
## | Requests ``url`` with the specified ``httpMethod``.
|
||||||
|
|
@ -611,7 +609,7 @@ proc getNewLocation(lastURL: string, headers: HttpHeaders): string =
|
||||||
result = $parsed
|
result = $parsed
|
||||||
|
|
||||||
proc get*(url: string, extraHeaders = "", maxRedirects = 5,
|
proc get*(url: string, extraHeaders = "", maxRedirects = 5,
|
||||||
sslContext: SSLContext = defaultSSLContext,
|
sslContext: SSLContext = getDefaultSSL(),
|
||||||
timeout = -1, userAgent = defUserAgent,
|
timeout = -1, userAgent = defUserAgent,
|
||||||
proxy: Proxy = nil): Response {.deprecated.} =
|
proxy: Proxy = nil): Response {.deprecated.} =
|
||||||
## | GETs the ``url`` and returns a ``Response`` object
|
## | GETs the ``url`` and returns a ``Response`` object
|
||||||
|
|
@ -632,7 +630,7 @@ proc get*(url: string, extraHeaders = "", maxRedirects = 5,
|
||||||
lastURL = redirectTo
|
lastURL = redirectTo
|
||||||
|
|
||||||
proc getContent*(url: string, extraHeaders = "", maxRedirects = 5,
|
proc getContent*(url: string, extraHeaders = "", maxRedirects = 5,
|
||||||
sslContext: SSLContext = defaultSSLContext,
|
sslContext: SSLContext = getDefaultSSL(),
|
||||||
timeout = -1, userAgent = defUserAgent,
|
timeout = -1, userAgent = defUserAgent,
|
||||||
proxy: Proxy = nil): string {.deprecated.} =
|
proxy: Proxy = nil): string {.deprecated.} =
|
||||||
## | GETs the body and returns it as a string.
|
## | GETs the body and returns it as a string.
|
||||||
|
|
@ -651,7 +649,7 @@ proc getContent*(url: string, extraHeaders = "", maxRedirects = 5,
|
||||||
|
|
||||||
proc post*(url: string, extraHeaders = "", body = "",
|
proc post*(url: string, extraHeaders = "", body = "",
|
||||||
maxRedirects = 5,
|
maxRedirects = 5,
|
||||||
sslContext: SSLContext = defaultSSLContext,
|
sslContext: SSLContext = getDefaultSSL(),
|
||||||
timeout = -1, userAgent = defUserAgent,
|
timeout = -1, userAgent = defUserAgent,
|
||||||
proxy: Proxy = nil,
|
proxy: Proxy = nil,
|
||||||
multipart: MultipartData = nil): Response {.deprecated.} =
|
multipart: MultipartData = nil): Response {.deprecated.} =
|
||||||
|
|
@ -694,7 +692,7 @@ proc post*(url: string, extraHeaders = "", body = "",
|
||||||
|
|
||||||
proc postContent*(url: string, extraHeaders = "", body = "",
|
proc postContent*(url: string, extraHeaders = "", body = "",
|
||||||
maxRedirects = 5,
|
maxRedirects = 5,
|
||||||
sslContext: SSLContext = defaultSSLContext,
|
sslContext: SSLContext = getDefaultSSL(),
|
||||||
timeout = -1, userAgent = defUserAgent,
|
timeout = -1, userAgent = defUserAgent,
|
||||||
proxy: Proxy = nil,
|
proxy: Proxy = nil,
|
||||||
multipart: MultipartData = nil): string
|
multipart: MultipartData = nil): string
|
||||||
|
|
@ -717,7 +715,7 @@ proc postContent*(url: string, extraHeaders = "", body = "",
|
||||||
return r.body
|
return r.body
|
||||||
|
|
||||||
proc downloadFile*(url: string, outputFilename: string,
|
proc downloadFile*(url: string, outputFilename: string,
|
||||||
sslContext: SSLContext = defaultSSLContext,
|
sslContext: SSLContext = getDefaultSSL(),
|
||||||
timeout = -1, userAgent = defUserAgent,
|
timeout = -1, userAgent = defUserAgent,
|
||||||
proxy: Proxy = nil) {.deprecated.} =
|
proxy: Proxy = nil) {.deprecated.} =
|
||||||
## | Downloads ``url`` and saves it to ``outputFilename``
|
## | Downloads ``url`` and saves it to ``outputFilename``
|
||||||
|
|
@ -817,7 +815,7 @@ type
|
||||||
HttpClient* = HttpClientBase[Socket]
|
HttpClient* = HttpClientBase[Socket]
|
||||||
|
|
||||||
proc newHttpClient*(userAgent = defUserAgent,
|
proc newHttpClient*(userAgent = defUserAgent,
|
||||||
maxRedirects = 5, sslContext = defaultSslContext, proxy: Proxy = nil,
|
maxRedirects = 5, sslContext = getDefaultSSL(), proxy: Proxy = nil,
|
||||||
timeout = -1): HttpClient =
|
timeout = -1): HttpClient =
|
||||||
## Creates a new HttpClient instance.
|
## Creates a new HttpClient instance.
|
||||||
##
|
##
|
||||||
|
|
@ -844,7 +842,7 @@ proc newHttpClient*(userAgent = defUserAgent,
|
||||||
result.bodyStream = newStringStream()
|
result.bodyStream = newStringStream()
|
||||||
result.getBody = true
|
result.getBody = true
|
||||||
when defined(ssl):
|
when defined(ssl):
|
||||||
result.sslContext = contextOrDefault(sslContext)
|
result.sslContext = sslContext
|
||||||
|
|
||||||
type
|
type
|
||||||
AsyncHttpClient* = HttpClientBase[AsyncSocket]
|
AsyncHttpClient* = HttpClientBase[AsyncSocket]
|
||||||
|
|
@ -852,7 +850,7 @@ type
|
||||||
{.deprecated: [PAsyncHttpClient: AsyncHttpClient].}
|
{.deprecated: [PAsyncHttpClient: AsyncHttpClient].}
|
||||||
|
|
||||||
proc newAsyncHttpClient*(userAgent = defUserAgent,
|
proc newAsyncHttpClient*(userAgent = defUserAgent,
|
||||||
maxRedirects = 5, sslContext = defaultSslContext,
|
maxRedirects = 5, sslContext = getDefaultSSL(),
|
||||||
proxy: Proxy = nil): AsyncHttpClient =
|
proxy: Proxy = nil): AsyncHttpClient =
|
||||||
## Creates a new AsyncHttpClient instance.
|
## Creates a new AsyncHttpClient instance.
|
||||||
##
|
##
|
||||||
|
|
@ -876,7 +874,7 @@ proc newAsyncHttpClient*(userAgent = defUserAgent,
|
||||||
result.bodyStream = newFutureStream[string]("newAsyncHttpClient")
|
result.bodyStream = newFutureStream[string]("newAsyncHttpClient")
|
||||||
result.getBody = true
|
result.getBody = true
|
||||||
when defined(ssl):
|
when defined(ssl):
|
||||||
result.sslContext = contextOrDefault(sslContext)
|
result.sslContext = sslContext
|
||||||
|
|
||||||
proc close*(client: HttpClient | AsyncHttpClient) =
|
proc close*(client: HttpClient | AsyncHttpClient) =
|
||||||
## Closes any connections held by the HTTP client.
|
## Closes any connections held by the HTTP client.
|
||||||
|
|
|
||||||
|
|
@ -1010,15 +1010,19 @@ proc replace*(s: string, sub: Peg, cb: proc(
|
||||||
inc(m)
|
inc(m)
|
||||||
add(result, substr(s, i))
|
add(result, substr(s, i))
|
||||||
|
|
||||||
|
when not defined(js):
|
||||||
proc transformFile*(infile, outfile: string,
|
proc transformFile*(infile, outfile: string,
|
||||||
subs: varargs[tuple[pattern: Peg, repl: string]]) {.
|
subs: varargs[tuple[pattern: Peg, repl: string]]) {.
|
||||||
rtl, extern: "npegs$1".} =
|
rtl, extern: "npegs$1".} =
|
||||||
## reads in the file `infile`, performs a parallel replacement (calls
|
## reads in the file `infile`, performs a parallel replacement (calls
|
||||||
## `parallelReplace`) and writes back to `outfile`. Raises ``EIO`` if an
|
## `parallelReplace`) and writes back to `outfile`. Raises ``EIO`` if an
|
||||||
## error occurs. This is supposed to be used for quick scripting.
|
## error occurs. This is supposed to be used for quick scripting.
|
||||||
|
##
|
||||||
|
## **Note**: this proc does not exist while using the JS backend.
|
||||||
var x = readFile(infile).string
|
var x = readFile(infile).string
|
||||||
writeFile(outfile, x.parallelReplace(subs))
|
writeFile(outfile, x.parallelReplace(subs))
|
||||||
|
|
||||||
|
|
||||||
iterator split*(s: string, sep: Peg): string =
|
iterator split*(s: string, sep: Peg): string =
|
||||||
## Splits the string `s` into substrings.
|
## Splits the string `s` into substrings.
|
||||||
##
|
##
|
||||||
|
|
@ -1121,7 +1125,7 @@ proc handleCR(L: var PegLexer, pos: int): int =
|
||||||
assert(L.buf[pos] == '\c')
|
assert(L.buf[pos] == '\c')
|
||||||
inc(L.lineNumber)
|
inc(L.lineNumber)
|
||||||
result = pos+1
|
result = pos+1
|
||||||
if L.buf[result] == '\L': inc(result)
|
if result < L.buf.len and L.buf[result] == '\L': inc(result)
|
||||||
L.lineStart = result
|
L.lineStart = result
|
||||||
|
|
||||||
proc handleLF(L: var PegLexer, pos: int): int =
|
proc handleLF(L: var PegLexer, pos: int): int =
|
||||||
|
|
@ -1217,12 +1221,13 @@ proc getEscapedChar(c: var PegLexer, tok: var Token) =
|
||||||
proc skip(c: var PegLexer) =
|
proc skip(c: var PegLexer) =
|
||||||
var pos = c.bufpos
|
var pos = c.bufpos
|
||||||
var buf = c.buf
|
var buf = c.buf
|
||||||
while true:
|
while pos < c.buf.len:
|
||||||
case buf[pos]
|
case buf[pos]
|
||||||
of ' ', '\t':
|
of ' ', '\t':
|
||||||
inc(pos)
|
inc(pos)
|
||||||
of '#':
|
of '#':
|
||||||
while not (buf[pos] in {'\c', '\L', '\0'}): inc(pos)
|
while (pos < c.buf.len) and
|
||||||
|
not (buf[pos] in {'\c', '\L', '\0'}): inc(pos)
|
||||||
of '\c':
|
of '\c':
|
||||||
pos = handleCR(c, pos)
|
pos = handleCR(c, pos)
|
||||||
buf = c.buf
|
buf = c.buf
|
||||||
|
|
@ -1238,7 +1243,7 @@ proc getString(c: var PegLexer, tok: var Token) =
|
||||||
var pos = c.bufpos + 1
|
var pos = c.bufpos + 1
|
||||||
var buf = c.buf
|
var buf = c.buf
|
||||||
var quote = buf[pos-1]
|
var quote = buf[pos-1]
|
||||||
while true:
|
while pos < c.buf.len:
|
||||||
case buf[pos]
|
case buf[pos]
|
||||||
of '\\':
|
of '\\':
|
||||||
c.bufpos = pos
|
c.bufpos = pos
|
||||||
|
|
@ -1261,7 +1266,7 @@ proc getDollar(c: var PegLexer, tok: var Token) =
|
||||||
if buf[pos] in {'0'..'9'}:
|
if buf[pos] in {'0'..'9'}:
|
||||||
tok.kind = tkBackref
|
tok.kind = tkBackref
|
||||||
tok.index = 0
|
tok.index = 0
|
||||||
while buf[pos] in {'0'..'9'}:
|
while pos < c.buf.len and buf[pos] in {'0'..'9'}:
|
||||||
tok.index = tok.index * 10 + ord(buf[pos]) - ord('0')
|
tok.index = tok.index * 10 + ord(buf[pos]) - ord('0')
|
||||||
inc(pos)
|
inc(pos)
|
||||||
else:
|
else:
|
||||||
|
|
@ -1277,11 +1282,11 @@ proc getCharSet(c: var PegLexer, tok: var Token) =
|
||||||
if buf[pos] == '^':
|
if buf[pos] == '^':
|
||||||
inc(pos)
|
inc(pos)
|
||||||
caret = true
|
caret = true
|
||||||
while true:
|
while pos < c.buf.len:
|
||||||
var ch: char
|
var ch: char
|
||||||
case buf[pos]
|
case buf[pos]
|
||||||
of ']':
|
of ']':
|
||||||
inc(pos)
|
if pos < c.buf.len: inc(pos)
|
||||||
break
|
break
|
||||||
of '\\':
|
of '\\':
|
||||||
c.bufpos = pos
|
c.bufpos = pos
|
||||||
|
|
@ -1296,11 +1301,14 @@ proc getCharSet(c: var PegLexer, tok: var Token) =
|
||||||
inc(pos)
|
inc(pos)
|
||||||
incl(tok.charset, ch)
|
incl(tok.charset, ch)
|
||||||
if buf[pos] == '-':
|
if buf[pos] == '-':
|
||||||
if buf[pos+1] == ']':
|
if pos+1 < c.buf.len and buf[pos+1] == ']':
|
||||||
incl(tok.charset, '-')
|
incl(tok.charset, '-')
|
||||||
inc(pos)
|
inc(pos)
|
||||||
else:
|
else:
|
||||||
|
if pos+1 < c.buf.len:
|
||||||
inc(pos)
|
inc(pos)
|
||||||
|
else:
|
||||||
|
break
|
||||||
var ch2: char
|
var ch2: char
|
||||||
case buf[pos]
|
case buf[pos]
|
||||||
of '\\':
|
of '\\':
|
||||||
|
|
@ -1312,8 +1320,11 @@ proc getCharSet(c: var PegLexer, tok: var Token) =
|
||||||
tok.kind = tkInvalid
|
tok.kind = tkInvalid
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
|
if pos+1 < c.buf.len:
|
||||||
ch2 = buf[pos]
|
ch2 = buf[pos]
|
||||||
inc(pos)
|
inc(pos)
|
||||||
|
else:
|
||||||
|
break
|
||||||
for i in ord(ch)+1 .. ord(ch2):
|
for i in ord(ch)+1 .. ord(ch2):
|
||||||
incl(tok.charset, chr(i))
|
incl(tok.charset, chr(i))
|
||||||
c.bufpos = pos
|
c.bufpos = pos
|
||||||
|
|
@ -1322,15 +1333,15 @@ proc getCharSet(c: var PegLexer, tok: var Token) =
|
||||||
proc getSymbol(c: var PegLexer, tok: var Token) =
|
proc getSymbol(c: var PegLexer, tok: var Token) =
|
||||||
var pos = c.bufpos
|
var pos = c.bufpos
|
||||||
var buf = c.buf
|
var buf = c.buf
|
||||||
while true:
|
while pos < c.buf.len:
|
||||||
add(tok.literal, buf[pos])
|
add(tok.literal, buf[pos])
|
||||||
inc(pos)
|
inc(pos)
|
||||||
if buf[pos] notin strutils.IdentChars: break
|
if pos < buf.len and buf[pos] notin strutils.IdentChars: break
|
||||||
c.bufpos = pos
|
c.bufpos = pos
|
||||||
tok.kind = tkIdentifier
|
tok.kind = tkIdentifier
|
||||||
|
|
||||||
proc getBuiltin(c: var PegLexer, tok: var Token) =
|
proc getBuiltin(c: var PegLexer, tok: var Token) =
|
||||||
if c.buf[c.bufpos+1] in strutils.Letters:
|
if c.bufpos+1 < c.buf.len and c.buf[c.bufpos+1] in strutils.Letters:
|
||||||
inc(c.bufpos)
|
inc(c.bufpos)
|
||||||
getSymbol(c, tok)
|
getSymbol(c, tok)
|
||||||
tok.kind = tkBuiltin
|
tok.kind = tkBuiltin
|
||||||
|
|
@ -1343,10 +1354,12 @@ proc getTok(c: var PegLexer, tok: var Token) =
|
||||||
tok.modifier = modNone
|
tok.modifier = modNone
|
||||||
setLen(tok.literal, 0)
|
setLen(tok.literal, 0)
|
||||||
skip(c)
|
skip(c)
|
||||||
|
|
||||||
case c.buf[c.bufpos]
|
case c.buf[c.bufpos]
|
||||||
of '{':
|
of '{':
|
||||||
inc(c.bufpos)
|
inc(c.bufpos)
|
||||||
if c.buf[c.bufpos] == '@' and c.buf[c.bufpos+1] == '}':
|
if c.buf[c.bufpos] == '@' and c.bufpos+2 < c.buf.len and
|
||||||
|
c.buf[c.bufpos+1] == '}':
|
||||||
tok.kind = tkCurlyAt
|
tok.kind = tkCurlyAt
|
||||||
inc(c.bufpos, 2)
|
inc(c.bufpos, 2)
|
||||||
add(tok.literal, "{@}")
|
add(tok.literal, "{@}")
|
||||||
|
|
@ -1379,13 +1392,11 @@ proc getTok(c: var PegLexer, tok: var Token) =
|
||||||
getBuiltin(c, tok)
|
getBuiltin(c, tok)
|
||||||
of '\'', '"': getString(c, tok)
|
of '\'', '"': getString(c, tok)
|
||||||
of '$': getDollar(c, tok)
|
of '$': getDollar(c, tok)
|
||||||
of '\0':
|
|
||||||
tok.kind = tkEof
|
|
||||||
tok.literal = "[EOF]"
|
|
||||||
of 'a'..'z', 'A'..'Z', '\128'..'\255':
|
of 'a'..'z', 'A'..'Z', '\128'..'\255':
|
||||||
getSymbol(c, tok)
|
getSymbol(c, tok)
|
||||||
if c.buf[c.bufpos] in {'\'', '"'} or
|
if c.buf[c.bufpos] in {'\'', '"'} or
|
||||||
c.buf[c.bufpos] == '$' and c.buf[c.bufpos+1] in {'0'..'9'}:
|
c.buf[c.bufpos] == '$' and c.bufpos+1 < c.buf.len and
|
||||||
|
c.buf[c.bufpos+1] in {'0'..'9'}:
|
||||||
case tok.literal
|
case tok.literal
|
||||||
of "i": tok.modifier = modIgnoreCase
|
of "i": tok.modifier = modIgnoreCase
|
||||||
of "y": tok.modifier = modIgnoreStyle
|
of "y": tok.modifier = modIgnoreStyle
|
||||||
|
|
@ -1406,7 +1417,7 @@ proc getTok(c: var PegLexer, tok: var Token) =
|
||||||
inc(c.bufpos)
|
inc(c.bufpos)
|
||||||
add(tok.literal, '+')
|
add(tok.literal, '+')
|
||||||
of '<':
|
of '<':
|
||||||
if c.buf[c.bufpos+1] == '-':
|
if c.bufpos+2 < c.buf.len and c.buf[c.bufpos+1] == '-':
|
||||||
inc(c.bufpos, 2)
|
inc(c.bufpos, 2)
|
||||||
tok.kind = tkArrow
|
tok.kind = tkArrow
|
||||||
add(tok.literal, "<-")
|
add(tok.literal, "<-")
|
||||||
|
|
@ -1441,14 +1452,17 @@ proc getTok(c: var PegLexer, tok: var Token) =
|
||||||
inc(c.bufpos)
|
inc(c.bufpos)
|
||||||
add(tok.literal, '^')
|
add(tok.literal, '^')
|
||||||
else:
|
else:
|
||||||
|
if c.bufpos >= c.buf.len:
|
||||||
|
tok.kind = tkEof
|
||||||
|
tok.literal = "[EOF]"
|
||||||
add(tok.literal, c.buf[c.bufpos])
|
add(tok.literal, c.buf[c.bufpos])
|
||||||
inc(c.bufpos)
|
inc(c.bufpos)
|
||||||
|
|
||||||
proc arrowIsNextTok(c: PegLexer): bool =
|
proc arrowIsNextTok(c: PegLexer): bool =
|
||||||
# the only look ahead we need
|
# the only look ahead we need
|
||||||
var pos = c.bufpos
|
var pos = c.bufpos
|
||||||
while c.buf[pos] in {'\t', ' '}: inc(pos)
|
while pos < c.buf.len and c.buf[pos] in {'\t', ' '}: inc(pos)
|
||||||
result = c.buf[pos] == '<' and c.buf[pos+1] == '-'
|
result = c.buf[pos] == '<' and (pos+1 < c.buf.len) and c.buf[pos+1] == '-'
|
||||||
|
|
||||||
# ----------------------------- parser ----------------------------------------
|
# ----------------------------- parser ----------------------------------------
|
||||||
|
|
||||||
|
|
@ -1471,7 +1485,7 @@ proc pegError(p: PegParser, msg: string, line = -1, col = -1) =
|
||||||
|
|
||||||
proc getTok(p: var PegParser) =
|
proc getTok(p: var PegParser) =
|
||||||
getTok(p, p.tok)
|
getTok(p, p.tok)
|
||||||
if p.tok.kind == tkInvalid: pegError(p, "invalid token")
|
if p.tok.kind == tkInvalid: pegError(p, "'" & p.tok.literal & "' is invalid token")
|
||||||
|
|
||||||
proc eat(p: var PegParser, kind: TokKind) =
|
proc eat(p: var PegParser, kind: TokKind) =
|
||||||
if p.tok.kind == kind: getTok(p)
|
if p.tok.kind == kind: getTok(p)
|
||||||
|
|
|
||||||
|
|
@ -86,18 +86,20 @@ proc readData*(s: Stream, buffer: pointer, bufLen: int): int =
|
||||||
## low level proc that reads data into an untyped `buffer` of `bufLen` size.
|
## low level proc that reads data into an untyped `buffer` of `bufLen` size.
|
||||||
result = s.readDataImpl(s, buffer, bufLen)
|
result = s.readDataImpl(s, buffer, bufLen)
|
||||||
|
|
||||||
|
when not defined(js):
|
||||||
proc readAll*(s: Stream): string =
|
proc readAll*(s: Stream): string =
|
||||||
## Reads all available data.
|
## Reads all available data.
|
||||||
const bufferSize = 1000
|
const bufferSize = 1024
|
||||||
result = newString(bufferSize)
|
var buffer {.noinit.}: array[bufferSize, char]
|
||||||
var r = 0
|
|
||||||
while true:
|
while true:
|
||||||
let readBytes = readData(s, addr(result[r]), bufferSize)
|
let readBytes = readData(s, addr(buffer[0]), bufferSize)
|
||||||
if readBytes < bufferSize:
|
if readBytes == 0:
|
||||||
setLen(result, r+readBytes)
|
break
|
||||||
|
let prevLen = result.len
|
||||||
|
result.setLen(prevLen + readBytes)
|
||||||
|
copyMem(addr(result[prevLen]), addr(buffer[0]), readBytes)
|
||||||
|
if readBytes < bufferSize:
|
||||||
break
|
break
|
||||||
inc r, bufferSize
|
|
||||||
setLen(result, r+bufferSize)
|
|
||||||
|
|
||||||
proc peekData*(s: Stream, buffer: pointer, bufLen: int): int =
|
proc peekData*(s: Stream, buffer: pointer, bufLen: int): int =
|
||||||
## low level proc that reads data into an untyped `buffer` of `bufLen` size
|
## low level proc that reads data into an untyped `buffer` of `bufLen` size
|
||||||
|
|
@ -131,7 +133,7 @@ proc write*(s: Stream, x: string) =
|
||||||
when nimvm:
|
when nimvm:
|
||||||
writeData(s, cstring(x), x.len)
|
writeData(s, cstring(x), x.len)
|
||||||
else:
|
else:
|
||||||
if x.len > 0: writeData(s, unsafeAddr x[0], x.len)
|
if x.len > 0: writeData(s, cstring(x), x.len)
|
||||||
|
|
||||||
proc writeLine*(s: Stream, args: varargs[string, `$`]) =
|
proc writeLine*(s: Stream, args: varargs[string, `$`]) =
|
||||||
## writes one or more strings to the the stream `s` followed
|
## writes one or more strings to the the stream `s` followed
|
||||||
|
|
@ -251,14 +253,14 @@ proc readStr*(s: Stream, length: int): TaintedString =
|
||||||
## reads a string of length `length` from the stream `s`. Raises `EIO` if
|
## reads a string of length `length` from the stream `s`. Raises `EIO` if
|
||||||
## an error occurred.
|
## an error occurred.
|
||||||
result = newString(length).TaintedString
|
result = newString(length).TaintedString
|
||||||
var L = readData(s, addr(string(result)[0]), length)
|
var L = readData(s, cstring(result), length)
|
||||||
if L != length: setLen(result.string, L)
|
if L != length: setLen(result.string, L)
|
||||||
|
|
||||||
proc peekStr*(s: Stream, length: int): TaintedString =
|
proc peekStr*(s: Stream, length: int): TaintedString =
|
||||||
## peeks a string of length `length` from the stream `s`. Raises `EIO` if
|
## peeks a string of length `length` from the stream `s`. Raises `EIO` if
|
||||||
## an error occurred.
|
## an error occurred.
|
||||||
result = newString(length).TaintedString
|
result = newString(length).TaintedString
|
||||||
var L = peekData(s, addr(string(result)[0]), length)
|
var L = peekData(s, cstring(result), length)
|
||||||
if L != length: setLen(result.string, L)
|
if L != length: setLen(result.string, L)
|
||||||
|
|
||||||
proc readLine*(s: Stream, line: var TaintedString): bool =
|
proc readLine*(s: Stream, line: var TaintedString): bool =
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
## A simple XML tree. More efficient and simpler than the DOM.
|
## A simple XML tree. More efficient and simpler than the DOM.
|
||||||
|
|
||||||
import macros, strtabs
|
import macros, strtabs, strutils
|
||||||
|
|
||||||
type
|
type
|
||||||
XmlNode* = ref XmlNodeObj ## an XML tree consists of ``XmlNode``'s.
|
XmlNode* = ref XmlNodeObj ## an XML tree consists of ``XmlNode``'s.
|
||||||
|
|
@ -217,7 +217,8 @@ proc escape*(s: string): string =
|
||||||
result = newStringOfCap(s.len)
|
result = newStringOfCap(s.len)
|
||||||
addEscaped(result, s)
|
addEscaped(result, s)
|
||||||
|
|
||||||
proc addIndent(result: var string, indent: int) =
|
proc addIndent(result: var string, indent: int, addNewLines: bool) =
|
||||||
|
if addNewLines:
|
||||||
result.add("\n")
|
result.add("\n")
|
||||||
for i in 1..indent: result.add(' ')
|
for i in 1..indent: result.add(' ')
|
||||||
|
|
||||||
|
|
@ -227,7 +228,8 @@ proc noWhitespace(n: XmlNode): bool =
|
||||||
for i in 0..n.len-1:
|
for i in 0..n.len-1:
|
||||||
if n[i].kind in {xnText, xnEntity}: return true
|
if n[i].kind in {xnText, xnEntity}: return true
|
||||||
|
|
||||||
proc add*(result: var string, n: XmlNode, indent = 0, indWidth = 2) =
|
proc add*(result: var string, n: XmlNode, indent = 0, indWidth = 2,
|
||||||
|
addNewLines=true) =
|
||||||
## adds the textual representation of `n` to `result`.
|
## adds the textual representation of `n` to `result`.
|
||||||
|
|
||||||
proc addEscapedAttr(result: var string, s: string) =
|
proc addEscapedAttr(result: var string, s: string) =
|
||||||
|
|
@ -260,14 +262,15 @@ proc add*(result: var string, n: XmlNode, indent = 0, indWidth = 2) =
|
||||||
# for mixed leaves, we cannot output whitespace for readability,
|
# for mixed leaves, we cannot output whitespace for readability,
|
||||||
# because this would be wrong. For example: ``a<b>b</b>`` is
|
# because this would be wrong. For example: ``a<b>b</b>`` is
|
||||||
# different from ``a <b>b</b>``.
|
# different from ``a <b>b</b>``.
|
||||||
for i in 0..n.len-1: result.add(n[i], indent+indWidth, indWidth)
|
for i in 0..n.len-1:
|
||||||
|
result.add(n[i], indent+indWidth, indWidth, addNewLines)
|
||||||
else:
|
else:
|
||||||
for i in 0..n.len-1:
|
for i in 0..n.len-1:
|
||||||
result.addIndent(indent+indWidth)
|
result.addIndent(indent+indWidth, addNewLines)
|
||||||
result.add(n[i], indent+indWidth, indWidth)
|
result.add(n[i], indent+indWidth, indWidth, addNewLines)
|
||||||
result.addIndent(indent)
|
result.addIndent(indent, addNewLines)
|
||||||
else:
|
else:
|
||||||
result.add(n[0], indent+indWidth, indWidth)
|
result.add(n[0], indent+indWidth, indWidth, addNewLines)
|
||||||
result.add("</")
|
result.add("</")
|
||||||
result.add(n.fTag)
|
result.add(n.fTag)
|
||||||
result.add(">")
|
result.add(">")
|
||||||
|
|
@ -316,7 +319,10 @@ proc xmlConstructor(a: NimNode): NimNode {.compileTime.} =
|
||||||
var elements = newNimNode(nnkBracket, a)
|
var elements = newNimNode(nnkBracket, a)
|
||||||
for i in 1..a.len-1:
|
for i in 1..a.len-1:
|
||||||
if a[i].kind == nnkExprEqExpr:
|
if a[i].kind == nnkExprEqExpr:
|
||||||
attrs.add(toStrLit(a[i][0]))
|
# In order to support attributes like `data-lang` we have to
|
||||||
|
# replace whitespace because `toStrLit` gives `data - lang`.
|
||||||
|
let attrName = toStrLit(a[i][0]).strVal.replace(" ", "")
|
||||||
|
attrs.add(newStrLitNode(attrName))
|
||||||
attrs.add(a[i][1])
|
attrs.add(a[i][1])
|
||||||
#echo repr(attrs)
|
#echo repr(attrs)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,6 @@ type
|
||||||
PRawChannel = ptr RawChannel
|
PRawChannel = ptr RawChannel
|
||||||
LoadStoreMode = enum mStore, mLoad
|
LoadStoreMode = enum mStore, mLoad
|
||||||
Channel* {.gcsafe.}[TMsg] = RawChannel ## a channel for thread communication
|
Channel* {.gcsafe.}[TMsg] = RawChannel ## a channel for thread communication
|
||||||
{.deprecated: [TRawChannel: RawChannel, TLoadStoreMode: LoadStoreMode,
|
|
||||||
TChannel: Channel].}
|
|
||||||
|
|
||||||
const ChannelDeadMask = -2
|
const ChannelDeadMask = -2
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ proc allocSlowPath(r: var MemRegion; size: int) =
|
||||||
r.tail = fresh
|
r.tail = fresh
|
||||||
r.remaining = s - sizeof(BaseChunk)
|
r.remaining = s - sizeof(BaseChunk)
|
||||||
|
|
||||||
proc alloc(r: var MemRegion; size: int): pointer =
|
proc allocFast(r: var MemRegion; size: int): pointer =
|
||||||
if size <= MaxSmallObject:
|
if size <= MaxSmallObject:
|
||||||
var it = r.freeLists[size div MemAlign]
|
var it = r.freeLists[size div MemAlign]
|
||||||
if it != nil:
|
if it != nil:
|
||||||
|
|
@ -270,7 +270,7 @@ proc isOnHeap*(r: MemRegion; p: pointer): bool =
|
||||||
it = it.next
|
it = it.next
|
||||||
|
|
||||||
proc rawNewObj(r: var MemRegion, typ: PNimType, size: int): pointer =
|
proc rawNewObj(r: var MemRegion, typ: PNimType, size: int): pointer =
|
||||||
var res = cast[ptr ObjHeader](alloc(r, size + sizeof(ObjHeader)))
|
var res = cast[ptr ObjHeader](allocFast(r, size + sizeof(ObjHeader)))
|
||||||
res.typ = typ
|
res.typ = typ
|
||||||
if typ.finalizer != nil:
|
if typ.finalizer != nil:
|
||||||
res.nextFinal = r.head.head
|
res.nextFinal = r.head.head
|
||||||
|
|
@ -278,7 +278,7 @@ proc rawNewObj(r: var MemRegion, typ: PNimType, size: int): pointer =
|
||||||
result = res +! sizeof(ObjHeader)
|
result = res +! sizeof(ObjHeader)
|
||||||
|
|
||||||
proc rawNewSeq(r: var MemRegion, typ: PNimType, size: int): pointer =
|
proc rawNewSeq(r: var MemRegion, typ: PNimType, size: int): pointer =
|
||||||
var res = cast[ptr SeqHeader](alloc(r, size + sizeof(SeqHeader)))
|
var res = cast[ptr SeqHeader](allocFast(r, size + sizeof(SeqHeader)))
|
||||||
res.typ = typ
|
res.typ = typ
|
||||||
res.region = addr(r)
|
res.region = addr(r)
|
||||||
result = res +! sizeof(SeqHeader)
|
result = res +! sizeof(SeqHeader)
|
||||||
|
|
@ -351,6 +351,11 @@ proc alloc0(r: var MemRegion; size: Natural): pointer =
|
||||||
# but incorrect in general. XXX
|
# but incorrect in general. XXX
|
||||||
result = alloc0(size)
|
result = alloc0(size)
|
||||||
|
|
||||||
|
proc alloc(r: var MemRegion; size: Natural): pointer =
|
||||||
|
# ignore the region. That is correct for the channels module
|
||||||
|
# but incorrect in general. XXX
|
||||||
|
result = alloc(size)
|
||||||
|
|
||||||
proc dealloc(r: var MemRegion; p: pointer) = dealloc(p)
|
proc dealloc(r: var MemRegion; p: pointer) = dealloc(p)
|
||||||
|
|
||||||
proc allocShared(size: Natural): pointer =
|
proc allocShared(size: Natural): pointer =
|
||||||
|
|
@ -390,3 +395,6 @@ proc getTotalMem*(r: MemRegion): int =
|
||||||
result = r.totalSize
|
result = r.totalSize
|
||||||
|
|
||||||
proc setStackBottom(theStackBottom: pointer) = discard
|
proc setStackBottom(theStackBottom: pointer) = discard
|
||||||
|
|
||||||
|
proc nimGCref(x: pointer) {.compilerProc.} = discard
|
||||||
|
proc nimGCunref(x: pointer) {.compilerProc.} = discard
|
||||||
|
|
|
||||||
|
|
@ -576,18 +576,3 @@ proc nimBoolToStr(x: bool): string {.compilerRtl.} =
|
||||||
proc nimCharToStr(x: char): string {.compilerRtl.} =
|
proc nimCharToStr(x: char): string {.compilerRtl.} =
|
||||||
result = newString(1)
|
result = newString(1)
|
||||||
result[0] = x
|
result[0] = x
|
||||||
|
|
||||||
proc binaryStrSearch(x: openArray[string], y: string): int {.compilerproc.} =
|
|
||||||
var
|
|
||||||
a = 0
|
|
||||||
b = len(x)
|
|
||||||
while a < b:
|
|
||||||
var mid = (a + b) div 2
|
|
||||||
if x[mid] < y:
|
|
||||||
a = mid + 1
|
|
||||||
else:
|
|
||||||
b = mid
|
|
||||||
if a < len(x) and x[a] == y:
|
|
||||||
result = a
|
|
||||||
else:
|
|
||||||
result = -1
|
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,9 @@ discard """
|
||||||
type
|
type
|
||||||
TMsgKind = enum
|
TMsgKind = enum
|
||||||
mLine, mEof
|
mLine, mEof
|
||||||
TMsg = object {.pure, final.}
|
TMsg = object
|
||||||
case k: TMsgKind
|
case k: TMsgKind
|
||||||
of mEof: nil
|
of mEof: discard
|
||||||
of mLine: data: string
|
of mLine: data: string
|
||||||
|
|
||||||
var
|
var
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#? stdtmpl(subsChar='?') | standard
|
#? stdtmpl(subsChar='?') | standard
|
||||||
#proc generateBuildBatchScript(c: ConfigData, winIndex, cpuIndex: int): string =
|
#proc generateBuildBatchScript(c: ConfigData, winIndex, cpuIndex32, cpuIndex64: int): string =
|
||||||
# result = "@echo off\nREM Generated by niminst\n"
|
# result = "@echo off\nREM Generated by niminst\n"
|
||||||
SET CC=gcc
|
SET CC=gcc
|
||||||
SET LINKER=gcc
|
SET LINKER=gcc
|
||||||
|
|
@ -7,27 +7,63 @@ SET COMP_FLAGS=?{c.ccompiler.flags}
|
||||||
SET LINK_FLAGS=?{c.linker.flags}
|
SET LINK_FLAGS=?{c.linker.flags}
|
||||||
SET BIN_DIR=?{firstBinPath(c).toWin}
|
SET BIN_DIR=?{firstBinPath(c).toWin}
|
||||||
|
|
||||||
|
REM Detect gcc arch
|
||||||
|
IF DEFINED ARCH (
|
||||||
|
ECHO Forcing %CC% arch
|
||||||
|
) ELSE (
|
||||||
|
ECHO Detecting %CC% arch
|
||||||
|
ECHO int main^(^) { return sizeof^(void *^); } | gcc -xc - -o archtest && archtest
|
||||||
|
IF ERRORLEVEL 4 SET ARCH=32
|
||||||
|
IF ERRORLEVEL 8 SET ARCH=64
|
||||||
|
del archtest.*
|
||||||
|
)
|
||||||
|
ECHO Building with %ARCH% bit %CC%
|
||||||
|
|
||||||
if EXIST ..\koch.nim SET BIN_DIR=..\bin
|
if EXIST ..\koch.nim SET BIN_DIR=..\bin
|
||||||
|
|
||||||
if NOT EXIST %BIN_DIR%\nul mkdir %BIN_DIR%
|
if NOT EXIST %BIN_DIR%\nul mkdir %BIN_DIR%
|
||||||
|
|
||||||
REM call the compiler:
|
REM call the compiler:
|
||||||
|
|
||||||
|
IF %ARCH% EQU 32 (
|
||||||
|
|
||||||
# block win32:
|
# block win32:
|
||||||
# var linkCmd = ""
|
# var linkCmd = ""
|
||||||
# for ff in items(c.cfiles[winIndex][cpuIndex]):
|
# if cpuIndex32 != -1:
|
||||||
|
# for ff in items(c.cfiles[winIndex][cpuIndex32]):
|
||||||
# let f = ff.toWin
|
# let f = ff.toWin
|
||||||
ECHO %CC% %COMP_FLAGS% -Ic_code -c ?{f} -o ?{changeFileExt(f, "o")}
|
ECHO %CC% %COMP_FLAGS% -Ic_code -c ?{f} -o ?{changeFileExt(f, "o")}
|
||||||
CALL %CC% %COMP_FLAGS% -Ic_code -c ?{f} -o ?{changeFileExt(f, "o")}
|
CALL %CC% %COMP_FLAGS% -Ic_code -c ?{f} -o ?{changeFileExt(f, "o")}
|
||||||
# linkCmd.add(" " & changeFileExt(f, "o"))
|
# linkCmd.add(" " & changeFileExt(f, "o"))
|
||||||
IF ERRORLEVEL 1 (GOTO:END)
|
IF ERRORLEVEL 1 (GOTO:END)
|
||||||
# end for
|
# end for
|
||||||
|
# end if
|
||||||
|
|
||||||
ECHO %LINKER% -o ?{"%BIN_DIR%"\toLowerAscii(c.name)}.exe ?linkCmd %LINK_FLAGS%
|
ECHO %LINKER% -o ?{"%BIN_DIR%"\toLowerAscii(c.name)}.exe ?linkCmd %LINK_FLAGS%
|
||||||
CALL %LINKER% -o ?{"%BIN_DIR%"\toLowerAscii(c.name)}.exe ?linkCmd %LINK_FLAGS%
|
CALL %LINKER% -o ?{"%BIN_DIR%"\toLowerAscii(c.name)}.exe ?linkCmd %LINK_FLAGS%
|
||||||
|
|
||||||
# end block
|
# end block
|
||||||
|
|
||||||
|
) ELSE IF %ARCH% EQU 64 (
|
||||||
|
|
||||||
|
# block win64:
|
||||||
|
# var linkCmd = ""
|
||||||
|
# if cpuIndex64 != -1:
|
||||||
|
# for ff in items(c.cfiles[winIndex][cpuIndex64]):
|
||||||
|
# let f = ff.toWin
|
||||||
|
ECHO %CC% %COMP_FLAGS% -Ic_code -c ?{f} -o ?{changeFileExt(f, "o")}
|
||||||
|
CALL %CC% %COMP_FLAGS% -Ic_code -c ?{f} -o ?{changeFileExt(f, "o")}
|
||||||
|
# linkCmd.add(" " & changeFileExt(f, "o"))
|
||||||
|
IF ERRORLEVEL 1 (GOTO:END)
|
||||||
|
# end for
|
||||||
|
# end if
|
||||||
|
|
||||||
|
ECHO %LINKER% -o ?{"%BIN_DIR%"\toLowerAscii(c.name)}.exe ?linkCmd %LINK_FLAGS%
|
||||||
|
CALL %LINKER% -o ?{"%BIN_DIR%"\toLowerAscii(c.name)}.exe ?linkCmd %LINK_FLAGS%
|
||||||
|
|
||||||
|
# end block
|
||||||
|
)
|
||||||
|
|
||||||
:END
|
:END
|
||||||
IF ERRORLEVEL 1 (
|
IF ERRORLEVEL 1 (
|
||||||
ECHO FAILURE
|
ECHO FAILURE
|
||||||
|
|
@ -35,6 +71,8 @@ IF ERRORLEVEL 1 (
|
||||||
ECHO CSource compilation failed. Please check that the gcc compiler is in
|
ECHO CSource compilation failed. Please check that the gcc compiler is in
|
||||||
ECHO the PATH environment variable, and that you are calling the batch script
|
ECHO the PATH environment variable, and that you are calling the batch script
|
||||||
ECHO that matches the target architecture of the compiler.
|
ECHO that matches the target architecture of the compiler.
|
||||||
|
ECHO.
|
||||||
|
ECHO Use build.bat to autodetect the compiler architecture.
|
||||||
) ELSE (
|
) ELSE (
|
||||||
ECHO SUCCESS
|
ECHO SUCCESS
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,8 @@ const
|
||||||
maxOS = 20 # max number of OSes
|
maxOS = 20 # max number of OSes
|
||||||
maxCPU = 20 # max number of CPUs
|
maxCPU = 20 # max number of CPUs
|
||||||
buildShFile = "build.sh"
|
buildShFile = "build.sh"
|
||||||
buildBatFile32 = "build.bat"
|
buildBatFile = "build.bat"
|
||||||
|
buildBatFile32 = "build32.bat"
|
||||||
buildBatFile64 = "build64.bat"
|
buildBatFile64 = "build64.bat"
|
||||||
makeFile = "makefile"
|
makeFile = "makefile"
|
||||||
installShFile = "install.sh"
|
installShFile = "install.sh"
|
||||||
|
|
@ -542,12 +543,13 @@ proc srcdist(c: var ConfigData) =
|
||||||
inclFilePermissions(getOutputDir(c) / buildShFile, {fpUserExec, fpGroupExec, fpOthersExec})
|
inclFilePermissions(getOutputDir(c) / buildShFile, {fpUserExec, fpGroupExec, fpOthersExec})
|
||||||
writeFile(getOutputDir(c) / makeFile, generateMakefile(c), "\10")
|
writeFile(getOutputDir(c) / makeFile, generateMakefile(c), "\10")
|
||||||
if winIndex >= 0:
|
if winIndex >= 0:
|
||||||
|
if intel32Index >= 0 or intel64Index >= 0:
|
||||||
|
writeFile(getOutputDir(c) / buildBatFile,
|
||||||
|
generateBuildBatchScript(c, winIndex, intel32Index, intel64Index), "\13\10")
|
||||||
if intel32Index >= 0:
|
if intel32Index >= 0:
|
||||||
writeFile(getOutputDir(c) / buildBatFile32,
|
writeFile(getOutputDir(c) / buildBatFile32, "SET ARCH=32\nCALL build.bat\n")
|
||||||
generateBuildBatchScript(c, winIndex, intel32Index), "\13\10")
|
|
||||||
if intel64Index >= 0:
|
if intel64Index >= 0:
|
||||||
writeFile(getOutputDir(c) / buildBatFile64,
|
writeFile(getOutputDir(c) / buildBatFile64, "SET ARCH=64\nCALL build.bat\n")
|
||||||
generateBuildBatchScript(c, winIndex, intel64Index), "\13\10")
|
|
||||||
writeInstallScripts(c)
|
writeInstallScripts(c)
|
||||||
|
|
||||||
# --------------------- generate inno setup -----------------------------------
|
# --------------------- generate inno setup -----------------------------------
|
||||||
|
|
@ -593,6 +595,7 @@ when haveZipLib:
|
||||||
else: n = c.outdir / n
|
else: n = c.outdir / n
|
||||||
var z: ZipArchive
|
var z: ZipArchive
|
||||||
if open(z, n, fmWrite):
|
if open(z, n, fmWrite):
|
||||||
|
addFile(z, proj / buildBatFile, "build" / buildBatFile)
|
||||||
addFile(z, proj / buildBatFile32, "build" / buildBatFile32)
|
addFile(z, proj / buildBatFile32, "build" / buildBatFile32)
|
||||||
addFile(z, proj / buildBatFile64, "build" / buildBatFile64)
|
addFile(z, proj / buildBatFile64, "build" / buildBatFile64)
|
||||||
addFile(z, proj / buildShFile, "build" / buildShFile)
|
addFile(z, proj / buildShFile, "build" / buildShFile)
|
||||||
|
|
@ -631,11 +634,12 @@ proc xzDist(c: var ConfigData; windowsZip=false) =
|
||||||
if not dirExists(destDir): createDir(destDir)
|
if not dirExists(destDir): createDir(destDir)
|
||||||
copyFileWithPermissions(src, dest)
|
copyFileWithPermissions(src, dest)
|
||||||
|
|
||||||
if not windowsZip and not existsFile("build" / buildBatFile32):
|
if not windowsZip and not existsFile("build" / buildBatFile):
|
||||||
quit("No C sources found in ./build/, please build by running " &
|
quit("No C sources found in ./build/, please build by running " &
|
||||||
"./koch csource -d:release.")
|
"./koch csource -d:release.")
|
||||||
|
|
||||||
if not windowsZip:
|
if not windowsZip:
|
||||||
|
processFile(proj / buildBatFile, "build" / buildBatFile)
|
||||||
processFile(proj / buildBatFile32, "build" / buildBatFile32)
|
processFile(proj / buildBatFile32, "build" / buildBatFile32)
|
||||||
processFile(proj / buildBatFile64, "build" / buildBatFile64)
|
processFile(proj / buildBatFile64, "build" / buildBatFile64)
|
||||||
processFile(proj / buildShFile, "build" / buildShFile)
|
processFile(proj / buildShFile, "build" / buildShFile)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue