Merge remote-tracking branch 'upstream/master' into standalone

This commit is contained in:
Simon Hafner 2013-06-29 20:29:37 -05:00
commit 7dd9dbe4dd
119 changed files with 4593 additions and 1580 deletions

View file

@ -1,24 +0,0 @@
===============================================================================
Nimrod -- a Compiler for Nimrod. http://nimrod-code.org/
Copyright (C) 2004-2013 Andreas Rumpf. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
[ MIT license: http://www.opensource.org/licenses/mit-license.php ]

View file

@ -390,7 +390,7 @@ proc lispRepr*(n: PNimrodNode): string {.compileTime.} =
add(result, ")")
macro dumpTree*(s: stmt): stmt = echo s.treeRepr
macro dumpTree*(s: stmt): stmt {.immediate.} = echo s.treeRepr
## Accepts a block of nimrod code and prints the parsed abstract syntax
## tree using the `toTree` function. Printing is done *at compile time*.
##
@ -398,16 +398,16 @@ macro dumpTree*(s: stmt): stmt = echo s.treeRepr
## tree and to discover what kind of nodes must be created to represent
## a certain expression/statement.
macro dumpLisp*(s: stmt): stmt = echo s.lispRepr
macro dumpLisp*(s: stmt): stmt {.immediate.} = echo s.lispRepr
## Accepts a block of nimrod code and prints the parsed abstract syntax
## tree using the `toLisp` function. Printing is done *at compile time*.
##
## See `dumpTree`.
macro dumpTreeImm*(s: stmt): stmt {.immediate.} = echo s.treeRepr
macro dumpTreeImm*(s: stmt): stmt {.immediate, deprecated.} = echo s.treeRepr
## The ``immediate`` version of `dumpTree`.
macro dumpLispImm*(s: stmt): stmt {.immediate.} = echo s.lispRepr
macro dumpLispImm*(s: stmt): stmt {.immediate, deprecated.} = echo s.lispRepr
## The ``immediate`` version of `dumpLisp`.

View file

@ -379,7 +379,7 @@ proc getBiggestInt*(x: TAny): biggestInt =
of tyInt8: result = biggestInt(cast[ptr int8](x.value)[])
of tyInt16: result = biggestInt(cast[ptr int16](x.value)[])
of tyInt32: result = biggestInt(cast[ptr int32](x.value)[])
of tyInt64: result = biggestInt(cast[ptr int64](x.value)[])
of tyInt64, tyUInt64: result = biggestInt(cast[ptr int64](x.value)[])
of tyBool: result = biggestInt(cast[ptr bool](x.value)[])
of tyChar: result = biggestInt(cast[ptr char](x.value)[])
of tyEnum, tySet:
@ -389,6 +389,10 @@ proc getBiggestInt*(x: TAny): biggestInt =
of 4: result = biggestInt(cast[ptr int32](x.value)[])
of 8: result = biggestInt(cast[ptr int64](x.value)[])
else: assert false
of tyUInt: result = biggestInt(cast[ptr uint](x.value)[])
of tyUInt8: result = biggestInt(cast[ptr uint8](x.value)[])
of tyUInt16: result = biggestInt(cast[ptr uint16](x.value)[])
of tyUInt32: result = biggestInt(cast[ptr uint32](x.value)[])
else: assert false
proc setBiggestInt*(x: TAny, y: biggestInt) =
@ -400,7 +404,7 @@ proc setBiggestInt*(x: TAny, y: biggestInt) =
of tyInt8: cast[ptr int8](x.value)[] = int8(y)
of tyInt16: cast[ptr int16](x.value)[] = int16(y)
of tyInt32: cast[ptr int32](x.value)[] = int32(y)
of tyInt64: cast[ptr int64](x.value)[] = int64(y)
of tyInt64, tyUInt64: cast[ptr int64](x.value)[] = int64(y)
of tyBool: cast[ptr bool](x.value)[] = y != 0
of tyChar: cast[ptr char](x.value)[] = chr(y.int)
of tyEnum, tySet:
@ -410,6 +414,10 @@ proc setBiggestInt*(x: TAny, y: biggestInt) =
of 4: cast[ptr int32](x.value)[] = int32(y)
of 8: cast[ptr int64](x.value)[] = y
else: assert false
of tyUInt: cast[ptr uint](x.value)[] = uint(y)
of tyUInt8: cast[ptr uint8](x.value)[] = uint8(y)
of tyUInt16: cast[ptr uint16](x.value)[] = uint16(y)
of tyUInt32: cast[ptr uint32](x.value)[] = uint32(y)
else: assert false
proc getChar*(x: TAny): char =

View file

@ -242,7 +242,6 @@ template `=~` *(s: string, pattern: TRegEx): expr =
bind maxSubPatterns
when not definedInScope(matches):
var matches {.inject.}: array[0..maxSubPatterns-1, string]
{.warning: "injected 'matches' might be affected by new scoping rules in 0.9.4".}
match(s, pattern, matches)
# ------------------------- more string handling ------------------------------

View file

@ -443,11 +443,11 @@ struct TFrame {
};
#define nimfr(proc, file) \
volatile TFrame F; \
TFrame F; \
F.procname = proc; F.filename = file; F.line = 0; F.len = 0; nimFrame(&F);
#define nimfrs(proc, file, slots, length) \
volatile struct {TFrame* prev;NCSTRING procname;NI line;NCSTRING filename; NI len; TVarSlot s[slots];} F; \
struct {TFrame* prev;NCSTRING procname;NI line;NCSTRING filename; NI len; TVarSlot s[slots];} F; \
F.procname = proc; F.filename = file; F.line = 0; F.len = length; nimFrame((TFrame*)&F);
#define nimln(n, file) \

View file

@ -44,7 +44,17 @@ const
"Assembler", "Preprocessor", "Directive", "Command", "Rule", "Hyperlink",
"Label", "Reference", "Other"]
nimrodKeywords = slurp("doc/keywords.txt").split
# The following list comes from doc/keywords.txt, make sure it is
# synchronized with this array by running the module itself as a test case.
nimrodKeywords = ["addr", "and", "as", "asm", "atomic", "bind", "block",
"break", "case", "cast", "const", "continue", "converter", "discard",
"distinct", "div", "do", "elif", "else", "end", "enum", "except", "export",
"finally", "for", "from", "generic", "if", "import", "in", "include",
"interface", "is", "isnot", "iterator", "lambda", "let", "macro", "method",
"mixin", "mod", "nil", "not", "notin", "object", "of", "or", "out", "proc",
"ptr", "raise", "ref", "return", "shared", "shl", "shr", "static",
"template", "try", "tuple", "type", "var", "when", "while", "with",
"without", "xor", "yield"]
proc getSourceLanguage*(name: string): TSourceLanguage =
for i in countup(succ(low(TSourceLanguage)), high(TSourceLanguage)):
@ -535,3 +545,16 @@ proc getNextToken*(g: var TGeneralTokenizer, lang: TSourceLanguage) =
of langC: cNextToken(g)
of langJava: javaNextToken(g)
when isMainModule:
var keywords: seq[string]
# Try to work running in both the subdir or at the root.
for filename in ["doc/keywords.txt", "../../../doc/keywords.txt"]:
except: echo filename, " not found"
let input = string(readFile(filename))
keywords = input.split()
break
doAssert (not keywords.isNil, "Couldn't read any keywords.txt file!")
doAssert keywords.len == nimrodKeywords.len, "No matching lengths"
for i in 0..keywords.len-1:
#echo keywords[i], " == ", nimrodKeywords[i]
doAssert keywords[i] == nimrodKeywords[i], "Unexpected keyword"

View file

@ -7,7 +7,7 @@
# distribution, for details about the copyright.
#
## This module implements a `reStructuredText`:idx parser. A large
## This module implements a `reStructuredText`:idx: parser. A large
## subset is implemented. Some features of the `markdown`:idx: wiki syntax are
## also supported.

View file

@ -7,7 +7,7 @@
# distribution, for details about the copyright.
#
## This module implements an AST for the `reStructuredText`:idx parser.
## This module implements an AST for the `reStructuredText`:idx: parser.
import strutils

View file

@ -7,7 +7,7 @@
# distribution, for details about the copyright.
#
## This module implements a generator of HTML/Latex from `reStructuredText`:idx.
## This module implements a generator of HTML/Latex from `reStructuredText`:idx:.
import strutils, os, hashes, strtabs, rstast, rst, highlite
@ -692,4 +692,4 @@ proc rstToHtml*(s: string, options: TRstParseOptions,
var rst = rstParse(s, filen, 0, 1, dummyHasToc, options)
result = ""
renderRstToOut(d, rst, result)

View file

@ -167,7 +167,7 @@ proc AsyncSocket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM,
result = newAsyncSocket()
result.socket = socket(domain, typ, protocol, buffered)
result.proto = protocol
if result.socket == InvalidSocket: OSError()
if result.socket == InvalidSocket: OSError(OSLastError())
result.socket.setBlocking(false)
proc toAsyncSocket*(sock: TSocket, state: TInfo = SockConnected): PAsyncSocket =
@ -349,7 +349,7 @@ proc acceptAddr*(server: PAsyncSocket, client: var PAsyncSocket,
client.sslNeedAccept = false
client.info = SockConnected
if c == InvalidSocket: OSError()
if c == InvalidSocket: SocketError(server.socket)
c.setBlocking(false) # TODO: Needs to be tested.
# deleg.open is set in ``toDelegate``.
@ -423,6 +423,10 @@ proc isConnecting*(s: PAsyncSocket): bool =
proc isClosed*(s: PAsyncSocket): bool =
## Determines whether ``s`` has been closed.
return s.info == SockClosed
proc isSendDataBuffered*(s: PAsyncSocket): bool =
## Determines whether ``s`` has data waiting to be sent, i.e. whether this
## socket's sendBuffer contains data.
return s.sendBuffer.len != 0
proc setHandleWrite*(s: PAsyncSocket,
handleWrite: proc (s: PAsyncSocket) {.closure.}) =
@ -638,8 +642,7 @@ when isMainModule:
proc testRead(s: PAsyncSocket, no: int) =
echo("Reading! " & $no)
var data = ""
if not s.readLine(data):
OSError()
if not s.readLine(data): return
if data == "":
echo("Closing connection. " & $no)
s.close()

View file

@ -1,7 +1,7 @@
#
#
# Nimrod's Runtime Library
# (c) Copyright 2010 Andreas Rumpf
# (c) Copyright 2013 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
@ -35,8 +35,12 @@ type
tagAddress, ## the HTML ``address`` element
tagApplet, ## the deprecated HTML ``applet`` element
tagArea, ## the HTML ``area`` element
tagArticle, ## the HTML ``article`` element
tagAside, ## the HTML ``aside`` element
tagAudio, ## the HTML ``audio`` element
tagB, ## the HTML ``b`` element
tagBase, ## the HTML ``base`` element
tagBdi, ## the HTML ``bdi`` element
tagBdo, ## the deprecated HTML ``dbo`` element
tagBasefont, ## the deprecated HTML ``basefont`` element
tagBig, ## the HTML ``big`` element
@ -44,22 +48,31 @@ type
tagBody, ## the HTML ``body`` element
tagBr, ## the HTML ``br`` element
tagButton, ## the HTML ``button`` element
tagCanvas, ## the HTML ``canvas`` element
tagCaption, ## the HTML ``caption`` element
tagCenter, ## the deprecated HTML ``center`` element
tagCite, ## the HTML ``cite`` element
tagCode, ## the HTML ``code`` element
tagCol, ## the HTML ``col`` element
tagColgroup, ## the HTML ``colgroup`` element
tagCommand, ## the HTML ``command`` element
tagDatalist, ## the HTML ``datalist`` element
tagDd, ## the HTML ``dd`` element
tagDel, ## the HTML ``del`` element
tagDetails, ## the HTML ``details`` element
tagDfn, ## the HTML ``dfn`` element
tagDialog, ## the HTML ``dialog`` element
tagDiv, ## the HTML ``div`` element
tagDir, ## the deprecated HTLM ``dir`` element
tagDl, ## the HTML ``dl`` element
tagDt, ## the HTML ``dt`` element
tagEm, ## the HTML ``em`` element
tagEmbed, ## the HTML ``embed`` element
tagFieldset, ## the HTML ``fieldset`` element
tagFigcaption, ## the HTML ``figcaption`` element
tagFigure, ## the HTML ``figure`` element
tagFont, ## the deprecated HTML ``font`` element
tagFooter, ## the HTML ``footer`` element
tagForm, ## the HTML ``form`` element
tagFrame, ## the HTML ``frame`` element
tagFrameset, ## the deprecated HTML ``frameset`` element
@ -70,6 +83,8 @@ type
tagH5, ## the HTML ``h5`` element
tagH6, ## the HTML ``h6`` element
tagHead, ## the HTML ``head`` element
tagHeader, ## the HTML ``header`` element
tagHgroup, ## the HTML ``hgroup`` element
tagHtml, ## the HTML ``html`` element
tagHr, ## the HTML ``hr`` element
tagI, ## the HTML ``i`` element
@ -79,13 +94,17 @@ type
tagIns, ## the HTML ``ins`` element
tagIsindex, ## the deprecated HTML ``isindex`` element
tagKbd, ## the HTML ``kbd`` element
tagKeygen, ## the HTML ``keygen`` element
tagLabel, ## the HTML ``label`` element
tagLegend, ## the HTML ``legend`` element
tagLi, ## the HTML ``li`` element
tagLink, ## the HTML ``link`` element
tagMap, ## the HTML ``map`` element
tagMark, ## the HTML ``mark`` element
tagMenu, ## the deprecated HTML ``menu`` element
tagMeta, ## the HTML ``meta`` element
tagMeter, ## the HTML ``meter`` element
tagNav, ## the HTML ``nav`` element
tagNobr, ## the deprecated HTML ``nobr`` element
tagNoframes, ## the deprecated HTML ``noframes`` element
tagNoscript, ## the HTML ``noscript`` element
@ -93,20 +112,28 @@ type
tagOl, ## the HTML ``ol`` element
tagOptgroup, ## the HTML ``optgroup`` element
tagOption, ## the HTML ``option`` element
tagOutput, ## the HTML ``output`` element
tagP, ## the HTML ``p`` element
tagParam, ## the HTML ``param`` element
tagPre, ## the HTML ``pre`` element
tagProgress, ## the HTML ``progress`` element
tagQ, ## the HTML ``q`` element
tagRp, ## the HTML ``rp`` element
tagRt, ## the HTML ``rt`` element
tagRuby, ## the HTML ``ruby`` element
tagS, ## the deprecated HTML ``s`` element
tagSamp, ## the HTML ``samp`` element
tagScript, ## the HTML ``script`` element
tagSection, ## the HTML ``section`` element
tagSelect, ## the HTML ``select`` element
tagSmall, ## the HTML ``small`` element
tagSource, ## the HTML ``source`` element
tagSpan, ## the HTML ``span`` element
tagStrike, ## the deprecated HTML ``strike`` element
tagStrong, ## the HTML ``strong`` element
tagStyle, ## the HTML ``style`` element
tagSub, ## the HTML ``sub`` element
tagSummary, ## the HTML ``summary`` element
tagSup, ## the HTML ``sup`` element
tagTable, ## the HTML ``table`` element
tagTbody, ## the HTML ``tbody`` element
@ -115,37 +142,46 @@ type
tagTfoot, ## the HTML ``tfoot`` element
tagTh, ## the HTML ``th`` element
tagThead, ## the HTML ``thead`` element
tagTime, ## the HTML ``time`` element
tagTitle, ## the HTML ``title`` element
tagTr, ## the HTML ``tr`` element
tagTrack, ## the HTML ``track`` element
tagTt, ## the HTML ``tt`` element
tagU, ## the deprecated HTML ``u`` element
tagUl, ## the HTML ``ul`` element
tagVar ## the HTML ``var`` element
tagVar, ## the HTML ``var`` element
tagVideo, ## the HTML ``video`` element
tagWbr ## the HTML ``wbr`` element
const
tagToStr* = [
"a", "abbr", "acronym", "address", "applet", "area",
"b", "base", "basefont", "bdo", "big", "blockquote", "body",
"br", "button", "caption", "center", "cite", "code",
"col", "colgroup", "dd", "del", "dfn", "div",
"dir", "dl", "dt", "em", "fieldset", "font",
"a", "abbr", "acronym", "address", "applet", "area", "article",
"aside", "audio",
"b", "base", "basefont", "bdi", "bdo", "big", "blockquote", "body",
"br", "button", "canvas", "caption", "center", "cite", "code",
"col", "colgroup", "command",
"datalist", "dd", "del", "details", "dfn", "dialog", "div",
"dir", "dl", "dt", "em", "embed", "fieldset",
"figcaption", "figure", "font", "footer",
"form", "frame", "frameset", "h1", "h2", "h3",
"h4", "h5", "h6", "head", "html", "hr",
"h4", "h5", "h6", "head", "header", "hgroup", "html", "hr",
"i", "iframe", "img", "input", "ins", "isindex",
"kbd", "label", "legend", "li", "link", "map",
"menu", "meta", "nobr", "noframes", "noscript", "object", "ol",
"optgroup", "option", "p", "param", "pre", "q",
"s", "samp", "script", "select", "small", "span",
"strike", "strong", "style", "sub", "sup", "table",
"tbody", "td", "textarea", "tfoot", "th", "thead",
"title", "tr", "tt", "u", "ul", "var"]
"kbd", "keygen", "label", "legend", "li", "link", "map", "mark",
"menu", "meta", "meter", "nav", "nobr", "noframes", "noscript",
"object", "ol",
"optgroup", "option", "output", "p", "param", "pre", "progress", "q",
"rp", "rt", "ruby", "s", "samp", "script", "section", "select", "small",
"source", "span", "strike", "strong", "style",
"sub", "summary", "sup", "table",
"tbody", "td", "textarea", "tfoot", "th", "thead", "time",
"title", "tr", "track", "tt", "u", "ul", "var", "video", "wbr"]
InlineTags* = {tagA, tagAbbr, tagAcronym, tagApplet, tagB, tagBasefont,
tagBdo, tagBig, tagBr, tagButton, tagCite, tagCode, tagDel, tagDfn,
tagEm, tagFont, tagI, tagImg, tagIns, tagInput, tagIframe, tagKbd,
tagLabel, tagMap, tagObject, tagQ, tagSamp, tagScript, tagSelect,
tagSmall, tagSpan, tagStrong, tagSub, tagSup, tagTextarea, tagTt,
tagVar, tagApplet, tagBasefont, tagFont, tagIframe, tagU, tagS,
tagStrike}
tagStrike, tagWbr}
BlockTags* = {tagAddress, tagBlockquote, tagCenter, tagDel, tagDir, tagDiv,
tagDl, tagFieldset, tagForm, tagH1, tagH2, tagH3, tagH4,
tagH5, tagH6, tagHr, tagIns, tagIsindex, tagMenu, tagNoframes, tagNoscript,
@ -153,7 +189,7 @@ const
tagMenu, tagNoframes}
SingleTags* = {tagArea, tagBase, tagBasefont,
tagBr, tagCol, tagFrame, tagHr, tagImg, tagIsindex,
tagLink, tagMeta, tagParam}
tagLink, tagMeta, tagParam, tagWbr}
Entities = [
("nbsp", 0x00A0), ("iexcl", 0x00A1), ("cent", 0x00A2), ("pound", 0x00A3),
@ -228,28 +264,149 @@ const
("loz", 0x25CA), ("spades", 0x2660), ("clubs", 0x2663),
("hearts", 0x2665), ("diams", 0x2666)]
proc binaryStrSearch(x: openarray[string], y: string): int =
## XXX put this into the library somewhere!
var a = 0
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 allLower(s: string): bool =
for c in s:
if c < 'a' or c > 'z': return false
return true
proc toHtmlTag(s: string): THtmlTag =
case s
of "a": tagA
of "abbr": tagAbbr
of "acronym": tagAcronym
of "address": tagAddress
of "applet": tagApplet
of "area": tagArea
of "article": tagArticle
of "aside": tagAside
of "audio": tagAudio
of "b": tagB
of "base": tagBase
of "basefont": tagBasefont
of "bdi": tagBdi
of "bdo": tagBdo
of "big": tagBig
of "blockquote": tagBlockquote
of "body": tagBody
of "br": tagBr
of "button": tagButton
of "canvas": tagCanvas
of "caption": tagCaption
of "center": tagCenter
of "cite": tagCite
of "code": tagCode
of "col": tagCol
of "colgroup": tagColgroup
of "command": tagCommand
of "datalist": tagDatalist
of "dd": tagDd
of "del": tagDel
of "details": tagDetails
of "dfn": tagDfn
of "dialog": tagDialog
of "div": tagDiv
of "dir": tagDir
of "dl": tagDl
of "dt": tagDt
of "em": tagEm
of "embed": tagEmbed
of "fieldset": tagFieldset
of "figcaption": tagFigcaption
of "figure": tagFigure
of "font": tagFont
of "footer": tagFooter
of "form": tagForm
of "frame": tagFrame
of "frameset": tagFrameset
of "h1": tagH1
of "h2": tagH2
of "h3": tagH3
of "h4": tagH4
of "h5": tagH5
of "h6": tagH6
of "head": tagHead
of "header": tagHeader
of "hgroup": tagHgroup
of "html": tagHtml
of "hr": tagHr
of "i": tagI
of "iframe": tagIframe
of "img": tagImg
of "input": tagInput
of "ins": tagIns
of "isindex": tagIsindex
of "kbd": tagKbd
of "keygen": tagKeygen
of "label": tagLabel
of "legend": tagLegend
of "li": tagLi
of "link": tagLink
of "map": tagMap
of "mark": tagMark
of "menu": tagMenu
of "meta": tagMeta
of "meter": tagMeter
of "nav": tagNav
of "nobr": tagNobr
of "noframes": tagNoframes
of "noscript": tagNoscript
of "object": tagObject
of "ol": tagOl
of "optgroup": tagOptgroup
of "option": tagOption
of "output": tagOutput
of "p": tagP
of "param": tagParam
of "pre": tagPre
of "progress": tagProgress
of "q": tagQ
of "rp": tagRp
of "rt": tagRt
of "ruby": tagRuby
of "s": tagS
of "samp": tagSamp
of "script": tagScript
of "section": tagSection
of "select": tagSelect
of "small": tagSmall
of "source": tagSource
of "span": tagSpan
of "strike": tagStrike
of "strong": tagStrong
of "style": tagStyle
of "sub": tagSub
of "summary": tagSummary
of "sup": tagSup
of "table": tagTable
of "tbody": tagTbody
of "td": tagTd
of "textarea": tagTextarea
of "tfoot": tagTfoot
of "th": tagTh
of "thead": tagThead
of "time": tagTime
of "title": tagTitle
of "tr": tagTr
of "track": tagTrack
of "tt": tagTt
of "u": tagU
of "ul": tagUl
of "var": tagVar
of "video": tagVideo
of "wbr": tagWbr
else: tagUnknown
proc htmlTag*(n: PXmlNode): THtmlTag =
## gets `n`'s tag as a ``THtmlTag``.
if n.clientData == 0:
n.clientData = binaryStrSearch(tagToStr, n.tag)+1
n.clientData = toHtmlTag(n.tag).ord
result = THtmlTag(n.clientData)
proc htmlTag*(s: string): THtmlTag =
## converts `s` to a ``THtmlTag``. If `s` is no HTML tag, ``tagUnknown`` is
## returned.
result = THtmlTag(binaryStrSearch(tagToStr, s.toLower)+1)
let s = if allLower(s): s else: s.toLower
result = toHtmlTag(s)
proc entityToUtf8*(entity: string): string =
## converts an HTML entity name like ``&Uuml;`` to its UTF-8 equivalent.
@ -267,11 +424,13 @@ proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode
proc expected(x: var TXmlParser, n: PXmlNode): string =
result = errorMsg(x, "</" & n.tag & "> expected")
template elemName(x: expr): expr = rawData(x)
proc untilElementEnd(x: var TXmlParser, result: PXmlNode,
errors: var seq[string]) =
# we parsed e.g. ``<br>`` and don't really expect a ``</br>``:
if result.htmlTag in singleTags:
if x.kind != xmlElementEnd or cmpIgnoreCase(x.elementName, result.tag) != 0:
if x.kind != xmlElementEnd or cmpIgnoreCase(x.elemName, result.tag) != 0:
return
while true:
case x.kind
@ -279,28 +438,29 @@ proc untilElementEnd(x: var TXmlParser, result: PXmlNode,
case result.htmlTag
of tagLi, tagP, tagDt, tagDd, tagInput, tagOption:
# some tags are common to have no ``</end>``, like ``<li>``:
if htmlTag(x.elementName) in {tagLi, tagP, tagDt, tagDd, tagInput,
tagOption}:
if htmlTag(x.elemName) in {tagLi, tagP, tagDt, tagDd, tagInput,
tagOption}:
errors.add(expected(x, result))
break
when false:
if htmlTag(x.elementName) notin InlineTags:
errors.add(expected(x, result))
break
of tagTr, tagTd, tagTh, tagTfoot, tagThead:
if htmlTag(x.elementName) in {tagTr, tagTd, tagTh, tagTfoot, tagThead}:
of tagTd, tagTh, tagTfoot, tagThead:
if htmlTag(x.elemName) in {tagTr, tagTd, tagTh, tagTfoot, tagThead}:
errors.add(expected(x, result))
break
of tagTr:
if htmlTag(x.elemName) == tagTr:
errors.add(expected(x, result))
break
of tagOptgroup:
if htmlTag(x.elementName) in {tagOption, tagOptgroup}:
if htmlTag(x.elemName) in {tagOption, tagOptgroup}:
errors.add(expected(x, result))
break
else: nil
result.addNode(parse(x, errors))
of xmlElementEnd:
if cmpIgnoreCase(x.elementName, result.tag) == 0:
if cmpIgnoreCase(x.elemName, result.tag) == 0:
next(x)
else:
echo "5; expected: ", result.htmltag, " ", x.elemName
errors.add(expected(x, result))
# do not skip it here!
break
@ -313,10 +473,10 @@ proc untilElementEnd(x: var TXmlParser, result: PXmlNode,
proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode =
case x.kind
of xmlComment:
result = newComment(x.charData)
result = newComment(x.rawData)
next(x)
of xmlCharData, xmlWhitespace:
result = newText(x.charData)
result = newText(x.rawData)
next(x)
of xmlPI, xmlSpecial:
# we just ignore processing instructions for now
@ -325,19 +485,19 @@ proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode =
errors.add(errorMsg(x))
next(x)
of xmlElementStart:
result = newElement(x.elementName.toLower)
result = newElement(x.elemName.toLower)
next(x)
untilElementEnd(x, result, errors)
of xmlElementEnd:
errors.add(errorMsg(x, "unexpected ending tag: " & x.elementName))
errors.add(errorMsg(x, "unexpected ending tag: " & x.elemName))
of xmlElementOpen:
result = newElement(x.elementName.toLower)
result = newElement(x.elemName.toLower)
next(x)
result.attrs = newStringTable()
while true:
case x.kind
of xmlAttribute:
result.attrs[x.attrKey] = x.attrValue
result.attrs[x.rawData] = x.rawData2
next(x)
of xmlElementClose:
next(x)
@ -355,10 +515,10 @@ proc parse(x: var TXmlParser, errors: var seq[string]): PXmlNode =
errors.add(errorMsg(x, "<some_tag> expected"))
next(x)
of xmlCData:
result = newCData(x.charData)
result = newCData(x.rawData)
next(x)
of xmlEntity:
var u = entityToUtf8(x.entityName)
var u = entityToUtf8(x.rawData)
if u.len != 0: result = newText(u)
next(x)
of xmlEof: nil
@ -372,16 +532,20 @@ proc parseHtml*(s: PStream, filename: string,
next(x)
# skip the DOCTYPE:
if x.kind == xmlSpecial: next(x)
result = parse(x, errors)
if x.kind != xmlEof:
errors.add(errorMsg(x, "EOF expected"))
result = newElement("document")
result.addNode(parse(x, errors))
#if x.kind != xmlEof:
# errors.add(errorMsg(x, "EOF expected"))
while x.kind != xmlEof:
var oldPos = x.bufpos # little hack to see if we made any progess
result.addNode(parse(x, errors))
if x.bufpos == oldPos:
if x.bufpos == oldPos:
# force progress!
next(x)
next(x)
close(x)
if result.len == 1:
result = result[0]
proc parseHtml*(s: PStream): PXmlNode =
## parses the XTML from stream `s` and returns a ``PXmlNode``. All parsing
@ -400,22 +564,9 @@ proc loadHtml*(path: string, errors: var seq[string]): PXmlNode =
proc loadHtml*(path: string): PXmlNode =
## Loads and parses HTML from file specified by ``path``, and returns
## a ``PXmlNode``. All parsing errors are ignored.
var errors: seq[string] = @[]
var errors: seq[string] = @[]
result = loadHtml(path, errors)
when true:
nil
else:
proc checkHtmlAux(n: PXmlNode, errors: var seq[string]) =
nil
proc checkHtmlStructure*(n: PXmlNode, errors: var seq[string]) =
## checks the HTML structure after parsing for other errors like
## a ``<h1>`` element within a ``<p>`` element.
if n == nil or n.htmlTag != tagHtml:
errors.add("<html> tag expected")
checkHtmlAux(n, errors)
when isMainModule:
import os
@ -429,4 +580,3 @@ when isMainModule:
f.close()
else:
quit("cannot write test.txt")

View file

@ -47,10 +47,11 @@ proc badRequest(client: TSocket) =
send(client, "<p>Your browser sent a bad request, " &
"such as a POST without a Content-Length.</p>" & wwwNL)
proc cannotExec(client: TSocket) =
send(client, "HTTP/1.1 500 Internal Server Error" & wwwNL)
sendTextContentType(client)
send(client, "<P>Error prohibited CGI execution." & wwwNL)
when false:
proc cannotExec(client: TSocket) =
send(client, "HTTP/1.1 500 Internal Server Error" & wwwNL)
sendTextContentType(client)
send(client, "<P>Error prohibited CGI execution." & wwwNL)
proc headers(client: TSocket, filename: string) =
# XXX could use filename to determine file type
@ -79,11 +80,11 @@ proc unimplemented(client: TSocket) =
# ----------------- file serving ---------------------------------------------
proc discardHeaders(client: TSocket) = skip(client)
when false:
proc discardHeaders(client: TSocket) = skip(client)
proc serveFile*(client: TSocket, filename: string) =
## serves a file to the client.
when false: discardHeaders(client)
var f: TFile
if open(f, filename):
headers(client, filename)
@ -96,7 +97,7 @@ proc serveFile*(client: TSocket, filename: string) =
if bytesread != bytesWritten:
dealloc(buf)
close(f)
OSError()
OSError(OSLastError())
if bytesread != bufSize: break
dealloc(buf)
close(f)
@ -104,108 +105,109 @@ proc serveFile*(client: TSocket, filename: string) =
notFound(client)
# ------------------ CGI execution -------------------------------------------
when false:
# TODO: Fix this, or get rid of it.
type
TRequestMethod = enum reqGet, reqPost
type
TRequestMethod = enum reqGet, reqPost
proc executeCgi(client: TSocket, path, query: string, meth: TRequestMethod) =
var env = newStringTable(modeCaseInsensitive)
var contentLength = -1
case meth
of reqGet:
discardHeaders(client)
proc executeCgi(client: TSocket, path, query: string, meth: TRequestMethod) =
var env = newStringTable(modeCaseInsensitive)
var contentLength = -1
case meth
of reqGet:
discardHeaders(client)
env["REQUEST_METHOD"] = "GET"
env["QUERY_STRING"] = query
of reqPost:
var buf = TaintedString""
var dataAvail = false
while dataAvail:
dataAvail = recvLine(client, buf) # TODO: This is incorrect.
var L = toLower(buf.string)
if L.startsWith("content-length:"):
var i = len("content-length:")
while L[i] in Whitespace: inc(i)
contentLength = parseInt(substr(L, i))
env["REQUEST_METHOD"] = "GET"
env["QUERY_STRING"] = query
of reqPost:
var buf = TaintedString""
var dataAvail = false
while dataAvail:
dataAvail = recvLine(client, buf) # TODO: This is incorrect.
var L = toLower(buf.string)
if L.startsWith("content-length:"):
var i = len("content-length:")
while L[i] in Whitespace: inc(i)
contentLength = parseInt(substr(L, i))
if contentLength < 0:
badRequest(client)
return
if contentLength < 0:
badRequest(client)
return
env["REQUEST_METHOD"] = "POST"
env["CONTENT_LENGTH"] = $contentLength
env["REQUEST_METHOD"] = "POST"
env["CONTENT_LENGTH"] = $contentLength
send(client, "HTTP/1.0 200 OK" & wwwNL)
send(client, "HTTP/1.0 200 OK" & wwwNL)
var process = startProcess(command=path, env=env)
if meth == reqPost:
# get from client and post to CGI program:
var buf = alloc(contentLength)
if recv(client, buf, contentLength) != contentLength:
var process = startProcess(command=path, env=env)
if meth == reqPost:
# get from client and post to CGI program:
var buf = alloc(contentLength)
if recv(client, buf, contentLength) != contentLength:
dealloc(buf)
OSError()
var inp = process.inputStream
inp.writeData(buf, contentLength)
dealloc(buf)
OSError()
var inp = process.inputStream
inp.writeData(buf, contentLength)
dealloc(buf)
var outp = process.outputStream
var line = newStringOfCap(120).TaintedString
while true:
if outp.readLine(line):
send(client, line.string)
send(client, wwwNL)
elif not running(process): break
var outp = process.outputStream
var line = newStringOfCap(120).TaintedString
while true:
if outp.readLine(line):
send(client, line.string)
send(client, wwwNL)
elif not running(process): break
# --------------- Server Setup -----------------------------------------------
# --------------- Server Setup -----------------------------------------------
proc acceptRequest(client: TSocket) =
var cgi = false
var query = ""
var buf = TaintedString""
discard recvLine(client, buf)
var path = ""
var data = buf.string.split()
var meth = reqGet
proc acceptRequest(client: TSocket) =
var cgi = false
var query = ""
var buf = TaintedString""
discard recvLine(client, buf)
var path = ""
var data = buf.string.split()
var meth = reqGet
var q = find(data[1], '?')
var q = find(data[1], '?')
# extract path
if q >= 0:
# strip "?..." from path, this may be found in both POST and GET
path = "." & data[1].substr(0, q-1)
else:
path = "." & data[1]
# path starts with "/", by adding "." in front of it we serve files from cwd
if cmpIgnoreCase(data[0], "GET") == 0:
# extract path
if q >= 0:
# strip "?..." from path, this may be found in both POST and GET
path = "." & data[1].substr(0, q-1)
else:
path = "." & data[1]
# path starts with "/", by adding "." in front of it we serve files from cwd
if cmpIgnoreCase(data[0], "GET") == 0:
if q >= 0:
cgi = true
query = data[1].substr(q+1)
elif cmpIgnoreCase(data[0], "POST") == 0:
cgi = true
query = data[1].substr(q+1)
elif cmpIgnoreCase(data[0], "POST") == 0:
cgi = true
meth = reqPost
else:
unimplemented(client)
if path[path.len-1] == '/' or existsDir(path):
path = path / "index.html"
if not ExistsFile(path):
discardHeaders(client)
notFound(client)
else:
when defined(Windows):
var ext = splitFile(path).ext.toLower
if ext == ".exe" or ext == ".cgi":
# XXX: extract interpreter information here?
cgi = true
meth = reqPost
else:
if {fpUserExec, fpGroupExec, fpOthersExec} * path.getFilePermissions != {}:
cgi = true
if not cgi:
serveFile(client, path)
unimplemented(client)
if path[path.len-1] == '/' or existsDir(path):
path = path / "index.html"
if not ExistsFile(path):
discardHeaders(client)
notFound(client)
else:
executeCgi(client, path, query, meth)
when defined(Windows):
var ext = splitFile(path).ext.toLower
if ext == ".exe" or ext == ".cgi":
# XXX: extract interpreter information here?
cgi = true
else:
if {fpUserExec, fpGroupExec, fpOthersExec} * path.getFilePermissions != {}:
cgi = true
if not cgi:
serveFile(client, path)
else:
executeCgi(client, path, query, meth)
type
TServer* = object of TObject ## contains the current server state
@ -226,7 +228,7 @@ proc open*(s: var TServer, port = TPort(80)) =
## creates a new server at port `port`. If ``port == 0`` a free port is
## acquired that can be accessed later by the ``port`` proc.
s.socket = socket(AF_INET)
if s.socket == InvalidSocket: OSError()
if s.socket == InvalidSocket: OSError(OSLastError())
bindAddr(s.socket, port)
listen(s.socket)

View file

@ -252,7 +252,7 @@ when isMainModule:
["test", "1", "2", "3", "4"], ["test", "1", "2", "3", "4"],
["test", "1", "2", "3", "4"]]
testit(x)
var test2: tuple[name: string, s: int] = ("tuple test", 56)
var test2: tuple[name: string, s: uint] = ("tuple test", 56u)
testit(test2)
type

View file

@ -50,11 +50,11 @@ proc open*(filename: string, mode: TFileMode = fmRead,
result.size = 0
when defined(windows):
template fail(msg: expr) =
template fail(errCode: TOSErrorCode, msg: expr) =
rollback()
if result.fHandle != 0: discard CloseHandle(result.fHandle)
if result.mapHandle != 0: discard CloseHandle(result.mapHandle)
OSError()
OSError(errCode)
# return false
#raise newException(EIO, msg)
@ -74,7 +74,7 @@ proc open*(filename: string, mode: TFileMode = fmRead,
result.fHandle = callCreateFile(CreateFileA, filename)
if result.fHandle == INVALID_HANDLE_VALUE:
fail "error opening file"
fail(OSLastError(), "error opening file")
if newFileSize != -1:
var
@ -83,9 +83,10 @@ proc open*(filename: string, mode: TFileMode = fmRead,
var status = SetFilePointer(result.fHandle, sizeLow, addr(sizeHigh),
FILE_BEGIN)
if (status == INVALID_SET_FILE_POINTER and GetLastError() != NO_ERROR) or
let lastErr = OSLastError()
if (status == INVALID_SET_FILE_POINTER and lastErr.int32 != NO_ERROR) or
(SetEndOfFile(result.fHandle) == 0):
fail "error setting file size"
fail(lastErr, "error setting file size")
# since the strings are always 'nil', we simply always call
# CreateFileMappingW which should be slightly faster anyway:
@ -95,7 +96,7 @@ proc open*(filename: string, mode: TFileMode = fmRead,
0, 0, nil)
if result.mapHandle == 0:
fail "error creating mapping"
fail(OSLastError(), "error creating mapping")
result.mem = MapViewOfFileEx(
result.mapHandle,
@ -106,22 +107,22 @@ proc open*(filename: string, mode: TFileMode = fmRead,
nil)
if result.mem == nil:
fail "error mapping view"
fail(OSLastError(), "error mapping view")
var hi, low: int32
low = GetFileSize(result.fHandle, addr(hi))
if low == INVALID_FILE_SIZE:
fail "error getting file size"
fail(OSLastError(), "error getting file size")
else:
var fileSize = (int64(hi) shr 32) or low
if mappedSize != -1: result.size = min(fileSize, mappedSize).int
else: result.size = fileSize.int
else:
template fail(msg: expr) =
template fail(errCode: TOSErrorCode, msg: expr) =
rollback()
if result.handle != 0: discard close(result.handle)
OSError()
OSError(errCode)
var flags = if readonly: O_RDONLY else: O_RDWR
@ -132,11 +133,11 @@ proc open*(filename: string, mode: TFileMode = fmRead,
if result.handle == -1:
# XXX: errno is supposed to be set here
# Is there an exception that wraps it?
fail "error opening file"
fail(OSLastError(), "error opening file")
if newFileSize != -1:
if ftruncate(result.handle, newFileSize) == -1:
fail "error setting file size"
fail(OSLastError(), "error setting file size")
if mappedSize != -1:
result.size = mappedSize
@ -147,7 +148,7 @@ proc open*(filename: string, mode: TFileMode = fmRead,
# Why is mmap taking int anyway?
result.size = int(stat.st_size)
else:
fail "error getting file size"
fail(OSLastError(), "error getting file size")
result.mem = mmap(
nil,
@ -158,21 +159,24 @@ proc open*(filename: string, mode: TFileMode = fmRead,
offset)
if result.mem == cast[pointer](MAP_FAILED):
fail "file mapping failed"
fail(OSLastError(), "file mapping failed")
proc close*(f: var TMemFile) =
## closes the memory mapped file `f`. All changes are written back to the
## file system, if `f` was opened with write access.
var error = false
var lastErr: TOSErrorCode
when defined(windows):
if f.fHandle != INVALID_HANDLE_VALUE:
lastErr = OSLastError()
error = UnmapViewOfFile(f.mem) == 0
error = (CloseHandle(f.mapHandle) == 0) or error
error = (CloseHandle(f.fHandle) == 0) or error
else:
if f.handle != 0:
lastErr = OSLastError()
error = munmap(f.mem, f.size) != 0
error = (close(f.handle) != 0) or error
@ -185,5 +189,5 @@ proc close*(f: var TMemFile) =
else:
f.handle = 0
if error: OSError()
if error: OSError(lastErr)

View file

@ -39,6 +39,8 @@ type
FWriteDir* = object of FWriteIO ## effect that denotes a write operation to
## the directory structure
TOSErrorCode* = distinct int32 ## Specifies an OS Error Code.
const
doslike = defined(windows) or defined(OS2) or defined(DOS)
# DOS-like filesystem
@ -171,10 +173,13 @@ const
## The character which separates the base filename from the extension;
## for example, the '.' in ``os.nim``.
proc OSErrorMsg*(): string {.rtl, extern: "nos$1".} =
proc OSErrorMsg*(): string {.rtl, extern: "nos$1", deprecated.} =
## Retrieves the operating system's error flag, ``errno``.
## On Windows ``GetLastError`` is checked before ``errno``.
## Returns "" if no error occured.
##
## **Deprecated since version 0.9.4**: use the other ``OSErrorMsg`` proc.
result = ""
when defined(Windows):
var err = GetLastError()
@ -194,17 +199,89 @@ proc OSErrorMsg*(): string {.rtl, extern: "nos$1".} =
if errno != 0'i32:
result = $os.strerror(errno)
proc OSError*(msg: string = "") {.noinline, rtl, extern: "nos$1".} =
{.push warning[deprecated]: off.}
proc OSError*(msg: string = "") {.noinline, rtl, extern: "nos$1", deprecated.} =
## raises an EOS exception with the given message ``msg``.
## If ``msg == ""``, the operating system's error flag
## (``errno``) is converted to a readable error message. On Windows
## ``GetLastError`` is checked before ``errno``.
## If no error flag is set, the message ``unknown OS error`` is used.
##
## **Deprecated since version 0.9.4**: use the other ``OSError`` proc.
if len(msg) == 0:
var m = OSErrorMsg()
raise newException(EOS, if m.len > 0: m else: "unknown OS error")
else:
raise newException(EOS, msg)
{.pop.}
proc `==`*(err1, err2: TOSErrorCode): bool {.borrow.}
proc `$`*(err: TOSErrorCode): string {.borrow.}
proc OSErrorMsg*(errorCode: TOSErrorCode): string =
## Converts an OS error code into a human readable string.
##
## The error code can be retrieved using the ``OSLastError`` proc.
##
## If conversion fails, or ``errorCode`` is ``0`` then ``""`` will be
## returned.
##
## On Windows, the ``-d:useWinAnsi`` compilation flag can be used to
## make this procedure use the non-unicode Win API calls to retrieve the
## message.
result = ""
when defined(Windows):
if errorCode != TOSErrorCode(0'i32):
when useWinUnicode:
var msgbuf: widecstring
if FormatMessageW(0x00000100 or 0x00001000 or 0x00000200,
nil, errorCode.int32, 0, addr(msgbuf), 0, nil) != 0'i32:
result = $msgbuf
if msgbuf != nil: LocalFree(cast[pointer](msgbuf))
else:
var msgbuf: cstring
if FormatMessageA(0x00000100 or 0x00001000 or 0x00000200,
nil, errorCode.int32, 0, addr(msgbuf), 0, nil) != 0'i32:
result = $msgbuf
if msgbuf != nil: LocalFree(msgbuf)
else:
if errorCode != TOSErrorCode(0'i32):
result = $os.strerror(errorCode.int32)
proc OSError*(errorCode: TOSErrorCode) =
## Raises an ``EOS`` exception. The ``errorCode`` will determine the
## message, ``OSErrorMsg`` will be used to get this message.
##
## The error code can be retrieved using the ``OSLastError`` proc.
##
## If the error code is ``0`` or an error message could not be retrieved,
## the message ``unknown OS error`` will be used.
let msg = OSErrorMsg(errorCode)
if msg == "":
raise newException(EOS, "unknown OS error")
else:
raise newException(EOS, msg)
{.push stackTrace:off.}
proc OSLastError*(): TOSErrorCode =
## Retrieves the last operating system error code.
##
## This procedure is useful in the event when an OS call fails. In that case
## this procedure will return the error code describing the reason why the
## OS call failed. The ``OSErrorMsg`` procedure can then be used to convert
## this code into a string.
##
## **Warning**:
## The behaviour of this procedure varies between Windows and POSIX systems.
## On Windows some OS calls can reset the error code to ``0`` causing this
## procedure to return ``0``. It is therefore advised to call this procedure
## immediately after an OS call fails. On POSIX systems this is not a problem.
when defined(windows):
result = TOSErrorCode(GetLastError())
else:
result = TOSErrorCode(errno)
{.pop.}
proc UnixToNativePath*(path: string): string {.
noSideEffect, rtl, extern: "nos$1".} =
@ -311,12 +388,12 @@ proc getLastModificationTime*(file: string): TTime {.rtl, extern: "nos$1".} =
## Returns the `file`'s last modification time.
when defined(posix):
var res: TStat
if stat(file, res) < 0'i32: OSError()
if stat(file, res) < 0'i32: OSError(OSLastError())
return res.st_mtime
else:
var f: TWIN32_Find_Data
var h = findfirstFile(file, f)
if h == -1'i32: OSError()
if h == -1'i32: OSError(OSLastError())
result = winTimeToUnixTime(rdFileTime(f.ftLastWriteTime))
findclose(h)
@ -324,12 +401,12 @@ proc getLastAccessTime*(file: string): TTime {.rtl, extern: "nos$1".} =
## Returns the `file`'s last read or write access time.
when defined(posix):
var res: TStat
if stat(file, res) < 0'i32: OSError()
if stat(file, res) < 0'i32: OSError(OSLastError())
return res.st_atime
else:
var f: TWIN32_Find_Data
var h = findfirstFile(file, f)
if h == -1'i32: OSError()
if h == -1'i32: OSError(OSLastError())
result = winTimeToUnixTime(rdFileTime(f.ftLastAccessTime))
findclose(h)
@ -337,12 +414,12 @@ proc getCreationTime*(file: string): TTime {.rtl, extern: "nos$1".} =
## Returns the `file`'s creation time.
when defined(posix):
var res: TStat
if stat(file, res) < 0'i32: OSError()
if stat(file, res) < 0'i32: OSError(OSLastError())
return res.st_ctime
else:
var f: TWIN32_Find_Data
var h = findfirstFile(file, f)
if h == -1'i32: OSError()
if h == -1'i32: OSError(OSLastError())
result = winTimeToUnixTime(rdFileTime(f.ftCreationTime))
findclose(h)
@ -358,30 +435,30 @@ proc getCurrentDir*(): string {.rtl, extern: "nos$1", tags: [].} =
when useWinUnicode:
var res = newWideCString("", bufsize)
var L = GetCurrentDirectoryW(bufsize, res)
if L == 0'i32: OSError()
if L == 0'i32: OSError(OSLastError())
result = res$L
else:
result = newString(bufsize)
var L = GetCurrentDirectoryA(bufsize, result)
if L == 0'i32: OSError()
if L == 0'i32: OSError(OSLastError())
setLen(result, L)
else:
result = newString(bufsize)
if getcwd(result, bufsize) != nil:
setlen(result, c_strlen(result))
else:
OSError()
OSError(OSLastError())
proc setCurrentDir*(newDir: string) {.inline, tags: [].} =
## Sets the `current working directory`:idx:; `EOS` is raised if
## `newDir` cannot been set.
when defined(Windows):
when useWinUnicode:
if SetCurrentDirectoryW(newWideCString(newDir)) == 0'i32: OSError()
if SetCurrentDirectoryW(newWideCString(newDir)) == 0'i32: OSError(OSLastError())
else:
if SetCurrentDirectoryA(newDir) == 0'i32: OSError()
if SetCurrentDirectoryA(newDir) == 0'i32: OSError(OSLastError())
else:
if chdir(newDir) != 0'i32: OSError()
if chdir(newDir) != 0'i32: OSError(OSLastError())
proc JoinPath*(head, tail: string): string {.
noSideEffect, rtl, extern: "nos$1".} =
@ -571,23 +648,23 @@ proc expandFilename*(filename: string): string {.rtl, extern: "nos$1",
var res = newWideCString("", bufsize div 2)
var L = GetFullPathNameW(newWideCString(filename), bufsize, res, unused)
if L <= 0'i32 or L >= bufsize:
OSError()
OSError(OSLastError())
result = res$L
else:
var unused: cstring
result = newString(bufsize)
var L = GetFullPathNameA(filename, bufsize, result, unused)
if L <= 0'i32 or L >= bufsize: OSError()
if L <= 0'i32 or L >= bufsize: OSError(OSLastError())
setLen(result, L)
elif defined(macosx) or defined(bsd):
# On Mac OS X 10.5, realpath does not allocate the buffer on its own
var pathBuffer: cstring = newString(pathMax)
var resultBuffer = realpath(filename, pathBuffer)
if resultBuffer == nil: OSError()
if resultBuffer == nil: OSError(OSLastError())
result = $resultBuffer
else:
var res = realpath(filename, nil)
if res == nil: OSError()
if res == nil: OSError(OSLastError())
result = $res
c_free(res)
@ -677,6 +754,7 @@ proc sameFile*(path1, path2: string): bool {.rtl, extern: "nos$1",
var f1 = OpenHandle(path1)
var f2 = OpenHandle(path2)
var lastErr: TOSErrorCode
if f1 != INVALID_HANDLE_VALUE and f2 != INVALID_HANDLE_VALUE:
var fi1, fi2: TBY_HANDLE_FILE_INFORMATION
@ -685,17 +763,21 @@ proc sameFile*(path1, path2: string): bool {.rtl, extern: "nos$1",
result = fi1.dwVolumeSerialNumber == fi2.dwVolumeSerialNumber and
fi1.nFileIndexHigh == fi2.nFileIndexHigh and
fi1.nFileIndexLow == fi2.nFileIndexLow
else: success = false
else: success = false
else:
lastErr = OSLastError()
success = false
else:
lastErr = OSLastError()
success = false
discard CloseHandle(f1)
discard CloseHandle(f2)
if not success: OSError()
if not success: OSError(lastErr)
else:
var a, b: TStat
if stat(path1, a) < 0'i32 or stat(path2, b) < 0'i32:
OSError()
OSError(OSLastError())
else:
result = a.st_dev == b.st_dev and a.st_ino == b.st_ino
@ -738,17 +820,17 @@ proc copyFile*(source, dest: string) {.rtl, extern: "nos$1",
when useWinUnicode:
let s = newWideCString(source)
let d = newWideCString(dest)
if CopyFileW(s, d, 0'i32) == 0'i32: OSError()
if CopyFileW(s, d, 0'i32) == 0'i32: OSError(OSLastError())
else:
if CopyFileA(source, dest, 0'i32) == 0'i32: OSError()
if CopyFileA(source, dest, 0'i32) == 0'i32: OSError(OSLastError())
else:
# generic version of copyFile which works for any platform:
const bufSize = 8000 # better for memory manager
var d, s: TFile
if not open(s, source): OSError()
if not open(s, source): OSError(OSLastError())
if not open(d, dest, fmWrite):
close(s)
OSError()
OSError(OSLastError())
var buf = alloc(bufsize)
while True:
var bytesread = readBuffer(s, buf, bufsize)
@ -758,7 +840,7 @@ proc copyFile*(source, dest: string) {.rtl, extern: "nos$1",
dealloc(buf)
close(s)
close(d)
OSError()
OSError(OSLastError())
if bytesread != bufSize: break
dealloc(buf)
close(s)
@ -767,7 +849,8 @@ proc copyFile*(source, dest: string) {.rtl, extern: "nos$1",
proc moveFile*(source, dest: string) {.rtl, extern: "nos$1",
tags: [FReadIO, FWriteIO].} =
## Moves a file from `source` to `dest`. If this fails, `EOS` is raised.
if crename(source, dest) != 0'i32: OSError()
if crename(source, dest) != 0'i32:
raise newException(EOS, $strerror(errno))
when not defined(ENOENT):
var ENOENT {.importc, header: "<errno.h>".}: cint
@ -775,7 +858,8 @@ when not defined(ENOENT):
proc removeFile*(file: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} =
## Removes the `file`. If this fails, `EOS` is raised. This does not fail
## if the file never existed in the first place.
if cremove(file) != 0'i32 and errno != ENOENT: OSError()
if cremove(file) != 0'i32 and errno != ENOENT:
raise newException(EOS, $strerror(errno))
proc execShellCmd*(command: string): int {.rtl, extern: "nos$1",
tags: [FExecIO].} =
@ -907,14 +991,14 @@ proc putEnv*(key, val: string) {.tags: [FWriteEnv].} =
indx = high(environment)
when defined(unix):
if cputenv(environment[indx]) != 0'i32:
OSError()
OSError(OSLastError())
else:
when useWinUnicode:
var k = newWideCString(key)
var v = newWideCString(val)
if SetEnvironmentVariableW(k, v) == 0'i32: OSError()
if SetEnvironmentVariableW(k, v) == 0'i32: OSError(OSLastError())
else:
if SetEnvironmentVariableA(key, val) == 0'i32: OSError()
if SetEnvironmentVariableA(key, val) == 0'i32: OSError(OSLastError())
iterator envPairs*(): tuple[key, value: TaintedString] {.tags: [FReadEnv].} =
## Iterate over all `environments variables`:idx:. In the first component
@ -1044,10 +1128,12 @@ proc rawRemoveDir(dir: string) =
wrapUnary(res, RemoveDirectoryW, dir)
else:
var res = RemoveDirectoryA(dir)
if res == 0'i32 and GetLastError() != 3'i32 and
GetLastError() != 18'i32: OSError()
let lastError = OSLastError()
if res == 0'i32 and lastError.int32 != 3'i32 and
lastError.int32 != 18'i32 and lastError.int32 != 2'i32:
OSError(lastError)
else:
if rmdir(dir) != 0'i32 and errno != ENOENT: OSError()
if rmdir(dir) != 0'i32 and errno != ENOENT: OSError(OSLastError())
proc removeDir*(dir: string) {.rtl, extern: "nos$1", tags: [
FWriteDir, FReadDir].} =
@ -1065,14 +1151,14 @@ proc removeDir*(dir: string) {.rtl, extern: "nos$1", tags: [
proc rawCreateDir(dir: string) =
when defined(unix):
if mkdir(dir, 0o711) != 0'i32 and errno != EEXIST:
OSError()
OSError(OSLastError())
else:
when useWinUnicode:
wrapUnary(res, CreateDirectoryW, dir)
else:
var res = CreateDirectoryA(dir)
if res == 0'i32 and GetLastError() != 183'i32:
OSError()
OSError(OSLastError())
proc createDir*(dir: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} =
## Creates the `directory`:idx: `dir`.
@ -1213,7 +1299,7 @@ proc getFilePermissions*(filename: string): set[TFilePermission] {.
## permission is available in any case.
when defined(posix):
var a: TStat
if stat(filename, a) < 0'i32: OSError()
if stat(filename, a) < 0'i32: OSError(OSLastError())
result = {}
if (a.st_mode and S_IRUSR) != 0'i32: result.incl(fpUserRead)
if (a.st_mode and S_IWUSR) != 0'i32: result.incl(fpUserWrite)
@ -1231,7 +1317,7 @@ proc getFilePermissions*(filename: string): set[TFilePermission] {.
wrapUnary(res, GetFileAttributesW, filename)
else:
var res = GetFileAttributesA(filename)
if res == -1'i32: OSError()
if res == -1'i32: OSError(OSLastError())
if (res and FILE_ATTRIBUTE_READONLY) != 0'i32:
result = {fpUserExec, fpUserRead, fpGroupExec, fpGroupRead,
fpOthersExec, fpOthersRead}
@ -1257,13 +1343,13 @@ proc setFilePermissions*(filename: string, permissions: set[TFilePermission]) {.
if fpOthersWrite in permissions: p = p or S_IWOTH
if fpOthersExec in permissions: p = p or S_IXOTH
if chmod(filename, p) != 0: OSError()
if chmod(filename, p) != 0: OSError(OSLastError())
else:
when useWinUnicode:
wrapUnary(res, GetFileAttributesW, filename)
else:
var res = GetFileAttributesA(filename)
if res == -1'i32: OSError()
if res == -1'i32: OSError(OSLastError())
if fpUserWrite in permissions:
res = res and not FILE_ATTRIBUTE_READONLY
else:
@ -1272,7 +1358,7 @@ proc setFilePermissions*(filename: string, permissions: set[TFilePermission]) {.
wrapBinary(res2, SetFileAttributesW, filename, res)
else:
var res2 = SetFileAttributesA(filename, res)
if res2 == - 1'i32: OSError()
if res2 == - 1'i32: OSError(OSLastError())
proc inclFilePermissions*(filename: string,
permissions: set[TFilePermission]) {.
@ -1368,6 +1454,9 @@ when defined(macosx):
proc getAppFilename*(): string {.rtl, extern: "nos$1", tags: [FReadIO].} =
## Returns the filename of the application's executable.
##
## This procedure will resolve symlinks.
##
## **Note**: This does not work reliably on BSD.
# Linux: /proc/<pid>/exe
@ -1397,6 +1486,8 @@ proc getAppFilename*(): string {.rtl, extern: "nos$1", tags: [FReadIO].} =
result = newString(int(size))
if getExecPath2(result, size):
result = "" # error!
if result.len > 0:
result = result.expandFilename
else:
# little heuristic that may work on other POSIX-like systems:
result = string(getEnv("_"))
@ -1443,7 +1534,7 @@ proc getFileSize*(file: string): biggestInt {.rtl, extern: "nos$1",
when defined(windows):
var a: TWin32FindData
var resA = findfirstFile(file, a)
if resA == -1: OSError()
if resA == -1: OSError(OSLastError())
result = rdFileSize(a)
findclose(resA)
else:
@ -1451,7 +1542,7 @@ proc getFileSize*(file: string): biggestInt {.rtl, extern: "nos$1",
if open(f, file):
result = getFileSize(f)
close(f)
else: OSError()
else: OSError(OSLastError())
proc findExe*(exe: string): string {.tags: [FReadDir, FReadEnv].} =
## Searches for `exe` in the current working directory and then

View file

@ -264,7 +264,7 @@ when defined(Windows) and not defined(useNimRtl):
# TRUE and zero bytes returned (EOF).
# TRUE and n (>0) bytes returned (good data).
# FALSE and bytes returned undefined (system error).
if a == 0 and br != 0: OSError()
if a == 0 and br != 0: OSError(OSLastError())
s.atTheEnd = br < bufLen
result = br
@ -272,7 +272,7 @@ when defined(Windows) and not defined(useNimRtl):
var s = PFileHandleStream(s)
var bytesWritten: int32
var a = winlean.writeFile(s.handle, buffer, bufLen.cint, bytesWritten, nil)
if a == 0: OSError()
if a == 0: OSError(OSLastError())
proc newFileHandleStream(handle: THandle): PFileHandleStream =
new(result)
@ -313,7 +313,7 @@ when defined(Windows) and not defined(useNimRtl):
piInheritablePipe.lpSecurityDescriptor = nil
piInheritablePipe.Binherithandle = 1
if CreatePipe(Rdhandle, Wrhandle, piInheritablePipe, 1024) == 0'i32:
OSError()
OSError(OSLastError())
proc fileClose(h: THandle) {.inline.} =
if h > 4: discard CloseHandle(h)
@ -370,6 +370,7 @@ when defined(Windows) and not defined(useNimRtl):
else:
success = winlean.CreateProcessA(nil,
cmdl, nil, nil, 1, NORMAL_PRIORITY_CLASS, e, wd, SI, ProcInfo)
let lastError = OSLastError()
if poParentStreams notin options:
FileClose(si.hStdInput)
@ -379,7 +380,7 @@ when defined(Windows) and not defined(useNimRtl):
if e != nil: dealloc(e)
dealloc(cmdl)
if success == 0: OSError()
if success == 0: OSError(lastError)
# Close the handle now so anyone waiting is woken:
discard closeHandle(procInfo.hThread)
result.FProcessHandle = procInfo.hProcess
@ -450,7 +451,7 @@ when defined(Windows) and not defined(useNimRtl):
var res = winlean.CreateProcessA(nil, command, nil, nil, 0,
NORMAL_PRIORITY_CLASS, nil, nil, SI, ProcInfo)
if res == 0:
OSError()
OSError(OSLastError())
else:
Process = ProcInfo.hProcess
discard CloseHandle(ProcInfo.hThread)
@ -473,7 +474,7 @@ when defined(Windows) and not defined(useNimRtl):
of WAIT_TIMEOUT:
return 0
of WAIT_FAILED:
OSError()
OSError(OSLastError())
else:
var i = ret - WAIT_OBJECT_0
readfds.del(i)
@ -531,7 +532,7 @@ elif not defined(useNimRtl):
if poParentStreams notin options:
if pipe(p_stdin) != 0'i32 or pipe(p_stdout) != 0'i32 or
pipe(p_stderr) != 0'i32:
OSError()
OSError(OSLastError())
var pid: TPid
when defined(posix_spawn) and not defined(useFork):
@ -539,7 +540,7 @@ elif not defined(useNimRtl):
var fops: Tposix_spawn_file_actions
template chck(e: expr) =
if e != 0'i32: OSError()
if e != 0'i32: OSError(OSLastError())
chck posix_spawn_file_actions_init(fops)
chck posix_spawnattr_init(attr)
@ -584,20 +585,20 @@ elif not defined(useNimRtl):
else:
Pid = fork()
if Pid < 0: OSError()
if Pid < 0: OSError(OSLastError())
if pid == 0:
## child process:
if poParentStreams notin options:
discard close(p_stdin[writeIdx])
if dup2(p_stdin[readIdx], readIdx) < 0: OSError()
if dup2(p_stdin[readIdx], readIdx) < 0: OSError(OSLastError())
discard close(p_stdout[readIdx])
if dup2(p_stdout[writeIdx], writeIdx) < 0: OSError()
if dup2(p_stdout[writeIdx], writeIdx) < 0: OSError(OSLastError())
discard close(p_stderr[readIdx])
if poStdErrToStdOut in options:
if dup2(p_stdout[writeIdx], 2) < 0: OSError()
if dup2(p_stdout[writeIdx], 2) < 0: OSError(OSLastError())
else:
if dup2(p_stderr[writeIdx], 2) < 0: OSError()
if dup2(p_stderr[writeIdx], 2) < 0: OSError(OSLastError())
# Create a new process group
if setpgid(0, 0) == -1: quit("setpgid call failed: " & $strerror(errno))
@ -652,10 +653,10 @@ elif not defined(useNimRtl):
discard close(p.errorHandle)
proc suspend(p: PProcess) =
if kill(-p.id, SIGSTOP) != 0'i32: OSError()
if kill(-p.id, SIGSTOP) != 0'i32: OSError(OSLastError())
proc resume(p: PProcess) =
if kill(-p.id, SIGCONT) != 0'i32: OSError()
if kill(-p.id, SIGCONT) != 0'i32: OSError(OSLastError())
proc running(p: PProcess): bool =
var ret = waitPid(p.id, p.exitCode, WNOHANG)
@ -665,8 +666,8 @@ elif not defined(useNimRtl):
proc terminate(p: PProcess) =
if kill(-p.id, SIGTERM) == 0'i32:
if p.running():
if kill(-p.id, SIGKILL) != 0'i32: OSError()
else: OSError()
if kill(-p.id, SIGKILL) != 0'i32: OSError(OSLastError())
else: OSError(OSLastError())
proc waitForExit(p: PProcess, timeout: int = -1): int =
#if waitPid(p.id, p.exitCode, 0) == int(p.id):
@ -676,7 +677,7 @@ elif not defined(useNimRtl):
if p.exitCode != -3: return p.exitCode
if waitPid(p.id, p.exitCode, 0) < 0:
p.exitCode = -3
OSError()
OSError(OSLastError())
result = int(p.exitCode) shr 8
proc peekExitCode(p: PProcess): int =
@ -690,7 +691,7 @@ elif not defined(useNimRtl):
proc createStream(stream: var PStream, handle: var TFileHandle,
fileMode: TFileMode) =
var f: TFile
if not open(f, handle, fileMode): OSError()
if not open(f, handle, fileMode): OSError(OSLastError())
stream = newFileStream(f)
proc inputStream(p: PProcess): PStream =

View file

@ -67,7 +67,8 @@ type
# implementation
const
SymChars: TCharSet = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\x80'..'\xFF', '.'}
SymChars: TCharSet = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\x80'..'\xFF', '.',
'/', '\\'}
proc rawGetTok(c: var TCfgParser, tok: var TToken)
@ -149,7 +150,7 @@ proc getEscapedChar(c: var TCfgParser, tok: var TToken) =
of 't', 'T':
add(tok.literal, '\t')
Inc(c.bufpos)
of '\'', '\"':
of '\'', '"':
add(tok.literal, c.buf[c.bufpos])
Inc(c.bufpos)
of '\\':
@ -178,7 +179,7 @@ proc getString(c: var TCfgParser, tok: var TToken, rawMode: bool) =
var pos = c.bufPos + 1 # skip "
var buf = c.buf # put `buf` in a register
tok.kind = tkSymbol
if (buf[pos] == '\"') and (buf[pos + 1] == '\"'):
if (buf[pos] == '"') and (buf[pos + 1] == '"'):
# long string literal:
inc(pos, 2) # skip ""
# skip leading newline:
@ -186,9 +187,9 @@ proc getString(c: var TCfgParser, tok: var TToken, rawMode: bool) =
buf = c.buf
while true:
case buf[pos]
of '\"':
if (buf[pos + 1] == '\"') and (buf[pos + 2] == '\"'): break
add(tok.literal, '\"')
of '"':
if (buf[pos + 1] == '"') and (buf[pos + 2] == '"'): break
add(tok.literal, '"')
Inc(pos)
of '\c', '\L':
pos = HandleCRLF(c, pos)
@ -205,7 +206,7 @@ proc getString(c: var TCfgParser, tok: var TToken, rawMode: bool) =
# ordinary string literal
while true:
var ch = buf[pos]
if ch == '\"':
if ch == '"':
inc(pos) # skip '"'
break
if ch in {'\c', '\L', lexbase.EndOfFile}:
@ -278,7 +279,7 @@ proc rawGetTok(c: var TCfgParser, tok: var TToken) =
tok.kind = tkBracketRi
Inc(c.bufpos)
tok.literal = "]"
of '\"':
of '"':
getString(c, tok, false)
of lexbase.EndOfFile:
tok.kind = tkEof
@ -351,7 +352,7 @@ proc next*(c: var TCfgParser): TCfgEvent {.rtl, extern: "npc$1".} =
rawGetTok(c, c.tok)
else:
result.kind = cfgError
result.msg = errorStr(c, "\']\' expected, but found: " & c.tok.literal)
result.msg = errorStr(c, "']' expected, but found: " & c.tok.literal)
of tkInvalid, tkEquals, tkColon, tkBracketRi:
result.kind = cfgError
result.msg = errorStr(c, "invalid token: " & c.tok.literal)

View file

@ -131,6 +131,10 @@ proc close*(my: var TXmlParser) {.inline.} =
## closes the parser `my` and its associated input stream.
lexbase.close(my)
proc kind*(my: TXmlParser): TXmlEventKind {.inline.} =
## returns the current event type for the XML parser
return my.kind
proc charData*(my: TXmlParser): string {.inline.} =
## returns the character data for the events: ``xmlCharData``,
## ``xmlWhitespace``, ``xmlComment``, ``xmlCData``, ``xmlSpecial``
@ -138,10 +142,6 @@ proc charData*(my: TXmlParser): string {.inline.} =
xmlSpecial})
return my.a
proc kind*(my: TXmlParser): TXmlEventKind {.inline.} =
## returns the current event type for the XML parser
return my.kind
proc elementName*(my: TXmlParser): string {.inline.} =
## returns the element name for the events: ``xmlElementStart``,
## ``xmlElementEnd``, ``xmlElementOpen``
@ -173,6 +173,16 @@ proc PIRest*(my: TXmlParser): string {.inline.} =
assert(my.kind == xmlPI)
return my.b
proc rawData*(my: TXmlParser): string {.inline.} =
## returns the underlying 'data' string by reference.
## This is only used for speed hacks.
shallowCopy(result, my.a)
proc rawData2*(my: TXmlParser): string {.inline.} =
## returns the underlying second 'data' string by reference.
## This is only used for speed hacks.
shallowCopy(result, my.b)
proc getColumn*(my: TXmlParser): int {.inline.} =
## get the current column the parser has arrived at.
result = getColNumber(my, my.bufPos)
@ -439,6 +449,7 @@ proc parseTag(my: var TXmlParser) =
if my.buf[my.bufpos] == '/' and my.buf[my.bufpos+1] == '>':
inc(my.bufpos, 2)
my.state = stateEmptyElementTag
my.c = nil
elif my.buf[my.bufpos] == '>':
inc(my.bufpos)
else:

View file

@ -82,7 +82,7 @@ type
of pkChar, pkGreedyRepChar: ch: char
of pkCharChoice, pkGreedyRepSet: charChoice: ref set[char]
of pkNonTerminal: nt: PNonTerminal
of pkBackRef..pkBackRefIgnoreStyle: index: range[1..MaxSubpatterns]
of pkBackRef..pkBackRefIgnoreStyle: index: range[0..MaxSubpatterns]
else: sons: seq[TNode]
PNonTerminal* = ref TNonTerminal
@ -870,7 +870,6 @@ template `=~`*(s: string, pattern: TPeg): bool =
bind maxSubpatterns
when not definedInScope(matches):
var matches {.inject.}: array[0..maxSubpatterns-1, string]
{.warning: "injected 'matches' might be affected by new scoping rules in 0.9.4".}
match(s, pattern, matches)
# ------------------------- more string handling ------------------------------

View file

@ -36,7 +36,7 @@ proc open*(host = "localhost", port = 6379.TPort): TRedis =
## Opens a connection to the redis server.
result.socket = socket(buffered = false)
if result.socket == InvalidSocket:
OSError()
OSError(OSLastError())
result.socket.connect(host, port)
proc raiseInvalidReply(expected, got: char) =
@ -50,34 +50,31 @@ proc raiseNoOK(status: string) =
proc parseStatus(r: TRedis): TRedisStatus =
var line = ""
if r.socket.recvLine(line):
if line == "":
raise newException(ERedis, "Server closed connection prematurely")
r.socket.readLine(line)
if line == "":
raise newException(ERedis, "Server closed connection prematurely")
if line[0] == '-':
raise newException(ERedis, strip(line))
if line[0] != '+':
raiseInvalidReply('+', line[0])
if line[0] == '-':
raise newException(ERedis, strip(line))
if line[0] != '+':
raiseInvalidReply('+', line[0])
return line.substr(1) # Strip '+'
else:
OSError()
return line.substr(1) # Strip '+'
proc parseInteger(r: TRedis): TRedisInteger =
var line = ""
if r.socket.recvLine(line):
if line == "":
raise newException(ERedis, "Server closed connection prematurely")
r.socket.readLine(line)
if line == "":
raise newException(ERedis, "Server closed connection prematurely")
if line[0] == '-':
raise newException(ERedis, strip(line))
if line[0] != ':':
raiseInvalidReply(':', line[0])
# Strip ':'
if parseBiggestInt(line, result, 1) == 0:
raise newException(EInvalidReply, "Unable to parse integer.")
else: OSError()
if line[0] == '-':
raise newException(ERedis, strip(line))
if line[0] != ':':
raiseInvalidReply(':', line[0])
# Strip ':'
if parseBiggestInt(line, result, 1) == 0:
raise newException(EInvalidReply, "Unable to parse integer.")
proc recv(sock: TSocket, size: int): TaintedString =
result = newString(size).TaintedString
@ -86,8 +83,7 @@ proc recv(sock: TSocket, size: int): TaintedString =
proc parseBulk(r: TRedis, allowMBNil = False): TRedisString =
var line = ""
if not r.socket.recvLine(line.TaintedString):
raise newException(EInvalidReply, "recvLine failed")
r.socket.readLine(line.TaintedString)
# Error.
if line[0] == '-':
@ -110,8 +106,7 @@ proc parseBulk(r: TRedis, allowMBNil = False): TRedisString =
proc parseMultiBulk(r: TRedis): TRedisList =
var line = TaintedString""
if not r.socket.recvLine(line):
raise newException(EInvalidReply, "recvLine failed")
r.socket.readLine(line)
if line.string[0] != '*':
raiseInvalidReply('*', line.string[0])
@ -848,10 +843,8 @@ proc shutdown*(r: TRedis) =
## Synchronously save the dataset to disk and then shut down the server
r.sendCommand("SHUTDOWN")
var s = "".TaintedString
if r.socket.recvLine(s):
if s.string.len != 0: raise newException(ERedis, s.string)
else:
OSError()
r.socket.readLine(s)
if s.string.len != 0: raise newException(ERedis, s.string)
proc slaveof*(r: TRedis, host: string, port: string) =
## Make the server a slave of another instance, or promote it as master

View file

@ -175,6 +175,15 @@ proc recvBufferAsync(client: PAsyncClient, L: int): TReadLineResult =
if ret == L:
return ReadFullLine
proc checkCloseSocket(client: PAsyncClient) =
if not client.c.isClosed:
if client.c.isSendDataBuffered:
client.c.setHandleWrite do (s: PAsyncSocket):
if not s.isClosed and not s.isSendDataBuffered:
s.close()
s.delHandleWrite()
else: client.c.close()
proc handleClientRead(client: PAsyncClient, s: PAsyncScgiState) =
case client.mode
of ClientReadChar:
@ -206,7 +215,7 @@ proc handleClientRead(client: PAsyncClient, s: PAsyncScgiState) =
client.mode = ClientReadContent
else:
s.handleRequest(client.c, client.input, client.headers)
if not client.c.isClosed: client.c.close()
checkCloseSocket(client)
of ReadPartialLine, ReadDisconnected, ReadNone: return
of ClientReadContent:
let L = parseInt(client.headers["CONTENT_LENGTH"])-client.input.len
@ -215,11 +224,11 @@ proc handleClientRead(client: PAsyncClient, s: PAsyncScgiState) =
case ret
of ReadFullLine:
s.handleRequest(client.c, client.input, client.headers)
if not client.c.isClosed: client.c.close()
checkCloseSocket(client)
of ReadPartialLine, ReadDisconnected, ReadNone: return
else:
s.handleRequest(client.c, client.input, client.headers)
if not client.c.isClosed: client.c.close()
checkCloseSocket(client)
proc handleAccept(sock: PAsyncSocket, s: PAsyncScgiState) =
var client: PAsyncSocket

View file

@ -231,7 +231,7 @@ when defined(ssl):
if err == 0:
raise newException(ESSL, "No error reported.")
if err == -1:
OSError()
OSError(OSLastError())
var errStr = ErrErrorString(err, nil)
raise newException(ESSL, $errStr)
@ -347,24 +347,23 @@ proc SocketError*(socket: TSocket, err: int = -1, async = false) =
else: SSLError("Unknown Error")
if err == -1 and not (when defined(ssl): socket.isSSL else: false):
let lastError = OSLastError()
if async:
when defined(windows):
# TODO: Test on Windows
var err = WSAGetLastError()
if err == WSAEWOULDBLOCK:
if lastError.int32 == WSAEWOULDBLOCK:
return
else: OSError()
else: OSError(lastError)
else:
if errno == EAGAIN or errno == EWOULDBLOCK:
if lastError.int32 == EAGAIN or lastError.int32 == EWOULDBLOCK:
return
else: OSError()
else: OSError()
else: OSError(lastError)
else: OSError(lastError)
proc listen*(socket: TSocket, backlog = SOMAXCONN) {.tags: [FReadIO].} =
## Marks ``socket`` as accepting connections.
## ``Backlog`` specifies the maximum length of the
## queue of pending connections.
if listen(socket.fd, cint(backlog)) < 0'i32: OSError()
if listen(socket.fd, cint(backlog)) < 0'i32: OSError(OSLastError())
proc invalidIp4(s: string) {.noreturn, noinline.} =
raise newException(EInvalidValue, "invalid ip4 address: " & s)
@ -403,7 +402,7 @@ template gaiNim(a, p, h, list: expr): stmt =
var gaiResult = getAddrInfo(a, $p, addr(h), list)
if gaiResult != 0'i32:
when defined(windows):
OSError()
OSError(OSLastError())
else:
OSError($gai_strerror(gaiResult))
@ -423,7 +422,7 @@ proc bindAddr*(socket: TSocket, port = TPort(0), address = "") {.
name.sin_addr.s_addr = sockets.htonl(INADDR_ANY)
if bindSocket(socket.fd, cast[ptr TSockAddr](addr(name)),
sizeof(name).TSockLen) < 0'i32:
OSError()
OSError(OSLastError())
else:
var hints: TAddrInfo
var aiList: ptr TAddrInfo = nil
@ -432,21 +431,7 @@ proc bindAddr*(socket: TSocket, port = TPort(0), address = "") {.
hints.ai_protocol = toInt(IPPROTO_TCP)
gaiNim(address, port, hints, aiList)
if bindSocket(socket.fd, aiList.ai_addr, aiList.ai_addrLen.TSockLen) < 0'i32:
OSError()
when false:
proc bindAddr*(socket: TSocket, port = TPort(0)) =
## binds a port number to a socket.
var name: Tsockaddr_in
when defined(Windows):
name.sin_family = int16(ord(AF_INET))
else:
name.sin_family = posix.AF_INET
name.sin_port = sockets.htons(int16(port))
name.sin_addr.s_addr = sockets.htonl(INADDR_ANY)
if bindSocket(cint(socket), cast[ptr TSockAddr](addr(name)),
sizeof(name).TSockLen) < 0'i32:
OSError()
OSError(OSLastError())
proc getSockName*(socket: TSocket): TPort =
## returns the socket's associated port number.
@ -460,7 +445,7 @@ proc getSockName*(socket: TSocket): TPort =
var namelen = sizeof(name).TSockLen
if getsockname(socket.fd, cast[ptr TSockAddr](addr(name)),
addr(namelen)) == -1'i32:
OSError()
OSError(OSLastError())
result = TPort(sockets.ntohs(name.sin_port))
template acceptAddrPlain(noClientRet, successRet: expr,
@ -472,26 +457,25 @@ template acceptAddrPlain(noClientRet, successRet: expr,
addr(addrLen))
if sock < 0:
# TODO: Test on Windows.
let err = OSLastError()
when defined(windows):
var err = WSAGetLastError()
if err == WSAEINPROGRESS:
if err.int32 == WSAEINPROGRESS:
client = InvalidSocket
address = ""
when noClientRet.int == -1:
return
else:
return noClientRet
else: OSError()
else: OSError(err)
else:
if errno == EAGAIN or errno == EWOULDBLOCK:
if err.int32 == EAGAIN or err.int32 == EWOULDBLOCK:
client = InvalidSocket
address = ""
when noClientRet.int == -1:
return
else:
return noClientRet
else: OSError()
else: OSError(err)
else:
client.fd = sock
client.isBuffered = server.isBuffered
@ -644,7 +628,7 @@ proc getServByName*(name, proto: string): TServent {.tags: [FReadIO].} =
var s = winlean.getservbyname(name, proto)
else:
var s = posix.getservbyname(name, proto)
if s == nil: OSError()
if s == nil: OSError(OSLastError())
result.name = $s.s_name
result.aliases = cstringArrayToSeq(s.s_aliases)
result.port = TPort(s.s_port)
@ -656,7 +640,7 @@ proc getServByPort*(port: TPort, proto: string): TServent {.tags: [FReadIO].} =
var s = winlean.getservbyport(ze(int16(port)).cint, proto)
else:
var s = posix.getservbyport(ze(int16(port)).cint, proto)
if s == nil: OSError()
if s == nil: OSError(OSLastError())
result.name = $s.s_name
result.aliases = cstringArrayToSeq(s.s_aliases)
result.port = TPort(s.s_port)
@ -670,7 +654,7 @@ proc getHostByAddr*(ip: string): THostEnt {.tags: [FReadIO].} =
when defined(windows):
var s = winlean.gethostbyaddr(addr(myaddr), sizeof(myaddr).cuint,
cint(sockets.AF_INET))
if s == nil: OSError()
if s == nil: OSError(OSLastError())
else:
var s = posix.gethostbyaddr(addr(myaddr), sizeof(myaddr).TSockLen,
cint(posix.AF_INET))
@ -687,7 +671,7 @@ proc getHostByAddr*(ip: string): THostEnt {.tags: [FReadIO].} =
elif s.h_addrtype == posix.AF_INET6:
result.addrType = AF_INET6
else:
OSError("unknown h_addrtype")
raise newException(EOS, "unknown h_addrtype")
result.addrList = cstringArrayToSeq(s.h_addr_list)
result.length = int(s.h_length)
@ -697,7 +681,7 @@ proc getHostByName*(name: string): THostEnt {.tags: [FReadIO].} =
var s = winlean.gethostbyname(name)
else:
var s = posix.gethostbyname(name)
if s == nil: OSError()
if s == nil: OSError(OSLastError())
result.name = $s.h_name
result.aliases = cstringArrayToSeq(s.h_aliases)
when defined(windows):
@ -708,7 +692,7 @@ proc getHostByName*(name: string): THostEnt {.tags: [FReadIO].} =
elif s.h_addrtype == posix.AF_INET6:
result.addrType = AF_INET6
else:
OSError("unknown h_addrtype")
raise newException(EOS, "unknown h_addrtype")
result.addrList = cstringArrayToSeq(s.h_addr_list)
result.length = int(s.h_length)
@ -719,7 +703,7 @@ proc getSockOptInt*(socket: TSocket, level, optname: int): int {.
var size = sizeof(res).TSockLen
if getsockopt(socket.fd, cint(level), cint(optname),
addr(res), addr(size)) < 0'i32:
OSError()
OSError(OSLastError())
result = int(res)
proc setSockOptInt*(socket: TSocket, level, optname, optval: int) {.
@ -728,7 +712,7 @@ proc setSockOptInt*(socket: TSocket, level, optname, optval: int) {.
var value = cint(optval)
if setsockopt(socket.fd, cint(level), cint(optname), addr(value),
sizeof(value).TSockLen) < 0'i32:
OSError()
OSError(OSLastError())
proc connect*(socket: TSocket, address: string, port = TPort(0),
af: TDomain = AF_INET) {.tags: [FReadIO].} =
@ -746,15 +730,17 @@ proc connect*(socket: TSocket, address: string, port = TPort(0),
gaiNim(address, port, hints, aiList)
# try all possibilities:
var success = false
var lastError: TOSErrorCode
var it = aiList
while it != nil:
if connect(socket.fd, it.ai_addr, it.ai_addrlen.TSockLen) == 0'i32:
success = true
break
else: lastError = OSLastError()
it = it.ai_next
freeaddrinfo(aiList)
if not success: OSError()
if not success: OSError(lastError)
when defined(ssl):
if socket.isSSL:
@ -807,6 +793,7 @@ proc connectAsync*(socket: TSocket, name: string, port = TPort(0),
gaiNim(name, port, hints, aiList)
# try all possibilities:
var success = false
var lastError: TOSErrorCode
var it = aiList
while it != nil:
var ret = connect(socket.fd, it.ai_addr, it.ai_addrlen.TSockLen)
@ -814,22 +801,21 @@ proc connectAsync*(socket: TSocket, name: string, port = TPort(0),
success = true
break
else:
# TODO: Test on Windows.
lastError = OSLastError()
when defined(windows):
var err = WSAGetLastError()
# Windows EINTR doesn't behave same as POSIX.
if err == WSAEWOULDBLOCK:
if lastError.int32 == WSAEWOULDBLOCK:
success = true
break
else:
if errno == EINTR or errno == EINPROGRESS:
if lastError.int32 == EINTR or lastError.int32 == EINPROGRESS:
success = true
break
it = it.ai_next
freeaddrinfo(aiList)
if not success: OSError()
if not success: OSError(lastError)
when defined(ssl):
if socket.isSSL:
socket.sslNoHandshake = true
@ -1110,7 +1096,7 @@ proc waitFor(socket: TSocket, waited: var float, timeout, size: int,
var s = @[socket]
var startTime = epochTime()
let selRet = select(s, timeout - int(waited * 1000.0))
if selRet < 0: OSError()
if selRet < 0: OSError(OSLastError())
if selRet != 1:
raise newException(ETimeout, "Call to '" & funcName & "' timed out.")
waited += (epochTime() - startTime)
@ -1259,14 +1245,14 @@ proc readLine*(socket: TSocket, line: var TaintedString, timeout = -1) {.
var c: char
discard waitFor(socket, waited, timeout, 1, "readLine")
var n = recv(socket, addr(c), 1)
if n < 0: OSError()
if n < 0: OSError(OSLastError())
elif n == 0: return
if c == '\r':
discard waitFor(socket, waited, timeout, 1, "readLine")
n = peekChar(socket, c)
if n > 0 and c == '\L':
discard recv(socket, addr(c), 1)
elif n <= 0: OSError()
elif n <= 0: OSError(OSLastError())
addNlIfEmpty()
return
elif c == '\L':
@ -1326,6 +1312,7 @@ proc readLineAsync*(socket: TSocket,
while true:
var c: char
var n = recv(socket, addr(c), 1)
#echo(n)
if n < 0:
if line.len == 0: errorOrNone else: return ReadPartialLine
elif n == 0:
@ -1352,7 +1339,7 @@ proc recv*(socket: TSocket): TaintedString {.tags: [FReadIO], deprecated.} =
var pos = 0
while true:
var bytesRead = recv(socket, addr(string(result)[pos]), bufSize-1)
if bytesRead == -1: OSError()
if bytesRead == -1: OSError(OSLastError())
setLen(result.string, pos + bytesRead)
if bytesRead != bufSize-1: break
# increase capacity:
@ -1364,7 +1351,7 @@ proc recv*(socket: TSocket): TaintedString {.tags: [FReadIO], deprecated.} =
while true:
var bytesRead = recv(socket, cstring(buf), bufSize-1)
# Error
if bytesRead == -1: OSError()
if bytesRead == -1: OSError(OSLastError())
buf[bytesRead] = '\0' # might not be necessary
setLen(buf, bytesRead)
@ -1421,16 +1408,15 @@ proc recvAsync*(socket: TSocket, s: var TaintedString): bool {.
else: SSLError("Unknown Error")
if bytesRead == -1 and not (when defined(ssl): socket.isSSL else: false):
let err = OSLastError()
when defined(windows):
# TODO: Test on Windows
var err = WSAGetLastError()
if err == WSAEWOULDBLOCK:
if err.int32 == WSAEWOULDBLOCK:
return False
else: OSError()
else: OSError(err)
else:
if errno == EAGAIN or errno == EWOULDBLOCK:
if err.int32 == EAGAIN or err.int32 == EWOULDBLOCK:
return False
else: OSError()
else: OSError(err)
setLen(s.string, pos + bytesRead)
if bytesRead != bufSize-1: break
@ -1475,16 +1461,15 @@ proc recvFromAsync*(socket: TSocket, data: var String, length: int,
result = true
var callRes = recvFrom(socket, data, length, address, port, flags)
if callRes < 0:
let err = OSLastError()
when defined(windows):
# TODO: Test on Windows
var err = WSAGetLastError()
if err == WSAEWOULDBLOCK:
if err.int32 == WSAEWOULDBLOCK:
return False
else: OSError()
else: OSError(err)
else:
if errno == EAGAIN or errno == EWOULDBLOCK:
if err.int32 == EAGAIN or err.int32 == EWOULDBLOCK:
return False
else: OSError()
else: OSError(err)
proc skip*(socket: TSocket) {.tags: [FReadIO], deprecated.} =
## skips all the data that is pending for the socket
@ -1531,7 +1516,7 @@ proc send*(socket: TSocket, data: string) {.tags: [FWriteIO].} =
if socket.isSSL:
SSLError()
OSError()
OSError(OSLastError())
proc sendAsync*(socket: TSocket, data: string): int {.tags: [FWriteIO].} =
## sends data to a non-blocking socket.
@ -1561,16 +1546,15 @@ proc sendAsync*(socket: TSocket, data: string): int {.tags: [FWriteIO].} =
else:
return
if result == -1:
let err = OSLastError()
when defined(windows):
var err = WSAGetLastError()
# TODO: Test on windows.
if err == WSAEINPROGRESS:
if err.int32 == WSAEINPROGRESS:
return 0
else: OSError()
else: OSError(err)
else:
if errno == EAGAIN or errno == EWOULDBLOCK:
if err.int32 == EAGAIN or err.int32 == EWOULDBLOCK:
return 0
else: OSError()
else: OSError(err)
proc trySend*(socket: TSocket, data: string): bool {.tags: [FWriteIO].} =
@ -1626,15 +1610,15 @@ proc setBlocking(s: TSocket, blocking: bool) =
when defined(Windows):
var mode = clong(ord(not blocking)) # 1 for non-blocking, 0 for blocking
if ioctlsocket(TWinSocket(s.fd), FIONBIO, addr(mode)) == -1:
OSError()
OSError(OSLastError())
else: # BSD sockets
var x: int = fcntl(s.fd, F_GETFL, 0)
if x == -1:
OSError()
OSError(OSLastError())
else:
var mode = if blocking: x and not O_NONBLOCK else: x or O_NONBLOCK
if fcntl(s.fd, F_SETFL, mode) == -1:
OSError()
OSError(OSLastError())
s.nonblocking = not blocking
proc connect*(socket: TSocket, address: string, port = TPort(0), timeout: int,
@ -1665,6 +1649,6 @@ proc getFD*(socket: TSocket): cint = return socket.fd
when defined(Windows):
var wsa: TWSADATA
if WSAStartup(0x0101'i16, wsa) != 0: OSError()
if WSAStartup(0x0101'i16, addr wsa) != 0: OSError(OSLastError())

View file

@ -1,312 +1,310 @@
#
#
# Nimrod's Runtime Library
# (c) Copyright 2012 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## This module contains a few procedures to control the *terminal*
## (also called *console*). On UNIX, the implementation simply uses ANSI escape
## sequences and does not depend on any other module, on Windows it uses the
## Windows API.
## Changing the style is permanent even after program termination! Use the
## code ``system.addQuitProc(resetAttributes)`` to restore the defaults.
import macros
when defined(windows):
import windows, os
var
conHandle: THandle
# = createFile("CONOUT$", GENERIC_WRITE, 0, nil, OPEN_ALWAYS, 0, 0)
block:
var hTemp = GetStdHandle(STD_OUTPUT_HANDLE)
if DuplicateHandle(GetCurrentProcess(), hTemp, GetCurrentProcess(),
addr(conHandle), 0, 1, DUPLICATE_SAME_ACCESS) == 0:
OSError()
proc getCursorPos(): tuple [x,y: int] =
var c: TCONSOLE_SCREEN_BUFFER_INFO
if GetConsoleScreenBufferInfo(conHandle, addr(c)) == 0: OSError()
return (int(c.dwCursorPosition.x), int(c.dwCursorPosition.y))
proc getAttributes(): int16 =
var c: TCONSOLE_SCREEN_BUFFER_INFO
# workaround Windows bugs: try several times
if GetConsoleScreenBufferInfo(conHandle, addr(c)) != 0:
return c.wAttributes
else:
OSError()
return 0x70'i16 # ERROR: return white background, black text
var
oldAttr = getAttributes()
proc setCursorPos*(x, y: int) =
## sets the terminal's cursor to the (x,y) position. (0,0) is the
## upper left of the screen.
when defined(windows):
var c: TCoord
c.x = int16(x)
c.y = int16(y)
if SetConsoleCursorPosition(conHandle, c) == 0: OSError()
else:
stdout.write("\e[" & $y & ';' & $x & 'f')
proc setCursorXPos*(x: int) =
## sets the terminal's cursor to the x position. The y position is
## not changed.
when defined(windows):
var scrbuf: TCONSOLE_SCREEN_BUFFER_INFO
var hStdout = conHandle
if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: OSError()
var origin = scrbuf.dwCursorPosition
origin.x = int16(x)
if SetConsoleCursorPosition(conHandle, origin) == 0: OSError()
else:
stdout.write("\e[" & $x & 'G')
when defined(windows):
proc setCursorYPos*(y: int) =
## sets the terminal's cursor to the y position. The x position is
## not changed. **Warning**: This is not supported on UNIX!
when defined(windows):
var scrbuf: TCONSOLE_SCREEN_BUFFER_INFO
var hStdout = conHandle
if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: OSError()
var origin = scrbuf.dwCursorPosition
origin.y = int16(y)
if SetConsoleCursorPosition(conHandle, origin) == 0: OSError()
else:
nil
proc CursorUp*(count=1) =
## Moves the cursor up by `count` rows.
when defined(windows):
var p = getCursorPos()
dec(p.y, count)
setCursorPos(p.x, p.y)
else:
stdout.write("\e[" & $count & 'A')
proc CursorDown*(count=1) =
## Moves the cursor down by `count` rows.
when defined(windows):
var p = getCursorPos()
inc(p.y, count)
setCursorPos(p.x, p.y)
else:
stdout.write("\e[" & $count & 'B')
proc CursorForward*(count=1) =
## Moves the cursor forward by `count` columns.
when defined(windows):
var p = getCursorPos()
inc(p.x, count)
setCursorPos(p.x, p.y)
else:
stdout.write("\e[" & $count & 'C')
proc CursorBackward*(count=1) =
## Moves the cursor backward by `count` columns.
when defined(windows):
var p = getCursorPos()
dec(p.x, count)
setCursorPos(p.x, p.y)
else:
stdout.write("\e[" & $count & 'D')
when true:
nil
else:
proc EraseLineEnd* =
## Erases from the current cursor position to the end of the current line.
when defined(windows):
nil
else:
stdout.write("\e[K")
proc EraseLineStart* =
## Erases from the current cursor position to the start of the current line.
when defined(windows):
nil
else:
stdout.write("\e[1K")
proc EraseDown* =
## Erases the screen from the current line down to the bottom of the screen.
when defined(windows):
nil
else:
stdout.write("\e[J")
proc EraseUp* =
## Erases the screen from the current line up to the top of the screen.
when defined(windows):
nil
else:
stdout.write("\e[1J")
proc EraseLine* =
## Erases the entire current line.
when defined(windows):
var scrbuf: TCONSOLE_SCREEN_BUFFER_INFO
var numwrote: DWORD
var hStdout = conHandle
if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: OSError()
var origin = scrbuf.dwCursorPosition
origin.x = 0'i16
if SetConsoleCursorPosition(conHandle, origin) == 0: OSError()
var ht = scrbuf.dwSize.Y - origin.Y
var wt = scrbuf.dwSize.X - origin.X
if FillConsoleOutputCharacter(hStdout,' ', ht*wt,
origin, addr(numwrote)) == 0:
OSError()
if FillConsoleOutputAttribute(hStdout, scrbuf.wAttributes, ht * wt,
scrbuf.dwCursorPosition, addr(numwrote)) == 0:
OSError()
else:
stdout.write("\e[2K")
setCursorXPos(0)
proc EraseScreen* =
## Erases the screen with the background colour and moves the cursor to home.
when defined(windows):
var scrbuf: TCONSOLE_SCREEN_BUFFER_INFO
var numwrote: DWORD
var origin: TCoord # is inititalized to 0, 0
var hStdout = conHandle
if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: OSError()
if FillConsoleOutputCharacter(hStdout, ' ', scrbuf.dwSize.X*scrbuf.dwSize.Y,
origin, addr(numwrote)) == 0:
OSError()
if FillConsoleOutputAttribute(hStdout, scrbuf.wAttributes,
scrbuf.dwSize.X * scrbuf.dwSize.Y,
origin, addr(numwrote)) == 0:
OSError()
setCursorXPos(0)
else:
stdout.write("\e[2J")
proc ResetAttributes* {.noconv.} =
## resets all attributes; it is advisable to register this as a quit proc
## with ``system.addQuitProc(resetAttributes)``.
when defined(windows):
discard SetConsoleTextAttribute(conHandle, oldAttr)
else:
stdout.write("\e[0m")
type
TStyle* = enum ## different styles for text output
styleBright = 1, ## bright text
styleDim, ## dim text
styleUnknown, ## unknown
styleUnderscore = 4, ## underscored text
styleBlink, ## blinking/bold text
styleReverse = 7, ## unknown
styleHidden ## hidden text
when not defined(windows):
var
# XXX: These better be thread-local
gFG = 0
gBG = 0
proc setStyle*(style: set[TStyle]) =
## sets the terminal style
when defined(windows):
var a = 0'i16
if styleBright in style: a = a or int16(FOREGROUND_INTENSITY)
if styleBlink in style: a = a or int16(BACKGROUND_INTENSITY)
if styleReverse in style: a = a or 0x4000'i16 # COMMON_LVB_REVERSE_VIDEO
if styleUnderscore in style: a = a or 0x8000'i16 # COMMON_LVB_UNDERSCORE
discard SetConsoleTextAttribute(conHandle, a)
else:
for s in items(style):
stdout.write("\e[" & $ord(s) & 'm')
proc WriteStyled*(txt: string, style: set[TStyle] = {styleBright}) =
## writes the text `txt` in a given `style`.
when defined(windows):
var old = getAttributes()
setStyle(style)
stdout.write(txt)
discard SetConsoleTextAttribute(conHandle, old)
else:
setStyle(style)
stdout.write(txt)
resetAttributes()
if gFG != 0:
stdout.write("\e[" & $ord(gFG) & 'm')
if gBG != 0:
stdout.write("\e[" & $ord(gBG) & 'm')
type
TForegroundColor* = enum ## terminal's foreground colors
fgBlack = 30, ## black
fgRed, ## red
fgGreen, ## green
fgYellow, ## yellow
fgBlue, ## blue
fgMagenta, ## magenta
fgCyan, ## cyan
fgWhite ## white
TBackgroundColor* = enum ## terminal's background colors
bgBlack = 40, ## black
bgRed, ## red
bgGreen, ## green
bgYellow, ## yellow
bgBlue, ## blue
bgMagenta, ## magenta
bgCyan, ## cyan
bgWhite ## white
proc setForegroundColor*(fg: TForegroundColor, bright=false) =
## sets the terminal's foreground color
when defined(windows):
var old = getAttributes() and not 0x0007
if bright:
old = old or FOREGROUND_INTENSITY
const lookup: array [TForegroundColor, int] = [
0,
(FOREGROUND_RED),
(FOREGROUND_GREEN),
(FOREGROUND_RED or FOREGROUND_GREEN),
(FOREGROUND_BLUE),
(FOREGROUND_RED or FOREGROUND_BLUE),
(FOREGROUND_BLUE or FOREGROUND_GREEN),
(FOREGROUND_BLUE or FOREGROUND_GREEN or FOREGROUND_RED)]
discard SetConsoleTextAttribute(conHandle, toU16(old or lookup[fg]))
else:
gFG = ord(fg)
if bright: inc(gFG, 60)
stdout.write("\e[" & $gFG & 'm')
proc setBackgroundColor*(bg: TBackgroundColor, bright=false) =
## sets the terminal's background color
when defined(windows):
var old = getAttributes() and not 0x0070
if bright:
old = old or BACKGROUND_INTENSITY
const lookup: array [TBackgroundColor, int] = [
0,
(BACKGROUND_RED),
(BACKGROUND_GREEN),
(BACKGROUND_RED or BACKGROUND_GREEN),
(BACKGROUND_BLUE),
(BACKGROUND_RED or BACKGROUND_BLUE),
(BACKGROUND_BLUE or BACKGROUND_GREEN),
(BACKGROUND_BLUE or BACKGROUND_GREEN or BACKGROUND_RED)]
discard SetConsoleTextAttribute(conHandle, toU16(old or lookup[bg]))
else:
gBG = ord(bg)
if bright: inc(gBG, 60)
stdout.write("\e[" & $gBG & 'm')
#
#
# Nimrod's Runtime Library
# (c) Copyright 2012 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## This module contains a few procedures to control the *terminal*
## (also called *console*). On UNIX, the implementation simply uses ANSI escape
## sequences and does not depend on any other module, on Windows it uses the
## Windows API.
## Changing the style is permanent even after program termination! Use the
## code ``system.addQuitProc(resetAttributes)`` to restore the defaults.
import macros
when defined(windows):
import windows, os
var
conHandle: THandle
# = createFile("CONOUT$", GENERIC_WRITE, 0, nil, OPEN_ALWAYS, 0, 0)
block:
var hTemp = GetStdHandle(STD_OUTPUT_HANDLE)
if DuplicateHandle(GetCurrentProcess(), hTemp, GetCurrentProcess(),
addr(conHandle), 0, 1, DUPLICATE_SAME_ACCESS) == 0:
OSError(OSLastError())
proc getCursorPos(): tuple [x,y: int] =
var c: TCONSOLE_SCREEN_BUFFER_INFO
if GetConsoleScreenBufferInfo(conHandle, addr(c)) == 0: OSError(OSLastError())
return (int(c.dwCursorPosition.x), int(c.dwCursorPosition.y))
proc getAttributes(): int16 =
var c: TCONSOLE_SCREEN_BUFFER_INFO
# workaround Windows bugs: try several times
if GetConsoleScreenBufferInfo(conHandle, addr(c)) != 0:
return c.wAttributes
return 0x70'i16 # ERROR: return white background, black text
var
oldAttr = getAttributes()
proc setCursorPos*(x, y: int) =
## sets the terminal's cursor to the (x,y) position. (0,0) is the
## upper left of the screen.
when defined(windows):
var c: TCoord
c.x = int16(x)
c.y = int16(y)
if SetConsoleCursorPosition(conHandle, c) == 0: OSError(OSLastError())
else:
stdout.write("\e[" & $y & ';' & $x & 'f')
proc setCursorXPos*(x: int) =
## sets the terminal's cursor to the x position. The y position is
## not changed.
when defined(windows):
var scrbuf: TCONSOLE_SCREEN_BUFFER_INFO
var hStdout = conHandle
if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: OSError(OSLastError())
var origin = scrbuf.dwCursorPosition
origin.x = int16(x)
if SetConsoleCursorPosition(conHandle, origin) == 0: OSError(OSLastError())
else:
stdout.write("\e[" & $x & 'G')
when defined(windows):
proc setCursorYPos*(y: int) =
## sets the terminal's cursor to the y position. The x position is
## not changed. **Warning**: This is not supported on UNIX!
when defined(windows):
var scrbuf: TCONSOLE_SCREEN_BUFFER_INFO
var hStdout = conHandle
if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: OSError(OSLastError())
var origin = scrbuf.dwCursorPosition
origin.y = int16(y)
if SetConsoleCursorPosition(conHandle, origin) == 0: OSError(OSLastError())
else:
nil
proc CursorUp*(count=1) =
## Moves the cursor up by `count` rows.
when defined(windows):
var p = getCursorPos()
dec(p.y, count)
setCursorPos(p.x, p.y)
else:
stdout.write("\e[" & $count & 'A')
proc CursorDown*(count=1) =
## Moves the cursor down by `count` rows.
when defined(windows):
var p = getCursorPos()
inc(p.y, count)
setCursorPos(p.x, p.y)
else:
stdout.write("\e[" & $count & 'B')
proc CursorForward*(count=1) =
## Moves the cursor forward by `count` columns.
when defined(windows):
var p = getCursorPos()
inc(p.x, count)
setCursorPos(p.x, p.y)
else:
stdout.write("\e[" & $count & 'C')
proc CursorBackward*(count=1) =
## Moves the cursor backward by `count` columns.
when defined(windows):
var p = getCursorPos()
dec(p.x, count)
setCursorPos(p.x, p.y)
else:
stdout.write("\e[" & $count & 'D')
when true:
nil
else:
proc EraseLineEnd* =
## Erases from the current cursor position to the end of the current line.
when defined(windows):
nil
else:
stdout.write("\e[K")
proc EraseLineStart* =
## Erases from the current cursor position to the start of the current line.
when defined(windows):
nil
else:
stdout.write("\e[1K")
proc EraseDown* =
## Erases the screen from the current line down to the bottom of the screen.
when defined(windows):
nil
else:
stdout.write("\e[J")
proc EraseUp* =
## Erases the screen from the current line up to the top of the screen.
when defined(windows):
nil
else:
stdout.write("\e[1J")
proc EraseLine* =
## Erases the entire current line.
when defined(windows):
var scrbuf: TCONSOLE_SCREEN_BUFFER_INFO
var numwrote: DWORD
var hStdout = conHandle
if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: OSError(OSLastError())
var origin = scrbuf.dwCursorPosition
origin.x = 0'i16
if SetConsoleCursorPosition(conHandle, origin) == 0: OSError(OSLastError())
var ht = scrbuf.dwSize.Y - origin.Y
var wt = scrbuf.dwSize.X - origin.X
if FillConsoleOutputCharacter(hStdout,' ', ht*wt,
origin, addr(numwrote)) == 0:
OSError(OSLastError())
if FillConsoleOutputAttribute(hStdout, scrbuf.wAttributes, ht * wt,
scrbuf.dwCursorPosition, addr(numwrote)) == 0:
OSError(OSLastError())
else:
stdout.write("\e[2K")
setCursorXPos(0)
proc EraseScreen* =
## Erases the screen with the background colour and moves the cursor to home.
when defined(windows):
var scrbuf: TCONSOLE_SCREEN_BUFFER_INFO
var numwrote: DWORD
var origin: TCoord # is inititalized to 0, 0
var hStdout = conHandle
if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: OSError(OSLastError())
if FillConsoleOutputCharacter(hStdout, ' ', scrbuf.dwSize.X*scrbuf.dwSize.Y,
origin, addr(numwrote)) == 0:
OSError(OSLastError())
if FillConsoleOutputAttribute(hStdout, scrbuf.wAttributes,
scrbuf.dwSize.X * scrbuf.dwSize.Y,
origin, addr(numwrote)) == 0:
OSError(OSLastError())
setCursorXPos(0)
else:
stdout.write("\e[2J")
proc ResetAttributes* {.noconv.} =
## resets all attributes; it is advisable to register this as a quit proc
## with ``system.addQuitProc(resetAttributes)``.
when defined(windows):
discard SetConsoleTextAttribute(conHandle, oldAttr)
else:
stdout.write("\e[0m")
type
TStyle* = enum ## different styles for text output
styleBright = 1, ## bright text
styleDim, ## dim text
styleUnknown, ## unknown
styleUnderscore = 4, ## underscored text
styleBlink, ## blinking/bold text
styleReverse = 7, ## unknown
styleHidden ## hidden text
when not defined(windows):
var
# XXX: These better be thread-local
gFG = 0
gBG = 0
proc setStyle*(style: set[TStyle]) =
## sets the terminal style
when defined(windows):
var a = 0'i16
if styleBright in style: a = a or int16(FOREGROUND_INTENSITY)
if styleBlink in style: a = a or int16(BACKGROUND_INTENSITY)
if styleReverse in style: a = a or 0x4000'i16 # COMMON_LVB_REVERSE_VIDEO
if styleUnderscore in style: a = a or 0x8000'i16 # COMMON_LVB_UNDERSCORE
discard SetConsoleTextAttribute(conHandle, a)
else:
for s in items(style):
stdout.write("\e[" & $ord(s) & 'm')
proc WriteStyled*(txt: string, style: set[TStyle] = {styleBright}) =
## writes the text `txt` in a given `style`.
when defined(windows):
var old = getAttributes()
setStyle(style)
stdout.write(txt)
discard SetConsoleTextAttribute(conHandle, old)
else:
setStyle(style)
stdout.write(txt)
resetAttributes()
if gFG != 0:
stdout.write("\e[" & $ord(gFG) & 'm')
if gBG != 0:
stdout.write("\e[" & $ord(gBG) & 'm')
type
TForegroundColor* = enum ## terminal's foreground colors
fgBlack = 30, ## black
fgRed, ## red
fgGreen, ## green
fgYellow, ## yellow
fgBlue, ## blue
fgMagenta, ## magenta
fgCyan, ## cyan
fgWhite ## white
TBackgroundColor* = enum ## terminal's background colors
bgBlack = 40, ## black
bgRed, ## red
bgGreen, ## green
bgYellow, ## yellow
bgBlue, ## blue
bgMagenta, ## magenta
bgCyan, ## cyan
bgWhite ## white
proc setForegroundColor*(fg: TForegroundColor, bright=false) =
## sets the terminal's foreground color
when defined(windows):
var old = getAttributes() and not 0x0007
if bright:
old = old or FOREGROUND_INTENSITY
const lookup: array [TForegroundColor, int] = [
0,
(FOREGROUND_RED),
(FOREGROUND_GREEN),
(FOREGROUND_RED or FOREGROUND_GREEN),
(FOREGROUND_BLUE),
(FOREGROUND_RED or FOREGROUND_BLUE),
(FOREGROUND_BLUE or FOREGROUND_GREEN),
(FOREGROUND_BLUE or FOREGROUND_GREEN or FOREGROUND_RED)]
discard SetConsoleTextAttribute(conHandle, toU16(old or lookup[fg]))
else:
gFG = ord(fg)
if bright: inc(gFG, 60)
stdout.write("\e[" & $gFG & 'm')
proc setBackgroundColor*(bg: TBackgroundColor, bright=false) =
## sets the terminal's background color
when defined(windows):
var old = getAttributes() and not 0x0070
if bright:
old = old or BACKGROUND_INTENSITY
const lookup: array [TBackgroundColor, int] = [
0,
(BACKGROUND_RED),
(BACKGROUND_GREEN),
(BACKGROUND_RED or BACKGROUND_GREEN),
(BACKGROUND_BLUE),
(BACKGROUND_RED or BACKGROUND_BLUE),
(BACKGROUND_BLUE or BACKGROUND_GREEN),
(BACKGROUND_BLUE or BACKGROUND_GREEN or BACKGROUND_RED)]
discard SetConsoleTextAttribute(conHandle, toU16(old or lookup[bg]))
else:
gBG = ord(bg)
if bright: inc(gBG, 60)
stdout.write("\e[" & $gBG & 'm')
proc isatty*(f: TFile): bool =
## returns true if `f` is associated with a terminal device.
@ -318,33 +316,33 @@ proc isatty*(f: TFile): bool =
importc: "_isatty", header: "<io.h>".}
result = isatty(fileHandle(f)) != 0'i32
proc styledEchoProcessArg(s: string) = write stdout, s
proc styledEchoProcessArg(style: TStyle) = setStyle({style})
proc styledEchoProcessArg(style: set[TStyle]) = setStyle style
proc styledEchoProcessArg(color: TForegroundColor) = setForeGroundColor color
proc styledEchoProcessArg(color: TBackgroundColor) = setBackGroundColor color
proc styledEchoProcessArg(s: string) = write stdout, s
proc styledEchoProcessArg(style: TStyle) = setStyle({style})
proc styledEchoProcessArg(style: set[TStyle]) = setStyle style
proc styledEchoProcessArg(color: TForegroundColor) = setForeGroundColor color
proc styledEchoProcessArg(color: TBackgroundColor) = setBackGroundColor color
macro styledEcho*(m: varargs[expr]): stmt =
## to be documented.
let m = callsite()
result = newNimNode(nnkStmtList)
for i in countup(1, m.len - 1):
result.add(newCall(bindSym"styledEchoProcessArg", m[i]))
result.add(newCall(bindSym"write", bindSym"stdout", newStrLitNode("\n")))
result.add(newCall(bindSym"resetAttributes"))
when isMainModule:
system.addQuitProc(resetAttributes)
write(stdout, "never mind")
eraseLine()
#setCursorPos(2, 2)
writeStyled("styled text ", {styleBright, styleBlink, styleUnderscore})
setBackGroundColor(bgCyan, true)
setForeGroundColor(fgBlue)
writeln(stdout, "ordinary text")
result = newNimNode(nnkStmtList)
for i in countup(1, m.len - 1):
result.add(newCall(bindSym"styledEchoProcessArg", m[i]))
result.add(newCall(bindSym"write", bindSym"stdout", newStrLitNode("\n")))
result.add(newCall(bindSym"resetAttributes"))
when isMainModule:
system.addQuitProc(resetAttributes)
write(stdout, "never mind")
eraseLine()
#setCursorPos(2, 2)
writeStyled("styled text ", {styleBright, styleBlink, styleUnderscore})
setBackGroundColor(bgCyan, true)
setForeGroundColor(fgBlue)
writeln(stdout, "ordinary text")
styledEcho("styled text ", {styleBright, styleBlink, styleUnderscore})

View file

@ -1,7 +1,7 @@
#
#
# Nimrod's Runtime Library
# (c) Copyright 2012 Andreas Rumpf
# (c) Copyright 2013 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
@ -338,24 +338,24 @@ when not defined(JS):
const
weekDays: array [0..6, TWeekDay] = [
dSun, dMon, dTue, dWed, dThu, dFri, dSat]
result.second = int(tm.second)
result.minute = int(tm.minute)
result.hour = int(tm.hour)
result.monthday = int(tm.monthday)
result.month = TMonth(tm.month)
result.year = tm.year + 1900'i32
result.weekday = weekDays[int(tm.weekDay)]
result.yearday = int(tm.yearday)
result.isDST = tm.isDST > 0
if local:
if result.isDST:
result.tzname = getTzname().DST
else:
result.tzname = getTzname().nonDST
else:
result.tzname = "UTC"
result.timezone = if local: getTimezone() else: 0
TTimeInfo(second: int(tm.second),
minute: int(tm.minute),
hour: int(tm.hour),
monthday: int(tm.monthday),
month: TMonth(tm.month),
year: tm.year + 1900'i32,
weekday: weekDays[int(tm.weekDay)],
yearday: int(tm.yearday),
isDST: tm.isDST > 0,
tzname: if local:
if tm.isDST > 0:
getTzname().DST
else:
getTzname().nonDST
else:
"UTC",
timezone: if local: getTimezone() else: 0
)
proc timeInfoToTM(t: TTimeInfo): structTM =
const

View file

@ -110,11 +110,9 @@ proc parseXml*(s: PStream, filename: string,
of xmlElementOpen, xmlElementStart:
result = parse(x, errors)
break
of xmlComment, xmlWhitespace: nil # just skip it
of xmlComment, xmlWhitespace, xmlSpecial: nil # just skip it
of xmlError:
errors.add(errorMsg(x))
of xmlSpecial:
errors.add(errorMsg(x, "<some_tag> expected"))
else:
errors.add(errorMsg(x, "<some_tag> expected"))
break

View file

@ -71,6 +71,16 @@ proc text*(n: PXmlNode): string {.inline.} =
assert n.k in {xnText, xnComment, xnCData, xnEntity}
result = n.fText
proc rawText*(n: PXmlNode): string {.inline.} =
## returns the underlying 'text' string by reference.
## This is only used for speed hacks.
shallowCopy(result, n.fText)
proc rawTag*(n: PXmlNode): string {.inline.} =
## returns the underlying 'tag' string by reference.
## This is only used for speed hacks.
shallowCopy(result, n.fTag)
proc innerText*(n: PXmlNode): string =
## gets the inner text of `n`. `n` has to be an ``xnElement`` node. Only
## ``xnText`` and ``xnEntity`` nodes are considered part of `n`'s inner text,

View file

@ -19,7 +19,7 @@ when defined(Windows):
OwningThread: int
LockSemaphore: int
Reserved: int32
TSysCond = THandle
proc InitSysLock(L: var TSysLock) {.stdcall, noSideEffect,

View file

@ -489,7 +489,7 @@ proc FD_SET*(Socket: TWinSocket, FDSet: var TFDSet) =
proc FD_ZERO*(FDSet: var TFDSet) =
FDSet.fd_count = 0
proc WSAStartup*(wVersionRequired: int16, WSData: var TWSAData): cint {.
proc WSAStartup*(wVersionRequired: int16, WSData: ptr TWSAData): cint {.
stdcall, importc: "WSAStartup", dynlib: ws2dll.}
proc getaddrinfo*(nodename, servname: cstring, hints: ptr TAddrInfo,

View file

@ -27,7 +27,7 @@ type
gshort* = cshort
glong* = clong
gint* = cint
gboolean* = bool
gboolean* = distinct gint
guchar* = char
gushort* = int16
gulong* = int
@ -173,6 +173,12 @@ type
TGBoxedFreeFunc* = proc (boxed: gpointer){.cdecl.}
PGsource = pointer # I don't know and don't care
converter gbool*(nimbool: bool): gboolean =
return ord(nimbool).gboolean
converter toBool*(gbool: gboolean): bool =
return int(gbool) == 1
const
G_TYPE_FUNDAMENTAL_SHIFT* = 2
G_TYPE_FUNDAMENTAL_MAX* = 255 shl G_TYPE_FUNDAMENTAL_SHIFT

View file

@ -2,6 +2,8 @@
import
glib2, atk, pango, gdk2pixbuf, gdk2
export gbool, toBool
when defined(win32):
const
lib = "libgtk-win32-2.0-0.dll"

View file

@ -26,9 +26,9 @@ import
proc pushstring*(L: PState, s: string)
# compatibilty macros
proc getn*(L: PState, n: int): int
proc getn*(L: PState, n: cint): cint
# calls lua_objlen
proc setn*(L: PState, t, n: int)
proc setn*(L: PState, t, n: cint)
# does nothing!
type
Treg*{.final.} = object
@ -37,58 +37,45 @@ type
Preg* = ptr Treg
proc openlib*(L: PState, libname: cstring, lr: Preg, nup: int){.cdecl,
dynlib: lua.LIB_NAME, importc: "luaL_openlib".}
proc register*(L: PState, libname: cstring, lr: Preg){.cdecl,
dynlib: lua.LIB_NAME, importc: "luaL_register".}
proc getmetafield*(L: PState, obj: int, e: cstring): int{.cdecl,
dynlib: lua.LIB_NAME, importc: "luaL_getmetafield".}
proc callmeta*(L: PState, obj: int, e: cstring): int{.cdecl,
dynlib: LIB_NAME, importc: "luaL_callmeta".}
proc typerror*(L: PState, narg: int, tname: cstring): int{.cdecl,
dynlib: LIB_NAME, importc: "luaL_typerror".}
proc argerror*(L: PState, numarg: int, extramsg: cstring): int{.cdecl,
dynlib: LIB_NAME, importc: "luaL_argerror".}
proc checklstring*(L: PState, numArg: int, len: ptr int): cstring{.cdecl,
dynlib: LIB_NAME, importc: "luaL_checklstring".}
proc optlstring*(L: PState, numArg: int, def: cstring, len: ptr int): cstring{.
cdecl, dynlib: LIB_NAME, importc: "luaL_optlstring".}
proc checknumber*(L: PState, numArg: int): Number{.cdecl,
dynlib: LIB_NAME, importc: "luaL_checknumber".}
proc optnumber*(L: PState, nArg: int, def: Number): Number{.cdecl,
dynlib: LIB_NAME, importc: "luaL_optnumber".}
proc checkinteger*(L: PState, numArg: int): Integer{.cdecl,
dynlib: LIB_NAME, importc: "luaL_checkinteger".}
proc optinteger*(L: PState, nArg: int, def: Integer): Integer{.
cdecl, dynlib: LIB_NAME, importc: "luaL_optinteger".}
proc checkstack*(L: PState, sz: int, msg: cstring){.cdecl,
dynlib: LIB_NAME, importc: "luaL_checkstack".}
proc checktype*(L: PState, narg, t: int){.cdecl, dynlib: LIB_NAME,
importc: "luaL_checktype".}
proc checkany*(L: PState, narg: int){.cdecl, dynlib: LIB_NAME,
importc: "luaL_checkany".}
proc newmetatable*(L: PState, tname: cstring): int{.cdecl,
dynlib: LIB_NAME, importc: "luaL_newmetatable".}
proc checkudata*(L: PState, ud: int, tname: cstring): Pointer{.cdecl,
dynlib: LIB_NAME, importc: "luaL_checkudata".}
proc where*(L: PState, lvl: int){.cdecl, dynlib: LIB_NAME,
importc: "luaL_where".}
proc error*(L: PState, fmt: cstring): int{.cdecl, varargs,
dynlib: LIB_NAME, importc: "luaL_error".}
proc checkoption*(L: PState, narg: int, def: cstring, lst: cstringArray): int{.
cdecl, dynlib: LIB_NAME, importc: "luaL_checkoption".}
proc reference*(L: PState, t: int): int{.cdecl, dynlib: LIB_NAME,
importc: "luaL_ref".}
proc unref*(L: PState, t, theref: int){.cdecl, dynlib: LIB_NAME,
importc: "luaL_unref".}
proc loadfile*(L: PState, filename: cstring): int{.cdecl,
dynlib: LIB_NAME, importc: "luaL_loadfile".}
proc loadbuffer*(L: PState, buff: cstring, size: int, name: cstring): int{.
cdecl, dynlib: LIB_NAME, importc: "luaL_loadbuffer".}
proc loadstring*(L: PState, s: cstring): int{.cdecl, dynlib: LIB_NAME,
importc: "luaL_loadstring".}
proc newstate*(): PState{.cdecl, dynlib: LIB_NAME,
importc: "luaL_newstate".}
{.push callConv: cdecl, dynlib: lua.LIB_NAME.}
{.push importc: "luaL_$1".}
proc openlib*(L: PState, libname: cstring, lr: Preg, nup: cint)
proc register*(L: PState, libname: cstring, lr: Preg)
proc getmetafield*(L: PState, obj: cint, e: cstring): cint
proc callmeta*(L: PState, obj: cint, e: cstring): cint
proc typerror*(L: PState, narg: cint, tname: cstring): cint
proc argerror*(L: PState, numarg: cint, extramsg: cstring): cint
proc checklstring*(L: PState, numArg: cint, len: ptr int): cstring
proc optlstring*(L: PState, numArg: cint, def: cstring, len: ptr cint): cstring
proc checknumber*(L: PState, numArg: cint): Number
proc optnumber*(L: PState, nArg: cint, def: Number): Number
proc checkinteger*(L: PState, numArg: cint): Integer
proc optinteger*(L: PState, nArg: cint, def: Integer): Integer
proc checkstack*(L: PState, sz: cint, msg: cstring)
proc checktype*(L: PState, narg, t: cint)
proc checkany*(L: PState, narg: cint)
proc newmetatable*(L: PState, tname: cstring): cint
proc checkudata*(L: PState, ud: cint, tname: cstring): Pointer
proc where*(L: PState, lvl: cint)
proc error*(L: PState, fmt: cstring): cint{.varargs.}
proc checkoption*(L: PState, narg: cint, def: cstring, lst: cstringArray): cint
proc unref*(L: PState, t, theref: cint)
proc loadfile*(L: PState, filename: cstring): cint
proc loadbuffer*(L: PState, buff: cstring, size: cint, name: cstring): cint
proc loadstring*(L: PState, s: cstring): cint
proc newstate*(): PState
{.pop.}
proc reference*(L: PState, t: cint): cint{.importc: "luaL_ref".}
{.pop.}
proc open*(): PState
# compatibility; moved from unit lua to lauxlib because it needs luaL_newstate
#
@ -96,18 +83,18 @@ proc open*(): PState
#** some useful macros
#** ===============================================================
#
proc argcheck*(L: PState, cond: bool, numarg: int, extramsg: cstring)
proc checkstring*(L: PState, n: int): cstring
proc optstring*(L: PState, n: int, d: cstring): cstring
proc checkint*(L: PState, n: int): int
proc checklong*(L: PState, n: int): int32
proc optint*(L: PState, n: int, d: float64): int
proc optlong*(L: PState, n: int, d: float64): int32
proc dofile*(L: PState, filename: cstring): int
proc dostring*(L: PState, str: cstring): int
proc argcheck*(L: PState, cond: bool, numarg: cint, extramsg: cstring)
proc checkstring*(L: PState, n: cint): cstring
proc optstring*(L: PState, n: cint, d: cstring): cstring
proc checkint*(L: PState, n: cint): cint
proc checklong*(L: PState, n: cint): clong
proc optint*(L: PState, n: cint, d: float64): cint
proc optlong*(L: PState, n: cint, d: float64): clong
proc dofile*(L: PState, filename: cstring): cint
proc dostring*(L: PState, str: cstring): cint
proc getmetatable*(L: PState, tname: cstring)
# not translated:
# #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
# #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
#
#** =======================================================
#** Generic Buffer manipulation
@ -119,7 +106,7 @@ const # note: this is just arbitrary, as it related to t
type
Buffer*{.final.} = object
p*: cstring # current position in buffer
lvl*: int # number of strings in the stack (level)
lvl*: cint # number of strings in the stack (level)
L*: PState
buffer*: array[0..BUFFERSIZE - 1, Char] # warning: see note above about LUAL_BUFFERSIZE
@ -130,80 +117,76 @@ proc addchar*(B: PBuffer, c: Char)
# compatibility only (alias for luaL_addchar)
proc putchar*(B: PBuffer, c: Char)
# warning: see note above about LUAL_BUFFERSIZE
proc addsize*(B: PBuffer, n: int)
proc buffinit*(L: PState, B: PBuffer){.cdecl, dynlib: LIB_NAME,
importc: "luaL_buffinit".}
proc prepbuffer*(B: PBuffer): cstring{.cdecl, dynlib: LIB_NAME,
importc: "luaL_prepbuffer".}
proc addlstring*(B: PBuffer, s: cstring, L: int){.cdecl,
dynlib: LIB_NAME, importc: "luaL_addlstring".}
proc addstring*(B: PBuffer, s: cstring){.cdecl, dynlib: LIB_NAME,
importc: "luaL_addstring".}
proc addvalue*(B: PBuffer){.cdecl, dynlib: LIB_NAME,
importc: "luaL_addvalue".}
proc pushresult*(B: PBuffer){.cdecl, dynlib: LIB_NAME,
importc: "luaL_pushresult".}
proc gsub*(L: PState, s, p, r: cstring): cstring{.cdecl,
dynlib: LIB_NAME, importc: "luaL_gsub".}
proc findtable*(L: PState, idx: int, fname: cstring, szhint: int): cstring{.
cdecl, dynlib: LIB_NAME, importc: "luaL_findtable".}
proc addsize*(B: PBuffer, n: cint)
{.push callConv: cdecl, dynlib: lua.LIB_NAME, importc: "luaL_$1".}
proc buffinit*(L: PState, B: PBuffer)
proc prepbuffer*(B: PBuffer): cstring
proc addlstring*(B: PBuffer, s: cstring, L: cint)
proc addstring*(B: PBuffer, s: cstring)
proc addvalue*(B: PBuffer)
proc pushresult*(B: PBuffer)
proc gsub*(L: PState, s, p, r: cstring): cstring
proc findtable*(L: PState, idx: cint, fname: cstring, szhint: cint): cstring
# compatibility with ref system
# pre-defined references
{.pop.}
const
NOREF* = - 2
REFNIL* = - 1
proc unref*(L: PState, theref: int)
proc getref*(L: PState, theref: int)
proc unref*(L: PState, theref: cint)
proc getref*(L: PState, theref: cint)
#
#** Compatibility macros and functions
#
# implementation
proc pushstring(L: PState, s: string) =
pushlstring(L, cstring(s), len(s))
pushlstring(L, cstring(s), s.len.cint)
proc getn(L: PState, n: int): int =
proc getn(L: PState, n: cint): cint =
Result = objlen(L, n)
proc setn(L: PState, t, n: int) =
proc setn(L: PState, t, n: cint) =
# does nothing as this operation is deprecated
nil
proc open(): PState =
Result = newstate()
proc dofile(L: PState, filename: cstring): int =
proc dofile(L: PState, filename: cstring): cint =
Result = loadfile(L, filename)
if Result == 0: Result = pcall(L, 0, MULTRET, 0)
proc dostring(L: PState, str: cstring): int =
proc dostring(L: PState, str: cstring): cint =
Result = loadstring(L, str)
if Result == 0: Result = pcall(L, 0, MULTRET, 0)
proc getmetatable(L: PState, tname: cstring) =
getfield(L, REGISTRYINDEX, tname)
proc argcheck(L: PState, cond: bool, numarg: int, extramsg: cstring) =
proc argcheck(L: PState, cond: bool, numarg: cint, extramsg: cstring) =
if not cond:
discard argerror(L, numarg, extramsg)
proc checkstring(L: PState, n: int): cstring =
proc checkstring(L: PState, n: cint): cstring =
Result = checklstring(L, n, nil)
proc optstring(L: PState, n: int, d: cstring): cstring =
proc optstring(L: PState, n: cint, d: cstring): cstring =
Result = optlstring(L, n, d, nil)
proc checkint(L: PState, n: int): int =
Result = toInt(checknumber(L, n))
proc checkint(L: PState, n: cint): cint =
Result = cint(checknumber(L, n))
proc checklong(L: PState, n: int): int32 =
proc checklong(L: PState, n: cint): clong =
Result = int32(ToInt(checknumber(L, n)))
proc optint(L: PState, n: int, d: float64): int =
Result = int(ToInt(optnumber(L, n, d)))
proc optint(L: PState, n: cint, d: float64): cint =
Result = optnumber(L, n, d).cint
proc optlong(L: PState, n: int, d: float64): int32 =
proc optlong(L: PState, n: cint, d: float64): clong =
Result = int32(ToInt(optnumber(L, n, d)))
proc addchar(B: PBuffer, c: Char) =
@ -215,11 +198,11 @@ proc addchar(B: PBuffer, c: Char) =
proc putchar(B: PBuffer, c: Char) =
addchar(B, c)
proc addsize(B: PBuffer, n: int) =
proc addsize(B: PBuffer, n: cint) =
B.p = cast[cstring](cast[int](B.p) + n)
proc unref(L: PState, theref: int) =
proc unref(L: PState, theref: cint) =
unref(L, REGISTRYINDEX, theref)
proc getref(L: PState, theref: int) =
proc getref(L: PState, theref: cint) =
rawgeti(L, REGISTRYINDEX, theref)

View file

@ -51,16 +51,16 @@ when defined(useLuajit):
else:
when defined(MACOSX):
const
NAME* = "liblua(|5.2|5.1|5.0).dylib"
LIB_NAME* = "liblua(|5.2|5.1|5.0).dylib"
NAME* = "liblua(|5.1|5.0).dylib"
LIB_NAME* = "liblua(|5.1|5.0).dylib"
elif defined(UNIX):
const
NAME* = "liblua(|5.2|5.1|5.0).so(|.0)"
LIB_NAME* = "liblua(|5.2|5.1|5.0).so(|.0)"
NAME* = "liblua(|5.1|5.0).so(|.0)"
LIB_NAME* = "liblua(|5.1|5.0).so(|.0)"
else:
const
NAME* = "lua(|5.2|5.1|5.0).dll"
LIB_NAME* = "lua(|5.2|5.1|5.0).dll"
NAME* = "lua(|5.1|5.0).dll"
LIB_NAME* = "lua(|5.1|5.0).dll"
const
VERSION* = "Lua 5.1"
@ -76,7 +76,7 @@ const
ENVIRONINDEX* = - 10001
GLOBALSINDEX* = - 10002
proc upvalueindex*(I: int): int
proc upvalueindex*(I: cint): cint
const # thread status; 0 is OK
constYIELD* = 1
ERRRUN* = 2
@ -86,16 +86,16 @@ const # thread status; 0 is OK
type
PState* = Pointer
CFunction* = proc (L: PState): int{.cdecl.}
CFunction* = proc (L: PState): cint{.cdecl.}
#
#** functions that read/write blocks when loading/dumping Lua chunks
#
type
Reader* = proc (L: PState, ud: Pointer, sz: ptr int): cstring{.cdecl.}
Writer* = proc (L: PState, p: Pointer, sz: int, ud: Pointer): int{.cdecl.}
Alloc* = proc (ud, theptr: Pointer, osize, nsize: int){.cdecl.}
Reader* = proc (L: PState, ud: Pointer, sz: ptr cint): cstring{.cdecl.}
Writer* = proc (L: PState, p: Pointer, sz: cint, ud: Pointer): cint{.cdecl.}
Alloc* = proc (ud, theptr: Pointer, osize, nsize: cint){.cdecl.}
const
TNONE* = - 1
@ -112,130 +112,86 @@ const
type # Type of Numbers in Lua
Number* = float
Integer* = int
Integer* = cint
{.pragma: ilua, importc: "lua_$1".}
{.push callConv: cdecl, dynlib: LibName.}
#{.push importc: "lua_$1".}
proc newstate*(f: Alloc, ud: Pointer): PState {.ilua.}
proc close*(L: PState){.ilua.}
proc newthread*(L: PState): PState{.ilua.}
proc atpanic*(L: PState, panicf: CFunction): CFunction{.ilua.}
proc gettop*(L: PState): cint{.ilua.}
proc settop*(L: PState, idx: cint){.ilua.}
proc pushvalue*(L: PState, Idx: cint){.ilua.}
proc remove*(L: PState, idx: cint){.ilua.}
proc insert*(L: PState, idx: cint){.ilua.}
proc replace*(L: PState, idx: cint){.ilua.}
proc checkstack*(L: PState, sz: cint): cint{.ilua.}
proc xmove*(`from`, `to`: PState, n: cint){.ilua.}
proc isnumber*(L: PState, idx: cint): cint{.ilua.}
proc isstring*(L: PState, idx: cint): cint{.ilua.}
proc iscfunction*(L: PState, idx: cint): cint{.ilua.}
proc isuserdata*(L: PState, idx: cint): cint{.ilua.}
proc luatype*(L: PState, idx: cint): cint{.importc: "lua_type".}
proc typename*(L: PState, tp: cint): cstring{.ilua.}
proc equal*(L: PState, idx1, idx2: cint): cint{.ilua.}
proc rawequal*(L: PState, idx1, idx2: cint): cint{.ilua.}
proc lessthan*(L: PState, idx1, idx2: cint): cint{.ilua.}
proc tonumber*(L: PState, idx: cint): Number{.ilua.}
proc tointeger*(L: PState, idx: cint): Integer{.ilua.}
proc toboolean*(L: PState, idx: cint): cint{.ilua.}
proc tolstring*(L: PState, idx: cint, length: ptr cint): cstring{.ilua.}
proc objlen*(L: PState, idx: cint): cint{.ilua.}
proc tocfunction*(L: PState, idx: cint): CFunction{.ilua.}
proc touserdata*(L: PState, idx: cint): Pointer{.ilua.}
proc tothread*(L: PState, idx: cint): PState{.ilua.}
proc topointer*(L: PState, idx: cint): Pointer{.ilua.}
proc pushnil*(L: PState){.ilua.}
proc pushnumber*(L: PState, n: Number){.ilua.}
proc pushinteger*(L: PState, n: Integer){.ilua.}
proc pushlstring*(L: PState, s: cstring, len: cint){.ilua.}
proc pushstring*(L: PState, s: cstring){.ilua.}
proc pushvfstring*(L: PState, fmt: cstring, argp: Pointer): cstring{.ilua.}
proc pushfstring*(L: PState, fmt: cstring): cstring{.varargs,ilua.}
proc pushcclosure*(L: PState, fn: CFunction, n: cint){.ilua.}
proc pushboolean*(L: PState, b: cint){.ilua.}
proc pushlightuserdata*(L: PState, p: Pointer){.ilua.}
proc pushthread*(L: PState){.ilua.}
proc gettable*(L: PState, idx: cint){.ilua.}
proc getfield*(L: Pstate, idx: cint, k: cstring){.ilua.}
proc rawget*(L: PState, idx: cint){.ilua.}
proc rawgeti*(L: PState, idx, n: cint){.ilua.}
proc createtable*(L: PState, narr, nrec: cint){.ilua.}
proc newuserdata*(L: PState, sz: cint): Pointer{.ilua.}
proc getmetatable*(L: PState, objindex: cint): cint{.ilua.}
proc getfenv*(L: PState, idx: cint){.ilua.}
proc settable*(L: PState, idx: cint){.ilua.}
proc setfield*(L: PState, idx: cint, k: cstring){.ilua.}
proc rawset*(L: PState, idx: cint){.ilua.}
proc rawseti*(L: PState, idx, n: cint){.ilua.}
proc setmetatable*(L: PState, objindex: cint): cint{.ilua.}
proc setfenv*(L: PState, idx: cint): cint{.ilua.}
proc call*(L: PState, nargs, nresults: cint){.ilua.}
proc pcall*(L: PState, nargs, nresults, errf: cint): cint{.ilua.}
proc cpcall*(L: PState, func: CFunction, ud: Pointer): cint{.ilua.}
proc load*(L: PState, reader: Reader, dt: Pointer, chunkname: cstring): cint{.ilua.}
proc dump*(L: PState, writer: Writer, data: Pointer): cint{.ilua.}
proc luayield*(L: PState, nresults: cint): cint{.importc: "lua_yield".}
proc resume*(L: PState, narg: cint): cint{.ilua.}
proc status*(L: PState): cint{.ilua.}
proc gc*(L: PState, what, data: cint): cint{.ilua.}
proc error*(L: PState): cint{.ilua.}
proc next*(L: PState, idx: cint): cint{.ilua.}
proc concat*(L: PState, n: cint){.ilua.}
proc getallocf*(L: PState, ud: ptr Pointer): Alloc{.ilua.}
proc setallocf*(L: PState, f: Alloc, ud: Pointer){.ilua.}
{.pop.}
proc newstate*(f: Alloc, ud: Pointer): PState{.cdecl, dynlib: NAME,
importc: "lua_newstate".}
proc close*(L: PState){.cdecl, dynlib: NAME, importc: "lua_close".}
proc newthread*(L: PState): PState{.cdecl, dynlib: NAME,
importc: "lua_newthread".}
proc atpanic*(L: PState, panicf: CFunction): CFunction{.cdecl, dynlib: NAME,
importc: "lua_atpanic".}
proc gettop*(L: PState): int{.cdecl, dynlib: NAME, importc: "lua_gettop".}
proc settop*(L: PState, idx: int){.cdecl, dynlib: NAME, importc: "lua_settop".}
proc pushvalue*(L: PState, Idx: int){.cdecl, dynlib: NAME,
importc: "lua_pushvalue".}
proc remove*(L: PState, idx: int){.cdecl, dynlib: NAME, importc: "lua_remove".}
proc insert*(L: PState, idx: int){.cdecl, dynlib: NAME, importc: "lua_insert".}
proc replace*(L: PState, idx: int){.cdecl, dynlib: NAME, importc: "lua_replace".}
proc checkstack*(L: PState, sz: int): cint{.cdecl, dynlib: NAME,
importc: "lua_checkstack".}
proc xmove*(`from`, `to`: PState, n: int){.cdecl, dynlib: NAME,
importc: "lua_xmove".}
proc isnumber*(L: PState, idx: int): cint{.cdecl, dynlib: NAME,
importc: "lua_isnumber".}
proc isstring*(L: PState, idx: int): cint{.cdecl, dynlib: NAME,
importc: "lua_isstring".}
proc iscfunction*(L: PState, idx: int): cint{.cdecl, dynlib: NAME,
importc: "lua_iscfunction".}
proc isuserdata*(L: PState, idx: int): cint{.cdecl, dynlib: NAME,
importc: "lua_isuserdata".}
proc luatype*(L: PState, idx: int): int{.cdecl, dynlib: NAME, importc: "lua_type".}
proc typename*(L: PState, tp: int): cstring{.cdecl, dynlib: NAME,
importc: "lua_typename".}
proc equal*(L: PState, idx1, idx2: int): cint{.cdecl, dynlib: NAME,
importc: "lua_equal".}
proc rawequal*(L: PState, idx1, idx2: int): cint{.cdecl, dynlib: NAME,
importc: "lua_rawequal".}
proc lessthan*(L: PState, idx1, idx2: int): cint{.cdecl, dynlib: NAME,
importc: "lua_lessthan".}
proc tonumber*(L: PState, idx: int): Number{.cdecl, dynlib: NAME,
importc: "lua_tonumber".}
proc tointeger*(L: PState, idx: int): Integer{.cdecl, dynlib: NAME,
importc: "lua_tointeger".}
proc toboolean*(L: PState, idx: int): cint{.cdecl, dynlib: NAME,
importc: "lua_toboolean".}
proc tolstring*(L: PState, idx: int, length: ptr int): cstring{.cdecl,
dynlib: NAME, importc: "lua_tolstring".}
proc objlen*(L: PState, idx: int): int{.cdecl, dynlib: NAME,
importc: "lua_objlen".}
proc tocfunction*(L: PState, idx: int): CFunction{.cdecl, dynlib: NAME,
importc: "lua_tocfunction".}
proc touserdata*(L: PState, idx: int): Pointer{.cdecl, dynlib: NAME,
importc: "lua_touserdata".}
proc tothread*(L: PState, idx: int): PState{.cdecl, dynlib: NAME,
importc: "lua_tothread".}
proc topointer*(L: PState, idx: int): Pointer{.cdecl, dynlib: NAME,
importc: "lua_topointer".}
proc pushnil*(L: PState){.cdecl, dynlib: NAME, importc: "lua_pushnil".}
proc pushnumber*(L: PState, n: Number){.cdecl, dynlib: NAME,
importc: "lua_pushnumber".}
proc pushinteger*(L: PState, n: Integer){.cdecl, dynlib: NAME,
importc: "lua_pushinteger".}
proc pushlstring*(L: PState, s: cstring, len: int){.cdecl, dynlib: NAME,
importc: "lua_pushlstring".}
proc pushstring*(L: PState, s: cstring){.cdecl, dynlib: NAME,
importc: "lua_pushstring".}
proc pushvfstring*(L: PState, fmt: cstring, argp: Pointer): cstring{.cdecl,
dynlib: NAME, importc: "lua_pushvfstring".}
proc pushfstring*(L: PState, fmt: cstring): cstring{.cdecl, varargs,
dynlib: NAME, importc: "lua_pushfstring".}
proc pushcclosure*(L: PState, fn: CFunction, n: int){.cdecl, dynlib: NAME,
importc: "lua_pushcclosure".}
proc pushboolean*(L: PState, b: cint){.cdecl, dynlib: NAME,
importc: "lua_pushboolean".}
proc pushlightuserdata*(L: PState, p: Pointer){.cdecl, dynlib: NAME,
importc: "lua_pushlightuserdata".}
proc pushthread*(L: PState){.cdecl, dynlib: NAME, importc: "lua_pushthread".}
proc gettable*(L: PState, idx: int){.cdecl, dynlib: NAME,
importc: "lua_gettable".}
proc getfield*(L: Pstate, idx: int, k: cstring){.cdecl, dynlib: NAME,
importc: "lua_getfield".}
proc rawget*(L: PState, idx: int){.cdecl, dynlib: NAME, importc: "lua_rawget".}
proc rawgeti*(L: PState, idx, n: int){.cdecl, dynlib: NAME,
importc: "lua_rawgeti".}
proc createtable*(L: PState, narr, nrec: int){.cdecl, dynlib: NAME,
importc: "lua_createtable".}
proc newuserdata*(L: PState, sz: int): Pointer{.cdecl, dynlib: NAME,
importc: "lua_newuserdata".}
proc getmetatable*(L: PState, objindex: int): int{.cdecl, dynlib: NAME,
importc: "lua_getmetatable".}
proc getfenv*(L: PState, idx: int){.cdecl, dynlib: NAME, importc: "lua_getfenv".}
proc settable*(L: PState, idx: int){.cdecl, dynlib: NAME,
importc: "lua_settable".}
proc setfield*(L: PState, idx: int, k: cstring){.cdecl, dynlib: NAME,
importc: "lua_setfield".}
proc rawset*(L: PState, idx: int){.cdecl, dynlib: NAME, importc: "lua_rawset".}
proc rawseti*(L: PState, idx, n: int){.cdecl, dynlib: NAME,
importc: "lua_rawseti".}
proc setmetatable*(L: PState, objindex: int): int{.cdecl, dynlib: NAME,
importc: "lua_setmetatable".}
proc setfenv*(L: PState, idx: int): int{.cdecl, dynlib: NAME,
importc: "lua_setfenv".}
proc call*(L: PState, nargs, nresults: int){.cdecl, dynlib: NAME,
importc: "lua_call".}
proc pcall*(L: PState, nargs, nresults, errf: int): int{.cdecl, dynlib: NAME,
importc: "lua_pcall".}
proc cpcall*(L: PState, func: CFunction, ud: Pointer): int{.cdecl, dynlib: NAME,
importc: "lua_cpcall".}
proc load*(L: PState, reader: Reader, dt: Pointer, chunkname: cstring): int{.
cdecl, dynlib: NAME, importc: "lua_load".}
proc dump*(L: PState, writer: Writer, data: Pointer): int{.cdecl, dynlib: NAME,
importc: "lua_dump".}
proc luayield*(L: PState, nresults: int): int{.cdecl, dynlib: NAME,
importc: "lua_yield".}
proc resume*(L: PState, narg: int): int{.cdecl, dynlib: NAME,
importc: "lua_resume".}
proc status*(L: PState): int{.cdecl, dynlib: NAME, importc: "lua_status".}
proc gc*(L: PState, what, data: int): int{.cdecl, dynlib: NAME,
importc: "lua_gc".}
proc error*(L: PState): int{.cdecl, dynlib: NAME, importc: "lua_error".}
proc next*(L: PState, idx: int): int{.cdecl, dynlib: NAME, importc: "lua_next".}
proc concat*(L: PState, n: int){.cdecl, dynlib: NAME, importc: "lua_concat".}
proc getallocf*(L: PState, ud: ptr Pointer): Alloc{.cdecl, dynlib: NAME,
importc: "lua_getallocf".}
proc setallocf*(L: PState, f: Alloc, ud: Pointer){.cdecl, dynlib: NAME,
importc: "lua_setallocf".}
#
#** Garbage-collection functions and options
#
@ -256,29 +212,29 @@ const
#** ===============================================================
#
proc pop*(L: PState, n: int)
proc pop*(L: PState, n: cint)
proc newtable*(L: Pstate)
proc register*(L: PState, n: cstring, f: CFunction)
proc pushcfunction*(L: PState, f: CFunction)
proc strlen*(L: Pstate, i: int): int
proc isfunction*(L: PState, n: int): bool
proc istable*(L: PState, n: int): bool
proc islightuserdata*(L: PState, n: int): bool
proc isnil*(L: PState, n: int): bool
proc isboolean*(L: PState, n: int): bool
proc isthread*(L: PState, n: int): bool
proc isnone*(L: PState, n: int): bool
proc isnoneornil*(L: PState, n: int): bool
proc strlen*(L: Pstate, i: cint): cint
proc isfunction*(L: PState, n: cint): bool
proc istable*(L: PState, n: cint): bool
proc islightuserdata*(L: PState, n: cint): bool
proc isnil*(L: PState, n: cint): bool
proc isboolean*(L: PState, n: cint): bool
proc isthread*(L: PState, n: cint): bool
proc isnone*(L: PState, n: cint): bool
proc isnoneornil*(L: PState, n: cint): bool
proc pushliteral*(L: PState, s: cstring)
proc setglobal*(L: PState, s: cstring)
proc getglobal*(L: PState, s: cstring)
proc tostring*(L: PState, i: int): cstring
proc tostring*(L: PState, i: cint): cstring
#
#** compatibility macros and functions
#
proc getregistry*(L: PState)
proc getgccount*(L: PState): int
proc getgccount*(L: PState): cint
type
Chunkreader* = Reader
Chunkwriter* = Writer
@ -307,18 +263,18 @@ const
type
TDebug*{.final.} = object # activation record
event*: int
event*: cint
name*: cstring # (n)
namewhat*: cstring # (n) `global', `local', `field', `method'
what*: cstring # (S) `Lua', `C', `main', `tail'
source*: cstring # (S)
currentline*: int # (l)
nups*: int # (u) number of upvalues
linedefined*: int # (S)
lastlinedefined*: int # (S)
short_src*: array[0..IDSIZE - 1, Char] # (S)
# private part
i_ci*: int # active function
currentline*: cint # (l)
nups*: cint # (u) number of upvalues
linedefined*: cint # (S)
lastlinedefined*: cint # (S)
short_src*: array[0.. <IDSIZE, Char] # (S) \
# private part
i_ci*: cint # active function
PDebug* = ptr TDebug
Hook* = proc (L: PState, ar: PDebug){.cdecl.}
@ -329,31 +285,27 @@ type
#** ======================================================================
#
proc getstack*(L: PState, level: int, ar: PDebug): int{.cdecl, dynlib: NAME,
importc: "lua_getstack".}
proc getinfo*(L: PState, what: cstring, ar: PDebug): int{.cdecl, dynlib: NAME,
importc: "lua_getinfo".}
proc getlocal*(L: PState, ar: PDebug, n: int): cstring{.cdecl, dynlib: NAME,
importc: "lua_getlocal".}
proc setlocal*(L: PState, ar: PDebug, n: int): cstring{.cdecl, dynlib: NAME,
importc: "lua_setlocal".}
proc getupvalue*(L: PState, funcindex: int, n: int): cstring{.cdecl,
dynlib: NAME, importc: "lua_getupvalue".}
proc setupvalue*(L: PState, funcindex: int, n: int): cstring{.cdecl,
dynlib: NAME, importc: "lua_setupvalue".}
proc sethook*(L: PState, func: Hook, mask: int, count: int): int{.cdecl,
dynlib: NAME, importc: "lua_sethook".}
proc gethook*(L: PState): Hook{.cdecl, dynlib: NAME, importc: "lua_gethook".}
proc gethookmask*(L: PState): int{.cdecl, dynlib: NAME,
importc: "lua_gethookmask".}
proc gethookcount*(L: PState): int{.cdecl, dynlib: NAME,
importc: "lua_gethookcount".}
{.push callConv: cdecl, dynlib: lua.LIB_NAME.}
proc getstack*(L: PState, level: cint, ar: PDebug): cint{.ilua.}
proc getinfo*(L: PState, what: cstring, ar: PDebug): cint{.ilua.}
proc getlocal*(L: PState, ar: PDebug, n: cint): cstring{.ilua.}
proc setlocal*(L: PState, ar: PDebug, n: cint): cstring{.ilua.}
proc getupvalue*(L: PState, funcindex: cint, n: cint): cstring{.ilua.}
proc setupvalue*(L: PState, funcindex: cint, n: cint): cstring{.ilua.}
proc sethook*(L: PState, func: Hook, mask: cint, count: cint): cint{.ilua.}
proc gethook*(L: PState): Hook{.ilua.}
proc gethookmask*(L: PState): cint{.ilua.}
proc gethookcount*(L: PState): cint{.ilua.}
{.pop.}
# implementation
proc upvalueindex(I: int): int =
proc upvalueindex(I: cint): cint =
Result = GLOBALSINDEX - i
proc pop(L: PState, n: int) =
proc pop(L: PState, n: cint) =
settop(L, - n - 1)
proc newtable(L: PState) =
@ -366,35 +318,35 @@ proc register(L: PState, n: cstring, f: CFunction) =
proc pushcfunction(L: PState, f: CFunction) =
pushcclosure(L, f, 0)
proc strlen(L: PState, i: int): int =
proc strlen(L: PState, i: cint): cint =
Result = objlen(L, i)
proc isfunction(L: PState, n: int): bool =
proc isfunction(L: PState, n: cint): bool =
Result = luatype(L, n) == TFUNCTION
proc istable(L: PState, n: int): bool =
proc istable(L: PState, n: cint): bool =
Result = luatype(L, n) == TTABLE
proc islightuserdata(L: PState, n: int): bool =
proc islightuserdata(L: PState, n: cint): bool =
Result = luatype(L, n) == TLIGHTUSERDATA
proc isnil(L: PState, n: int): bool =
proc isnil(L: PState, n: cint): bool =
Result = luatype(L, n) == TNIL
proc isboolean(L: PState, n: int): bool =
proc isboolean(L: PState, n: cint): bool =
Result = luatype(L, n) == TBOOLEAN
proc isthread(L: PState, n: int): bool =
proc isthread(L: PState, n: cint): bool =
Result = luatype(L, n) == TTHREAD
proc isnone(L: PState, n: int): bool =
proc isnone(L: PState, n: cint): bool =
Result = luatype(L, n) == TNONE
proc isnoneornil(L: PState, n: int): bool =
proc isnoneornil(L: PState, n: cint): bool =
Result = luatype(L, n) <= 0
proc pushliteral(L: PState, s: cstring) =
pushlstring(L, s, len(s))
pushlstring(L, s, s.len.cint)
proc setglobal(L: PState, s: cstring) =
setfield(L, GLOBALSINDEX, s)
@ -402,11 +354,11 @@ proc setglobal(L: PState, s: cstring) =
proc getglobal(L: PState, s: cstring) =
getfield(L, GLOBALSINDEX, s)
proc tostring(L: PState, i: int): cstring =
proc tostring(L: PState, i: cint): cstring =
Result = tolstring(L, i, nil)
proc getregistry(L: PState) =
pushvalue(L, REGISTRYINDEX)
proc getgccount(L: PState): int =
proc getgccount(L: PState): cint =
Result = gc(L, GCCOUNT, 0)

View file

@ -32,35 +32,33 @@ const
DBLIBNAME* = "debug"
LOADLIBNAME* = "package"
proc open_base*(L: PState): cint{.cdecl, dynlib: LIB_NAME,
importc: "luaopen_base".}
proc open_table*(L: PState): cint{.cdecl, dynlib: LIB_NAME,
importc: "luaopen_table".}
proc open_io*(L: PState): cint{.cdecl, dynlib: LIB_NAME, importc: "luaopen_io".}
proc open_string*(L: PState): cint{.cdecl, dynlib: LIB_NAME,
importc: "luaopen_string".}
proc open_math*(L: PState): cint{.cdecl, dynlib: LIB_NAME,
importc: "luaopen_math".}
proc open_debug*(L: PState): cint{.cdecl, dynlib: LIB_NAME,
importc: "luaopen_debug".}
proc open_package*(L: PState): cint{.cdecl, dynlib: LIB_NAME,
importc: "luaopen_package".}
proc openlibs*(L: PState){.cdecl, dynlib: LIB_NAME, importc: "luaL_openlibs".}
{.pragma: ilua, importc: "lua$1".}
{.push callConv: cdecl, dynlib: lua.LIB_NAME.}
proc open_base*(L: PState): cint{.ilua.}
proc open_table*(L: PState): cint{.ilua.}
proc open_io*(L: PState): cint{.ilua.}
proc open_string*(L: PState): cint{.ilua.}
proc open_math*(L: PState): cint{.ilua.}
proc open_debug*(L: PState): cint{.ilua.}
proc open_package*(L: PState): cint{.ilua.}
proc openlibs*(L: PState){.importc: "luaL_openlibs".}
{.pop.}
proc baselibopen*(L: PState): Bool =
Result = open_base(L) != 0'i32
open_base(L) != 0'i32
proc tablibopen*(L: PState): Bool =
Result = open_table(L) != 0'i32
open_table(L) != 0'i32
proc iolibopen*(L: PState): Bool =
Result = open_io(L) != 0'i32
open_io(L) != 0'i32
proc strlibopen*(L: PState): Bool =
Result = open_string(L) != 0'i32
open_string(L) != 0'i32
proc mathlibopen*(L: PState): Bool =
Result = open_math(L) != 0'i32
open_math(L) != 0'i32
proc dblibopen*(L: PState): Bool =
Result = open_debug(L) != 0'i32
open_debug(L) != 0'i32

View file

@ -196,7 +196,7 @@ const
proc SSL_library_init*(): cInt{.cdecl, dynlib: DLLSSLName, importc, discardable.}
proc SSL_load_error_strings*(){.cdecl, dynlib: DLLSSLName, importc.}
proc ERR_load_BIO_strings*(){.cdecl, dynlib: DLLSSLName, importc.}
proc ERR_load_BIO_strings*(){.cdecl, dynlib: DLLUtilName, importc.}
proc SSLv23_client_method*(): PSSL_METHOD{.cdecl, dynlib: DLLSSLName, importc.}
proc SSLv23_method*(): PSSL_METHOD{.cdecl, dynlib: DLLSSLName, importc.}
@ -262,14 +262,15 @@ proc ERR_error_string*(e: cInt, buf: cstring): cstring{.cdecl,
proc ERR_get_error*(): cInt{.cdecl, dynlib: DLLUtilName, importc.}
proc ERR_peek_last_error*(): cInt{.cdecl, dynlib: DLLUtilName, importc.}
proc OpenSSL_add_all_algorithms*(){.cdecl, dynlib: DLLSSLName, importc: "OPENSSL_add_all_algorithms_conf".}
proc OpenSSL_add_all_algorithms*(){.cdecl, dynlib: DLLUtilName, importc: "OPENSSL_add_all_algorithms_conf".}
proc OPENSSL_config*(configName: cstring){.cdecl, dynlib: DLLSSLName, importc.}
proc CRYPTO_set_mem_functions(a,b,c: pointer){.cdecl, dynlib: DLLSSLName, importc.}
proc CRYPTO_malloc_init*() =
CRYPTO_set_mem_functions(alloc, realloc, dealloc)
when not defined(windows):
CRYPTO_set_mem_functions(alloc, realloc, dealloc)
when True:
nil

View file

@ -156,33 +156,34 @@ const
type
Thook_func* = proc (a2: cstring): cstring{.cdecl.}
# If non-null, this contains the address of a function that the application
# wants called before trying the standard tilde expansions. The function
# is called with the text sans tilde, and returns a malloc()'ed string
# which is the expansion, or a NULL pointer if the expansion fails.
when not defined(macosx):
# If non-null, this contains the address of a function that the application
# wants called before trying the standard tilde expansions. The function
# is called with the text sans tilde, and returns a malloc()'ed string
# which is the expansion, or a NULL pointer if the expansion fails.
var expansion_preexpansion_hook*{.importc: "tilde_expansion_preexpansion_hook",
dynlib: tildeDll.}: Thook_func
var expansion_preexpansion_hook*{.importc: "tilde_expansion_preexpansion_hook",
dynlib: tildeDll.}: Thook_func
# If non-null, this contains the address of a function to call if the
# standard meaning for expanding a tilde fails. The function is called
# with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
# which is the expansion, or a NULL pointer if there is no expansion.
# If non-null, this contains the address of a function to call if the
# standard meaning for expanding a tilde fails. The function is called
# with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
# which is the expansion, or a NULL pointer if there is no expansion.
var expansion_failure_hook*{.importc: "tilde_expansion_failure_hook",
dynlib: tildeDll.}: Thook_func
var expansion_failure_hook*{.importc: "tilde_expansion_failure_hook",
dynlib: tildeDll.}: Thook_func
# When non-null, this is a NULL terminated array of strings which
# are duplicates for a tilde prefix. Bash uses this to expand
# `=~' and `:~'.
# When non-null, this is a NULL terminated array of strings which
# are duplicates for a tilde prefix. Bash uses this to expand
# `=~' and `:~'.
var additional_prefixes*{.importc: "tilde_additional_prefixes", dynlib: tildeDll.}: cstringArray
var additional_prefixes*{.importc: "tilde_additional_prefixes", dynlib: tildeDll.}: cstringArray
# When non-null, this is a NULL terminated array of strings which match
# the end of a username, instead of just "/". Bash sets this to
# `:' and `=~'.
# When non-null, this is a NULL terminated array of strings which match
# the end of a username, instead of just "/". Bash sets this to
# `:' and `=~'.
var additional_suffixes*{.importc: "tilde_additional_suffixes", dynlib: tildeDll.}: cstringArray
var additional_suffixes*{.importc: "tilde_additional_suffixes", dynlib: tildeDll.}: cstringArray
# Return a new string which is the result of tilde expanding STRING.
@ -229,7 +230,8 @@ type
# The current undo list for RL_LINE_BUFFER.
var undo_list*{.importc: "rl_undo_list", dynlib: readlineDll.}: ptr TUNDO_LIST
when not defined(macosx):
var undo_list*{.importc: "rl_undo_list", dynlib: readlineDll.}: ptr TUNDO_LIST
# The data structure for mapping textual names to code addresses.
@ -239,7 +241,8 @@ type
function*: TCommandFunc
var funmap*{.importc: "funmap", dynlib: readlineDll.}: ptr ptr TFUNMAP
when not defined(macosx):
var funmap*{.importc: "funmap", dynlib: readlineDll.}: ptr ptr TFUNMAP
# ****************************************************************
#

View file

@ -1,16 +1,16 @@
#
#
# Nimrod's Runtime Library
# (c) Copyright 2008 Andreas Rumpf
# (c) Copyright 2013 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## Interface to the `libzip <http://www.nih.at/libzip/index.html>`_ library by
## Dieter Baron and Thomas Klausner. However, this does not need any external
## library (DLL, lib*.so), as the source for this library is included and
## compiled with this interface.
## Dieter Baron and Thomas Klausner. This version links
## against ``libzip2.so.2`` unless you define the symbol ``useLibzipSrc``; then
## it is compiled against some old ``libizp_all.c`` file.
#
# zip.h -- exported declarations.
@ -47,9 +47,16 @@
import times
{.compile: "libzip_all.c".}
when defined(unix):
{.passl: "-lz".}
when defined(unix) and not defined(useLibzipSrc):
when defined(macosx):
{.pragma: mydll, dynlib: "libzip2.dylib".}
else:
{.pragma: mydll, dynlib: "libzip2.so(|.2|.1|.0)".}
else:
when defined(unix):
{.passl: "-lz".}
{.compile: "libzip_all.c".}
{.pragma: mydll.}
type
Tzip_source_cmd* = int32
@ -57,7 +64,7 @@ type
Tzip_source_callback* = proc (state: pointer, data: pointer, length: int,
cmd: Tzip_source_cmd): int {.cdecl.}
Pzip_stat* = ptr Tzip_stat
Tzip_stat* {.final, pure.} = object
Tzip_stat* = object ## the 'zip_stat' struct
name*: cstring ## name of the file
index*: int32 ## index within archive
crc*: int32 ## crc of file data
@ -67,9 +74,9 @@ type
comp_method*: int16 ## compression method used
encryption_method*: int16 ## encryption method used
Tzip {.final, pure.} = object
Tzip_source {.final, pure.} = object
Tzip_file {.final, pure.} = object
Tzip = object
Tzip_source = object
Tzip_file = object
Pzip* = ptr Tzip ## represents a zip archive
Pzip_file* = ptr Tzip_file ## represents a file within an archive
@ -160,82 +167,83 @@ const
constZIP_SOURCE_FREE* = 5'i32 ## cleanup and free resources
proc zip_add*(para1: Pzip, para2: cstring, para3: Pzip_source): int32 {.cdecl,
importc: "zip_add".}
importc: "zip_add", mydll.}
proc zip_add_dir*(para1: Pzip, para2: cstring): int32 {.cdecl,
importc: "zip_add_dir".}
proc zip_close*(para1: Pzip) {.cdecl, importc: "zip_close".}
proc zip_delete*(para1: Pzip, para2: int32): int32 {.cdecl,
importc: "zip_add_dir", mydll.}
proc zip_close*(para1: Pzip) {.cdecl, importc: "zip_close", mydll.}
proc zip_delete*(para1: Pzip, para2: int32): int32 {.cdecl, mydll,
importc: "zip_delete".}
proc zip_error_clear*(para1: Pzip) {.cdecl, importc: "zip_error_clear".}
proc zip_error_clear*(para1: Pzip) {.cdecl, importc: "zip_error_clear", mydll.}
proc zip_error_get*(para1: Pzip, para2: ptr int32, para3: ptr int32) {.cdecl,
importc: "zip_error_get".}
proc zip_error_get_sys_type*(para1: int32): int32 {.cdecl,
importc: "zip_error_get", mydll.}
proc zip_error_get_sys_type*(para1: int32): int32 {.cdecl, mydll,
importc: "zip_error_get_sys_type".}
proc zip_error_to_str*(para1: cstring, para2: int, para3: int32,
para4: int32): int32 {.cdecl,
para4: int32): int32 {.cdecl, mydll,
importc: "zip_error_to_str".}
proc zip_fclose*(para1: Pzip_file) {.cdecl,
proc zip_fclose*(para1: Pzip_file) {.cdecl, mydll,
importc: "zip_fclose".}
proc zip_file_error_clear*(para1: Pzip_file) {.cdecl,
proc zip_file_error_clear*(para1: Pzip_file) {.cdecl, mydll,
importc: "zip_file_error_clear".}
proc zip_file_error_get*(para1: Pzip_file, para2: ptr int32, para3: ptr int32) {.
cdecl, importc: "zip_file_error_get".}
proc zip_file_strerror*(para1: Pzip_file): cstring {.cdecl,
cdecl, mydll, importc: "zip_file_error_get".}
proc zip_file_strerror*(para1: Pzip_file): cstring {.cdecl, mydll,
importc: "zip_file_strerror".}
proc zip_fopen*(para1: Pzip, para2: cstring, para3: int32): Pzip_file {.cdecl,
importc: "zip_fopen".}
mydll, importc: "zip_fopen".}
proc zip_fopen_index*(para1: Pzip, para2: int32, para3: int32): Pzip_file {.
cdecl, importc: "zip_fopen_index".}
cdecl, mydll, importc: "zip_fopen_index".}
proc zip_fread*(para1: Pzip_file, para2: pointer, para3: int): int {.
cdecl, importc: "zip_fread".}
cdecl, mydll, importc: "zip_fread".}
proc zip_get_archive_comment*(para1: Pzip, para2: ptr int32, para3: int32): cstring {.
cdecl, importc: "zip_get_archive_comment".}
cdecl, mydll, importc: "zip_get_archive_comment".}
proc zip_get_archive_flag*(para1: Pzip, para2: int32, para3: int32): int32 {.
cdecl, importc: "zip_get_archive_flag".}
cdecl, mydll, importc: "zip_get_archive_flag".}
proc zip_get_file_comment*(para1: Pzip, para2: int32, para3: ptr int32,
para4: int32): cstring {.cdecl,
para4: int32): cstring {.cdecl, mydll,
importc: "zip_get_file_comment".}
proc zip_get_name*(para1: Pzip, para2: int32, para3: int32): cstring {.cdecl,
importc: "zip_get_name".}
mydll, importc: "zip_get_name".}
proc zip_get_num_files*(para1: Pzip): int32 {.cdecl,
importc: "zip_get_num_files".}
mydll, importc: "zip_get_num_files".}
proc zip_name_locate*(para1: Pzip, para2: cstring, para3: int32): int32 {.cdecl,
importc: "zip_name_locate".}
mydll, importc: "zip_name_locate".}
proc zip_open*(para1: cstring, para2: int32, para3: ptr int32): Pzip {.cdecl,
importc: "zip_open".}
mydll, importc: "zip_open".}
proc zip_rename*(para1: Pzip, para2: int32, para3: cstring): int32 {.cdecl,
importc: "zip_rename".}
mydll, importc: "zip_rename".}
proc zip_replace*(para1: Pzip, para2: int32, para3: Pzip_source): int32 {.cdecl,
importc: "zip_replace".}
mydll, importc: "zip_replace".}
proc zip_set_archive_comment*(para1: Pzip, para2: cstring, para3: int32): int32 {.
cdecl, importc: "zip_set_archive_comment".}
cdecl, mydll, importc: "zip_set_archive_comment".}
proc zip_set_archive_flag*(para1: Pzip, para2: int32, para3: int32): int32 {.
cdecl, importc: "zip_set_archive_flag".}
cdecl, mydll, importc: "zip_set_archive_flag".}
proc zip_set_file_comment*(para1: Pzip, para2: int32, para3: cstring,
para4: int32): int32 {.cdecl,
para4: int32): int32 {.cdecl, mydll,
importc: "zip_set_file_comment".}
proc zip_source_buffer*(para1: Pzip, para2: pointer, para3: int, para4: int32): Pzip_source {.
cdecl, importc: "zip_source_buffer".}
cdecl, mydll, importc: "zip_source_buffer".}
proc zip_source_file*(para1: Pzip, para2: cstring, para3: int, para4: int): Pzip_source {.
cdecl, importc: "zip_source_file".}
cdecl, mydll, importc: "zip_source_file".}
proc zip_source_filep*(para1: Pzip, para2: TFile, para3: int, para4: int): Pzip_source {.
cdecl, importc: "zip_source_filep".}
proc zip_source_free*(para1: Pzip_source) {.cdecl,
cdecl, mydll, importc: "zip_source_filep".}
proc zip_source_free*(para1: Pzip_source) {.cdecl, mydll,
importc: "zip_source_free".}
proc zip_source_function*(para1: Pzip, para2: Tzip_source_callback,
para3: pointer): Pzip_source {.cdecl,
para3: pointer): Pzip_source {.cdecl, mydll,
importc: "zip_source_function".}
proc zip_source_zip*(para1: Pzip, para2: Pzip, para3: int32, para4: int32,
para5: int, para6: int): Pzip_source {.cdecl,
para5: int, para6: int): Pzip_source {.cdecl, mydll,
importc: "zip_source_zip".}
proc zip_stat*(para1: Pzip, para2: cstring, para3: int32, para4: Pzip_stat): int32 {.
cdecl, importc: "zip_stat".}
cdecl, mydll, importc: "zip_stat".}
proc zip_stat_index*(para1: Pzip, para2: int32, para3: int32, para4: Pzip_stat): int32 {.
cdecl, importc: "zip_stat_index".}
proc zip_stat_init*(para1: Pzip_stat) {.cdecl, importc: "zip_stat_init".}
proc zip_strerror*(para1: Pzip): cstring {.cdecl, importc: "zip_strerror".}
proc zip_unchange*(para1: Pzip, para2: int32): int32 {.cdecl,
cdecl, mydll, importc: "zip_stat_index".}
proc zip_stat_init*(para1: Pzip_stat) {.cdecl, mydll, importc: "zip_stat_init".}
proc zip_strerror*(para1: Pzip): cstring {.cdecl, mydll, importc: "zip_strerror".}
proc zip_unchange*(para1: Pzip, para2: int32): int32 {.cdecl, mydll,
importc: "zip_unchange".}
proc zip_unchange_all*(para1: Pzip): int32 {.cdecl, importc: "zip_unchange_all".}
proc zip_unchange_archive*(para1: Pzip): int32 {.cdecl,
proc zip_unchange_all*(para1: Pzip): int32 {.cdecl, mydll,
importc: "zip_unchange_all".}
proc zip_unchange_archive*(para1: Pzip): int32 {.cdecl, mydll,
importc: "zip_unchange_archive".}