version 0.7.0
This commit is contained in:
parent
972c510861
commit
8b2a9401a1
185 changed files with 21451 additions and 24296 deletions
103
cogapp.py
103
cogapp.py
|
|
@ -5,11 +5,13 @@
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# $Id: cogapp.py 141 2008-05-22 10:56:43Z nedbat $
|
# $Id: cogapp.py 141 2008-05-22 10:56:43Z nedbat $
|
||||||
|
# modified to run with Python1.5.2 by Andreas Rumpf
|
||||||
|
|
||||||
import md5, os, re, string, sys, traceback, types
|
import md5, os, re, string, sys, traceback, types
|
||||||
import imp, compiler
|
import imp
|
||||||
import copy, getopt, shlex
|
import copy, getopt, shlex
|
||||||
from cStringIO import StringIO
|
from cStringIO import StringIO
|
||||||
|
from string import strip, split, join, replace
|
||||||
|
|
||||||
__all__ = ['Cog', 'CogUsageError']
|
__all__ = ['Cog', 'CogUsageError']
|
||||||
|
|
||||||
|
|
@ -99,7 +101,11 @@ class CogGenerator(Redirectable):
|
||||||
self.markers.append(l)
|
self.markers.append(l)
|
||||||
|
|
||||||
def parseLine(self, l):
|
def parseLine(self, l):
|
||||||
self.lines.append(l.strip('\n'))
|
s = 0
|
||||||
|
e = len(l)
|
||||||
|
while s < len(l) and l[s] == '\n': s = s + 1
|
||||||
|
while e >= 1 and l[e-1] == '\n': e = e - 1
|
||||||
|
self.lines.append(l[s:e+1])
|
||||||
|
|
||||||
def getCode(self):
|
def getCode(self):
|
||||||
""" Extract the executable Python code from the generator.
|
""" Extract the executable Python code from the generator.
|
||||||
|
|
@ -109,8 +115,14 @@ class CogGenerator(Redirectable):
|
||||||
# then remove it from all the lines.
|
# then remove it from all the lines.
|
||||||
prefIn = commonPrefix(self.markers + self.lines)
|
prefIn = commonPrefix(self.markers + self.lines)
|
||||||
if prefIn:
|
if prefIn:
|
||||||
self.markers = [ l.replace(prefIn, '', 1) for l in self.markers ]
|
tmp = []
|
||||||
self.lines = [ l.replace(prefIn, '', 1) for l in self.lines ]
|
for l in self.markers: tmp.append(replace(l, prefIn, '', 1))
|
||||||
|
self.markers = tmp
|
||||||
|
tmp = []
|
||||||
|
for l in self.lines: tmp.append(replace(l, prefIn, '', 1))
|
||||||
|
self.lines = tmp
|
||||||
|
#self.markers = [ l.replace(prefIn, '', 1) for l in self.markers ]
|
||||||
|
#self.lines = [ l.replace(prefIn, '', 1) for l in self.lines ]
|
||||||
|
|
||||||
return reindentBlock(self.lines, '')
|
return reindentBlock(self.lines, '')
|
||||||
|
|
||||||
|
|
@ -123,9 +135,14 @@ class CogGenerator(Redirectable):
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
# In Python 2.2, the last line has to end in a newline.
|
# In Python 2.2, the last line has to end in a newline.
|
||||||
intext = "import cog\n" + intext + "\n"
|
intext = "import cog\n" + replace(intext, "\r\n", "\n") + "\n"
|
||||||
|
code = None
|
||||||
|
try:
|
||||||
|
import compiler
|
||||||
|
except ImportError:
|
||||||
|
code = compile(intext, str(fname), 'exec')
|
||||||
|
if code == None:
|
||||||
code = compiler.compile(intext, filename=str(fname), mode='exec')
|
code = compiler.compile(intext, filename=str(fname), mode='exec')
|
||||||
|
|
||||||
# Make sure the "cog" module has our state.
|
# Make sure the "cog" module has our state.
|
||||||
cog.cogmodule.msg = self.msg
|
cog.cogmodule.msg = self.msg
|
||||||
cog.cogmodule.out = self.out
|
cog.cogmodule.out = self.out
|
||||||
|
|
@ -139,31 +156,31 @@ class CogGenerator(Redirectable):
|
||||||
# ends with a newline, or it will be joined to the
|
# ends with a newline, or it will be joined to the
|
||||||
# end-output line, ruining cog's idempotency.
|
# end-output line, ruining cog's idempotency.
|
||||||
if self.outstring and self.outstring[-1] != '\n':
|
if self.outstring and self.outstring[-1] != '\n':
|
||||||
self.outstring += '\n'
|
self.outstring = self.outstring + '\n'
|
||||||
|
|
||||||
return reindentBlock(self.outstring, prefOut)
|
return reindentBlock(self.outstring, prefOut)
|
||||||
|
|
||||||
def msg(self, s):
|
def msg(self, s):
|
||||||
print >>self.stdout, "Message: "+s
|
self.stdout.write("Message: "+s+"\n")
|
||||||
|
|
||||||
def out(self, sOut='', dedent=False, trimblanklines=False):
|
def out(self, sOut='', dedent=False, trimblanklines=False):
|
||||||
""" The cog.out function.
|
""" The cog.out function.
|
||||||
"""
|
"""
|
||||||
if trimblanklines and ('\n' in sOut):
|
if trimblanklines and ('\n' in sOut):
|
||||||
lines = sOut.split('\n')
|
lines = split(sOut, '\n')
|
||||||
if lines[0].strip() == '':
|
if strip(lines[0]) == '':
|
||||||
del lines[0]
|
del lines[0]
|
||||||
if lines and lines[-1].strip() == '':
|
if lines and strip(lines[-1]) == '':
|
||||||
del lines[-1]
|
del lines[-1]
|
||||||
sOut = '\n'.join(lines)+'\n'
|
sOut = join(lines,'\n')+'\n'
|
||||||
if dedent:
|
if dedent:
|
||||||
sOut = reindentBlock(sOut)
|
sOut = reindentBlock(sOut)
|
||||||
self.outstring += sOut
|
self.outstring = self.outstring + sOut
|
||||||
|
|
||||||
def outl(self, sOut='', **kw):
|
def outl(self, sOut='', dedent=False, trimblanklines=False):
|
||||||
""" The cog.outl function.
|
""" The cog.outl function.
|
||||||
"""
|
"""
|
||||||
self.out(sOut, **kw)
|
self.out(sOut, dedent, trimblanklines)
|
||||||
self.out('\n')
|
self.out('\n')
|
||||||
|
|
||||||
def error(self, msg='Error raised by cog generator.'):
|
def error(self, msg='Error raised by cog generator.'):
|
||||||
|
|
@ -185,7 +202,7 @@ class NumberedFileReader:
|
||||||
def readline(self):
|
def readline(self):
|
||||||
l = self.f.readline()
|
l = self.f.readline()
|
||||||
if l:
|
if l:
|
||||||
self.n += 1
|
self.n = self.n + 1
|
||||||
return l
|
return l
|
||||||
|
|
||||||
def linenumber(self):
|
def linenumber(self):
|
||||||
|
|
@ -225,7 +242,7 @@ class CogOptions:
|
||||||
def addToIncludePath(self, dirs):
|
def addToIncludePath(self, dirs):
|
||||||
""" Add directories to the include path.
|
""" Add directories to the include path.
|
||||||
"""
|
"""
|
||||||
dirs = dirs.split(os.pathsep)
|
dirs = split(dirs, os.pathsep)
|
||||||
self.includePath.extend(dirs)
|
self.includePath.extend(dirs)
|
||||||
|
|
||||||
def parseArgs(self, argv):
|
def parseArgs(self, argv):
|
||||||
|
|
@ -244,7 +261,7 @@ class CogOptions:
|
||||||
elif o == '-D':
|
elif o == '-D':
|
||||||
if a.count('=') < 1:
|
if a.count('=') < 1:
|
||||||
raise CogUsageError("-D takes a name=value argument")
|
raise CogUsageError("-D takes a name=value argument")
|
||||||
name, value = a.split('=', 1)
|
name, value = split(a, '=', 1)
|
||||||
self.defines[name] = value
|
self.defines[name] = value
|
||||||
elif o == '-e':
|
elif o == '-e':
|
||||||
self.bWarnEmpty = True
|
self.bWarnEmpty = True
|
||||||
|
|
@ -281,6 +298,14 @@ class CogOptions:
|
||||||
raise CogUsageError("Can't use -o with -r (they are opposites)")
|
raise CogUsageError("Can't use -o with -r (they are opposites)")
|
||||||
|
|
||||||
|
|
||||||
|
def mydigest(hasher):
|
||||||
|
result = ""
|
||||||
|
for c in hasher.digest():
|
||||||
|
x = hex(ord(c))[2:]
|
||||||
|
if len(x) == 1: x = "0" + x
|
||||||
|
result = result + x
|
||||||
|
return result
|
||||||
|
|
||||||
class Cog(Redirectable):
|
class Cog(Redirectable):
|
||||||
""" The Cog engine.
|
""" The Cog engine.
|
||||||
"""
|
"""
|
||||||
|
|
@ -298,7 +323,7 @@ class Cog(Redirectable):
|
||||||
self.installCogModule()
|
self.installCogModule()
|
||||||
|
|
||||||
def showWarning(self, msg):
|
def showWarning(self, msg):
|
||||||
print >>self.stdout, "Warning:", msg
|
self.stdout.write("Warning: " + msg + "\n")
|
||||||
|
|
||||||
def isBeginSpecLine(self, s):
|
def isBeginSpecLine(self, s):
|
||||||
return string.find(s, self.sBeginSpec) >= 0
|
return string.find(s, self.sBeginSpec) >= 0
|
||||||
|
|
@ -326,11 +351,11 @@ class Cog(Redirectable):
|
||||||
sFileIn = fname or ''
|
sFileIn = fname or ''
|
||||||
sFileOut = fname or ''
|
sFileOut = fname or ''
|
||||||
# Convert filenames to files.
|
# Convert filenames to files.
|
||||||
if isinstance(fIn, types.StringTypes):
|
if type(fIn) == type(""):
|
||||||
# Open the input file.
|
# Open the input file.
|
||||||
sFileIn = fIn
|
sFileIn = fIn
|
||||||
fIn = open(fIn, 'r')
|
fIn = open(fIn, 'r')
|
||||||
if isinstance(fOut, types.StringTypes):
|
if type(fOut) == type(""):
|
||||||
# Open the output file.
|
# Open the output file.
|
||||||
sFileOut = fOut
|
sFileOut = fOut
|
||||||
fOut = open(fOut, self.sOutputMode)
|
fOut = open(fOut, self.sOutputMode)
|
||||||
|
|
@ -383,7 +408,7 @@ class Cog(Redirectable):
|
||||||
raise CogError("Cog code markers inverted",
|
raise CogError("Cog code markers inverted",
|
||||||
file=sFileIn, line=firstLineNum)
|
file=sFileIn, line=firstLineNum)
|
||||||
else:
|
else:
|
||||||
sCode = l[beg+len(self.sBeginSpec):end].strip()
|
sCode = strip(l[beg+len(self.sBeginSpec):end])
|
||||||
gen.parseLine(sCode)
|
gen.parseLine(sCode)
|
||||||
else:
|
else:
|
||||||
# Deal with an ordinary code block.
|
# Deal with an ordinary code block.
|
||||||
|
|
@ -424,7 +449,7 @@ class Cog(Redirectable):
|
||||||
file=sFileIn, line=fIn.linenumber())
|
file=sFileIn, line=fIn.linenumber())
|
||||||
hasher.update(l)
|
hasher.update(l)
|
||||||
l = fIn.readline()
|
l = fIn.readline()
|
||||||
curHash = hasher.hexdigest()
|
curHash = mydigest(hasher)
|
||||||
|
|
||||||
if not l and not self.options.bEofCanBeEnd:
|
if not l and not self.options.bEofCanBeEnd:
|
||||||
# We reached end of file before we found the end output line.
|
# We reached end of file before we found the end output line.
|
||||||
|
|
@ -440,7 +465,7 @@ class Cog(Redirectable):
|
||||||
sGen = self.suffixLines(sGen)
|
sGen = self.suffixLines(sGen)
|
||||||
hasher.update(sGen)
|
hasher.update(sGen)
|
||||||
fOut.write(sGen)
|
fOut.write(sGen)
|
||||||
newHash = hasher.hexdigest()
|
newHash = mydigest(hasher)
|
||||||
|
|
||||||
bSawCog = True
|
bSawCog = True
|
||||||
|
|
||||||
|
|
@ -453,16 +478,16 @@ class Cog(Redirectable):
|
||||||
raise CogError("Output has been edited! Delete old checksum to unprotect.",
|
raise CogError("Output has been edited! Delete old checksum to unprotect.",
|
||||||
file=sFileIn, line=fIn.linenumber())
|
file=sFileIn, line=fIn.linenumber())
|
||||||
# Create a new end line with the correct hash.
|
# Create a new end line with the correct hash.
|
||||||
endpieces = l.split(hashMatch.group(0), 1)
|
endpieces = split(l, hashMatch.group(0), 1)
|
||||||
else:
|
else:
|
||||||
# There was no old hash, but we want a new hash.
|
# There was no old hash, but we want a new hash.
|
||||||
endpieces = l.split(self.sEndOutput, 1)
|
endpieces = split(l, self.sEndOutput, 1)
|
||||||
l = (self.sEndFormat % newHash).join(endpieces)
|
l = join(endpieces, (self.sEndFormat % newHash))
|
||||||
else:
|
else:
|
||||||
# We don't want hashes output, so if there was one, get rid of
|
# We don't want hashes output, so if there was one, get rid of
|
||||||
# it.
|
# it.
|
||||||
if hashMatch:
|
if hashMatch:
|
||||||
l = l.replace(hashMatch.groupdict()['hashsect'], '', 1)
|
l = replace(l, hashMatch.groupdict()['hashsect'], '', 1)
|
||||||
|
|
||||||
if not self.options.bDeleteCode:
|
if not self.options.bDeleteCode:
|
||||||
fOut.write(l)
|
fOut.write(l)
|
||||||
|
|
@ -480,7 +505,7 @@ class Cog(Redirectable):
|
||||||
"""
|
"""
|
||||||
if self.options.sSuffix:
|
if self.options.sSuffix:
|
||||||
# Find all non-blank lines, and add the suffix to the end.
|
# Find all non-blank lines, and add the suffix to the end.
|
||||||
repl = r"\g<0>" + self.options.sSuffix.replace('\\', '\\\\')
|
repl = r"\g<0>" + replace(self.options.sSuffix, '\\', '\\\\')
|
||||||
text = self.reNonEmptyLines.sub(repl, text)
|
text = self.reNonEmptyLines.sub(repl, text)
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
@ -500,7 +525,7 @@ class Cog(Redirectable):
|
||||||
# Need to ensure we can write.
|
# Need to ensure we can write.
|
||||||
if self.options.sMakeWritableCmd:
|
if self.options.sMakeWritableCmd:
|
||||||
# Use an external command to make the file writable.
|
# Use an external command to make the file writable.
|
||||||
cmd = self.options.sMakeWritableCmd.replace('%s', sOldPath)
|
cmd = replace(self.options.sMakeWritableCmd, '%s', sOldPath)
|
||||||
self.stdout.write(os.popen(cmd).read())
|
self.stdout.write(os.popen(cmd).read())
|
||||||
if not os.access(sOldPath, os.W_OK):
|
if not os.access(sOldPath, os.W_OK):
|
||||||
raise CogError("Couldn't make %s writable" % sOldPath)
|
raise CogError("Couldn't make %s writable" % sOldPath)
|
||||||
|
|
@ -548,7 +573,7 @@ class Cog(Redirectable):
|
||||||
elif self.options.bReplace:
|
elif self.options.bReplace:
|
||||||
# We want to replace the cog file with the output,
|
# We want to replace the cog file with the output,
|
||||||
# but only if they differ.
|
# but only if they differ.
|
||||||
print >>self.stdout, "Cogging %s" % sFile,
|
self.stdout.write("Cogging %s" % sFile)
|
||||||
bNeedNewline = True
|
bNeedNewline = True
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
@ -557,7 +582,7 @@ class Cog(Redirectable):
|
||||||
fOldFile.close()
|
fOldFile.close()
|
||||||
sNewText = self.processString(sOldText, fname=sFile)
|
sNewText = self.processString(sOldText, fname=sFile)
|
||||||
if sOldText != sNewText:
|
if sOldText != sNewText:
|
||||||
print >>self.stdout, " (changed)"
|
self.stdout.write(" (changed)\n")
|
||||||
bNeedNewline = False
|
bNeedNewline = False
|
||||||
self.replaceFile(sFile, sNewText)
|
self.replaceFile(sFile, sNewText)
|
||||||
finally:
|
finally:
|
||||||
|
|
@ -566,7 +591,7 @@ class Cog(Redirectable):
|
||||||
# same line, but also make sure to break the line before
|
# same line, but also make sure to break the line before
|
||||||
# any traceback.
|
# any traceback.
|
||||||
if bNeedNewline:
|
if bNeedNewline:
|
||||||
print >>self.stdout
|
self.stdout.write('\n')
|
||||||
else:
|
else:
|
||||||
self.processFile(sFile, self.stdout, sFile)
|
self.processFile(sFile, self.stdout, sFile)
|
||||||
finally:
|
finally:
|
||||||
|
|
@ -613,14 +638,14 @@ class Cog(Redirectable):
|
||||||
|
|
||||||
# Provide help if asked for anywhere in the command line.
|
# Provide help if asked for anywhere in the command line.
|
||||||
if '-?' in argv or '-h' in argv:
|
if '-?' in argv or '-h' in argv:
|
||||||
print >>self.stderr, usage,
|
self.stderr.write(usage)
|
||||||
return
|
return
|
||||||
|
|
||||||
self.options.parseArgs(argv)
|
self.options.parseArgs(argv)
|
||||||
self.options.validate()
|
self.options.validate()
|
||||||
|
|
||||||
if self.options.bShowVersion:
|
if self.options.bShowVersion:
|
||||||
print >>self.stdout, "Cog version %s" % __version__
|
self.stdout.write("Cog version %s\n" % __version__)
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.options.args:
|
if self.options.args:
|
||||||
|
|
@ -637,14 +662,14 @@ class Cog(Redirectable):
|
||||||
self.callableMain(argv)
|
self.callableMain(argv)
|
||||||
return 0
|
return 0
|
||||||
except CogUsageError, err:
|
except CogUsageError, err:
|
||||||
print >>self.stderr, err
|
self.stderr.write(err + "\n")
|
||||||
print >>self.stderr, "(for help use -?)"
|
self.stderr.write("(for help use -?)\n")
|
||||||
return 2
|
return 2
|
||||||
except CogGeneratedError, err:
|
except CogGeneratedError, err:
|
||||||
print >>self.stderr, "Error: %s" % err
|
self.stderr.write("Error: %s\n" % err)
|
||||||
return 3
|
return 3
|
||||||
except CogError, err:
|
except CogError, err:
|
||||||
print >>self.stderr, err
|
self.stderr.write(err + "\n")
|
||||||
return 1
|
return 1
|
||||||
except:
|
except:
|
||||||
traceback.print_exc(None, self.stderr)
|
traceback.print_exc(None, self.stderr)
|
||||||
|
|
|
||||||
|
|
@ -1,291 +0,0 @@
|
||||||
# This is the config file for the documentation generator.
|
|
||||||
# (c) 2008 Andreas Rumpf
|
|
||||||
# Feel free to edit the templates as you need.
|
|
||||||
|
|
||||||
split.item.toc = "25"
|
|
||||||
# too long entries in the table of contents get truncated
|
|
||||||
# after this number of characters
|
|
||||||
|
|
||||||
doc.section = """
|
|
||||||
<div class="section" id="$sectionID">
|
|
||||||
<h1><a class="toc-backref" href="#$sectionTitleID">$sectionTitle</a></h1>
|
|
||||||
<dl class="item">
|
|
||||||
$content
|
|
||||||
</dl></div>
|
|
||||||
"""
|
|
||||||
|
|
||||||
doc.section.toc = """
|
|
||||||
<li>
|
|
||||||
<a class="reference" href="#$sectionID" id="$sectionTitleID">$sectionTitle</a>
|
|
||||||
<ul class="simple">
|
|
||||||
$content
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
"""
|
|
||||||
|
|
||||||
doc.item = """
|
|
||||||
<dt id="$itemID"><pre>$header</pre></dt>
|
|
||||||
<dd>
|
|
||||||
$desc
|
|
||||||
</dd>
|
|
||||||
"""
|
|
||||||
|
|
||||||
doc.item.toc = """
|
|
||||||
<li><a class="reference" href="#$itemID">$name</a></li>
|
|
||||||
"""
|
|
||||||
|
|
||||||
doc.toc = """
|
|
||||||
<div class="navigation">
|
|
||||||
<p class="topic-title first">Navigation</p>
|
|
||||||
<ul class="simple">
|
|
||||||
$content
|
|
||||||
</ul>
|
|
||||||
</div>"""
|
|
||||||
|
|
||||||
doc.body_toc = """
|
|
||||||
$tableofcontents
|
|
||||||
<div class="content">
|
|
||||||
$moduledesc
|
|
||||||
$content
|
|
||||||
</div>
|
|
||||||
"""
|
|
||||||
|
|
||||||
doc.body_no_toc = """
|
|
||||||
$moduledesc
|
|
||||||
$content
|
|
||||||
"""
|
|
||||||
|
|
||||||
doc.file = """<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
|
||||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
||||||
<!-- This file is generated by Nimrod. -->
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
||||||
<title>$title</title>
|
|
||||||
<style type="text/css">
|
|
||||||
|
|
||||||
span.DecNumber {color: blue}
|
|
||||||
span.BinNumber {color: blue}
|
|
||||||
span.HexNumber {color: blue}
|
|
||||||
span.OctNumber {color: blue}
|
|
||||||
span.FloatNumber {color: blue}
|
|
||||||
span.Identifier {color: black}
|
|
||||||
span.Keyword {font-weight: bold}
|
|
||||||
span.StringLit {color: blue}
|
|
||||||
span.LongStringLit {color: blue}
|
|
||||||
span.CharLit {color: blue}
|
|
||||||
span.EscapeSequence {color: black}
|
|
||||||
span.Operator {color: black}
|
|
||||||
span.Punctation {color: black}
|
|
||||||
span.Comment, span.LongComment {font-style:italic; color: green}
|
|
||||||
span.RegularExpression {color: pink}
|
|
||||||
span.TagStart {color: yellow}
|
|
||||||
span.TagEnd {color: yellow}
|
|
||||||
span.Key {color: blue}
|
|
||||||
span.Value {color: black}
|
|
||||||
span.RawData {color: blue}
|
|
||||||
span.Assembler {color: blue}
|
|
||||||
span.Preprocessor {color: yellow}
|
|
||||||
span.Directive {color: yellow}
|
|
||||||
span.Command, span.Rule, span.Hyperlink, span.Label, span.Reference,
|
|
||||||
span.Other {color: black}
|
|
||||||
|
|
||||||
div.navigation {
|
|
||||||
float: left; width: 25em;
|
|
||||||
margin: 0; padding: 0; /*
|
|
||||||
border: 1px dashed gold; */
|
|
||||||
outline: 3px outset #99ff99; //gold;
|
|
||||||
background-color: #99ff99;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.navigation ul {list-style-type: none;}
|
|
||||||
div.navigation ul li a, div.navigation ul li a:visited {
|
|
||||||
font-weight: bold;
|
|
||||||
color: #CC0000;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
div.navigation ul li a:hover {
|
|
||||||
font-weight: bold;
|
|
||||||
text-decoration: none;
|
|
||||||
outline: 2px outset gold;
|
|
||||||
background-color: gold; /* #779977;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
div.content {
|
|
||||||
margin-left: 25em;
|
|
||||||
padding: 0 1em;
|
|
||||||
border: 1px dashed gold;
|
|
||||||
min-width: 16em;
|
|
||||||
}
|
|
||||||
|
|
||||||
dl.item dd, dl.item dd p {
|
|
||||||
margin-top:3px;
|
|
||||||
}
|
|
||||||
dl.item dd pre {
|
|
||||||
margin-left: 15pt;
|
|
||||||
border: 0px;
|
|
||||||
}
|
|
||||||
dl.item dt, dl.item dt pre {
|
|
||||||
margin: 20pt 0 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre, span.tok {
|
|
||||||
background-color:#F9F9F9;
|
|
||||||
border:1px dotted #2F6FAB;
|
|
||||||
color:black;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
:Author: David Goodger
|
|
||||||
:Contact: goodger@python.org
|
|
||||||
:Date: Date: 2006-05-21 22:44:42 +0200 (Sun, 21 May 2006)
|
|
||||||
:Revision: Revision: 4564
|
|
||||||
:Copyright: This stylesheet has been placed in the public domain.
|
|
||||||
|
|
||||||
Default cascading style sheet for the HTML output of Docutils.
|
|
||||||
|
|
||||||
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
|
|
||||||
customize this style sheet.
|
|
||||||
*/
|
|
||||||
/* used to remove borders from tables and images */
|
|
||||||
.borderless, table.borderless td, table.borderless th { border: 0 }
|
|
||||||
|
|
||||||
table.borderless td, table.borderless th {
|
|
||||||
/* Override padding for "table.docutils td" with "! important".
|
|
||||||
The right padding separates the table cells. */
|
|
||||||
padding: 0 0.5em 0 0 ! important }
|
|
||||||
|
|
||||||
.first { margin-top: 0 ! important }
|
|
||||||
.last, .with-subtitle { margin-bottom: 0 ! important }
|
|
||||||
.hidden { display: none }
|
|
||||||
a.toc-backref { text-decoration: none ; color: black }
|
|
||||||
blockquote.epigraph { margin: 2em 5em ; }
|
|
||||||
dl.docutils dd { margin-bottom: 0.5em }
|
|
||||||
div.abstract { margin: 2em 5em }
|
|
||||||
div.abstract p.topic-title { font-weight: bold ; text-align: center }
|
|
||||||
div.admonition, div.attention, div.caution, div.danger, div.error,
|
|
||||||
div.hint, div.important, div.note, div.tip, div.warning {
|
|
||||||
margin: 2em ; border: medium outset ; padding: 1em }
|
|
||||||
div.admonition p.admonition-title, div.hint p.admonition-title,
|
|
||||||
div.important p.admonition-title, div.note p.admonition-title,
|
|
||||||
div.tip p.admonition-title { font-weight: bold ; font-family: sans-serif }
|
|
||||||
|
|
||||||
div.attention p.admonition-title, div.caution p.admonition-title,
|
|
||||||
div.danger p.admonition-title, div.error p.admonition-title,
|
|
||||||
div.warning p.admonition-title { color: red ; font-weight: bold ;
|
|
||||||
font-family: sans-serif }
|
|
||||||
|
|
||||||
/* Uncomment (and remove this text!) to get reduced vertical space in
|
|
||||||
compound paragraphs.
|
|
||||||
div.compound .compound-first, div.compound .compound-middle {
|
|
||||||
margin-bottom: 0.5em }
|
|
||||||
|
|
||||||
div.compound .compound-last, div.compound .compound-middle {
|
|
||||||
margin-top: 0.5em }
|
|
||||||
*/
|
|
||||||
|
|
||||||
div.dedication { margin: 2em 5em ; text-align: center ; font-style: italic }
|
|
||||||
div.dedication p.topic-title { font-weight: bold ; font-style: normal }
|
|
||||||
div.figure { margin-left: 2em ; margin-right: 2em }
|
|
||||||
div.footer, div.header { clear: both; font-size: smaller }
|
|
||||||
div.line-block { display: block ; margin-top: 1em ; margin-bottom: 1em }
|
|
||||||
div.line-block div.line-block { margin-top: 0 ; margin-bottom: 0 ;
|
|
||||||
margin-left: 1.5em }
|
|
||||||
div.sidebar { margin-left: 1em ; border: medium outset ;
|
|
||||||
padding: 1em ; background-color: #ffffee ; width: 40% ; float: right ;
|
|
||||||
clear: right }
|
|
||||||
|
|
||||||
div.sidebar p.rubric { font-family: sans-serif ; font-size: medium }
|
|
||||||
div.system-messages { margin: 5em }
|
|
||||||
div.system-messages h1 { color: red }
|
|
||||||
div.system-message { border: medium outset ; padding: 1em }
|
|
||||||
div.system-message p.system-message-title { color: red ; font-weight: bold }
|
|
||||||
div.topic { margin: 2em;}
|
|
||||||
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
|
|
||||||
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
|
|
||||||
margin-top: 0.4em }
|
|
||||||
h1.title { text-align: center }
|
|
||||||
h2.subtitle { text-align: center }
|
|
||||||
hr.docutils { width: 75% }
|
|
||||||
img.align-left { clear: left }
|
|
||||||
img.align-right { clear: right }
|
|
||||||
ol.simple, ul.simple { margin-bottom: 1em }
|
|
||||||
ol.arabic { list-style: decimal }
|
|
||||||
ol.loweralpha { list-style: lower-alpha }
|
|
||||||
ol.upperalpha { list-style: upper-alpha }
|
|
||||||
ol.lowerroman { list-style: lower-roman }
|
|
||||||
ol.upperroman { list-style: upper-roman }
|
|
||||||
p.attribution { text-align: right ; margin-left: 50% }
|
|
||||||
p.caption { font-style: italic }
|
|
||||||
p.credits { font-style: italic ; font-size: smaller }
|
|
||||||
p.label { white-space: nowrap }
|
|
||||||
p.rubric { font-weight:bold;font-size:larger;color:maroon;text-align:center}
|
|
||||||
p.sidebar-title {font-family: sans-serif ;font-weight: bold ;font-size: larger }
|
|
||||||
p.sidebar-subtitle {font-family: sans-serif ; font-weight: bold }
|
|
||||||
p.topic-title { font-weight: bold }
|
|
||||||
pre.address { margin-bottom: 0;margin-top:0;font-family:serif;font-size:100% }
|
|
||||||
pre.literal-block, pre.doctest-block {margin-left: 2em ;margin-right: 2em }
|
|
||||||
span.classifier {font-family: sans-serif;font-style: oblique }
|
|
||||||
span.classifier-delimiter {font-family: sans-serif;font-weight: bold }
|
|
||||||
span.interpreted {font-family: sans-serif }
|
|
||||||
span.option {white-space: nowrap }
|
|
||||||
span.pre {white-space: pre }
|
|
||||||
span.problematic {color: red }
|
|
||||||
span.section-subtitle {
|
|
||||||
/* font-size relative to parent (h1..h6 element) */
|
|
||||||
font-size: 80% }
|
|
||||||
|
|
||||||
table.citation { border-left: solid 1px gray; margin-left: 1px }
|
|
||||||
table.docinfo {margin: 2em 4em }
|
|
||||||
table.docutils {margin-top: 0.5em;margin-bottom: 0.5em }
|
|
||||||
table.footnote {border-left: solid 1px black;margin-left: 1px }
|
|
||||||
|
|
||||||
table.docutils td, table.docutils th,
|
|
||||||
table.docinfo td, table.docinfo th {padding-left: 0.5em;padding-right: 0.5em;
|
|
||||||
vertical-align: top}
|
|
||||||
|
|
||||||
table.docutils th.field-name, table.docinfo th.docinfo-name {
|
|
||||||
font-weight: bold;text-align: left;white-space: nowrap;padding-left: 0 }
|
|
||||||
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
|
|
||||||
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {font-size: 100% }
|
|
||||||
ul.auto-toc { list-style-type: none }
|
|
||||||
/*a.reference { color: #E00000; font-weight:bold;}
|
|
||||||
a.reference:hover {color: #E00000;background-color: #ffff00;display: margin;
|
|
||||||
font-weight:bold;}*/
|
|
||||||
|
|
||||||
</style>
|
|
||||||
<script type="text/javascript">
|
|
||||||
//<![CDATA[
|
|
||||||
function toggleElem(id) {
|
|
||||||
var e = document.getElementById(id);
|
|
||||||
e.style.display = e.style.display == 'none' ? 'block' : 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
var gOpen = 'none'
|
|
||||||
function toggleAll() {
|
|
||||||
gOpen = gOpen == 'none' ? 'block' : 'none';
|
|
||||||
var i = 1
|
|
||||||
while (1) {
|
|
||||||
var e = document.getElementById("m"+i)
|
|
||||||
if (!e) break;
|
|
||||||
e.style.display = gOpen
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
document.getElementById('toggleButton').value =
|
|
||||||
gOpen == 'none' ? 'Show Details' : 'Hide Details';
|
|
||||||
}
|
|
||||||
//]]>
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="document" id="documentId">
|
|
||||||
<h1 class="title">$title</h1>
|
|
||||||
$content
|
|
||||||
<small>Generated: $date $time UTC</small>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
@ -9,12 +9,14 @@
|
||||||
# Environment variables cannot be used in the options, however!
|
# Environment variables cannot be used in the options, however!
|
||||||
|
|
||||||
# Just call the compiler with several options:
|
# Just call the compiler with several options:
|
||||||
cc = @if unix: gcc @else: vcc @end
|
cc = @if macosx or windows: llvm_gcc @else: gcc @end
|
||||||
lib="$nimrod/lib"
|
lib="$nimrod/lib"
|
||||||
path="$lib/base"
|
path="$lib/base"
|
||||||
path="$lib/base/gtk"
|
path="$lib/base/gtk"
|
||||||
path="$lib/base/cairo"
|
path="$lib/base/cairo"
|
||||||
path="$lib/base/x11"
|
path="$lib/base/x11"
|
||||||
|
path="$lib/base/sdl"
|
||||||
|
path="$lib/base/opengl"
|
||||||
path="$lib/windows"
|
path="$lib/windows"
|
||||||
path="$lib/posix"
|
path="$lib/posix"
|
||||||
path="$lib/ecmas"
|
path="$lib/ecmas"
|
||||||
|
|
@ -25,20 +27,23 @@ path="$lib/extra"
|
||||||
stacktrace:off
|
stacktrace:off
|
||||||
debugger:off
|
debugger:off
|
||||||
line_dir:off
|
line_dir:off
|
||||||
|
opt:speed
|
||||||
@end
|
@end
|
||||||
|
|
||||||
# additional defines:
|
# additional defines:
|
||||||
#define=""
|
#define=""
|
||||||
# additional options always passed to the compiler:
|
# additional options always passed to the compiler:
|
||||||
force_build
|
|
||||||
line_dir=off
|
line_dir=off
|
||||||
cfilecache=on
|
|
||||||
|
# use the new experimental symbol files for speeding up compilation:
|
||||||
|
#--symbol_files
|
||||||
|
--verbosity: "1"
|
||||||
|
|
||||||
hint[LineTooLong]=off
|
hint[LineTooLong]=off
|
||||||
hint[XDeclaredButNotUsed]=off
|
hint[XDeclaredButNotUsed]=off
|
||||||
|
|
||||||
@if unix:
|
@if unix:
|
||||||
passl= "-ldl"
|
@if not bsd: passl= "-ldl" @end
|
||||||
path = "$lib/base/gtk"
|
path = "$lib/base/gtk"
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
@ -50,10 +55,12 @@ hint[XDeclaredButNotUsed]=off
|
||||||
# Configuration for the LLVM GCC compiler:
|
# Configuration for the LLVM GCC compiler:
|
||||||
@if windows:
|
@if windows:
|
||||||
llvm_gcc.path = r"$nimrod\dist\llvm-gcc4.2\bin"
|
llvm_gcc.path = r"$nimrod\dist\llvm-gcc4.2\bin"
|
||||||
|
@elif macosx:
|
||||||
|
llvm_gcc.path = r"/Users/andreasrumpf/download/C/llvm-gcc4.2-2.3-x86-darwin8/bin"
|
||||||
@end
|
@end
|
||||||
llvm_gcc.options.debug = "-g"
|
llvm_gcc.options.debug = "-g"
|
||||||
llvm_gcc.options.always = "-w"
|
llvm_gcc.options.always = "-w"
|
||||||
llvm_gcc.options.speed = "-O3 -ffast-math"
|
llvm_gcc.options.speed = "-O2 -fno-strict-aliasing -ffast-math"
|
||||||
llvm_gcc.options.size = "-Os -ffast-math"
|
llvm_gcc.options.size = "-Os -ffast-math"
|
||||||
|
|
||||||
# Configuration for the Borland C++ Compiler:
|
# Configuration for the Borland C++ Compiler:
|
||||||
|
|
@ -62,23 +69,24 @@ llvm_gcc.options.size = "-Os -ffast-math"
|
||||||
@end
|
@end
|
||||||
bcc.options.debug = ""
|
bcc.options.debug = ""
|
||||||
# turn off warnings about unreachable code and inline procs:
|
# turn off warnings about unreachable code and inline procs:
|
||||||
bcc.options.always = "-w- -H- -q -RT- -a8 -w-8027 -w-8066"
|
bcc.options.always = "-H- -q -RT- -a8 -w-8027 -w-8066 -w-8004"
|
||||||
bcc.options.speed = "-O2 -6"
|
bcc.options.speed = "-O2 -6"
|
||||||
bcc.options.size = "-O1 -6"
|
bcc.options.size = "-O1 -6"
|
||||||
|
|
||||||
# Configuration for the Visual C/C++ compiler:
|
# Configuration for the Visual C/C++ compiler:
|
||||||
@if vcc:
|
@if vcc:
|
||||||
@prepend_env path r"C:\Eigenes\compiler\vcc2005\Common7\IDE;"
|
@prepend_env path r"C:\Programme\Microsoft Visual Studio 9.0\Common7\IDE;"
|
||||||
@prepend_env INCLUDE r"C:\Eigenes\compiler\vcc2005\VC\include;C:\Eigenes\compiler\vcc2005\VC\ATLMFC\INCLUDE;"
|
@prepend_env INCLUDE r"C:\Programme\Microsoft Visual Studio 9.0\VC\include;C:\Programme\Microsoft Visual Studio 9.0\VC\ATLMFC\INCLUDE;C:\Programme\Microsoft SDKs\Windows\v6.0A\Include;"
|
||||||
@prepend_env LIB r"C:\Eigenes\compiler\vcc2005\VC\lib;C:\Eigenes\compiler\vcc2005\SDK\v2.0\Lib;"
|
@prepend_env LIB r"C:\Programme\Microsoft Visual Studio 9.0\VC\lib;C:\Programme\Microsoft Visual Studio 9.0\SDK\v2.0\Lib;C:\Programme\Microsoft SDKs\Windows\v6.0A\Lib;"
|
||||||
|
passl: r"/F33554432" # set the stack size to 8 MB
|
||||||
@end
|
@end
|
||||||
@if windows:
|
@if windows:
|
||||||
vcc.path = r"C:\Eigenes\compiler\vcc2005\VC\bin"
|
vcc.path = r"C:\Programme\Microsoft Visual Studio 9.0\VC\bin"
|
||||||
@end
|
@end
|
||||||
vcc.options.debug = "/RTC1 /ZI"
|
vcc.options.debug = "/RTC1 /ZI"
|
||||||
vcc.options.always = "/nologo"
|
vcc.options.always = "/nologo"
|
||||||
vcc.options.speed = "/Ogityb2 /G7 /arch:SSE2"
|
vcc.options.speed = "/Ox /arch:SSE2"
|
||||||
vcc.options.size = "/O1 /G7"
|
vcc.options.size = "/O1"
|
||||||
|
|
||||||
# Configuration for the Watcom C/C++ compiler:
|
# Configuration for the Watcom C/C++ compiler:
|
||||||
@if windows:
|
@if windows:
|
||||||
|
|
@ -122,10 +130,11 @@ lcc.options.size = "-O -p6"
|
||||||
|
|
||||||
# Configuration for the Tiny C Compiler:
|
# Configuration for the Tiny C Compiler:
|
||||||
@if windows:
|
@if windows:
|
||||||
tcc.path = r"C:\eigenes\compiler\tcc\bin"
|
tcc.path = r"C:\Eigenes\compiler\tcc-0.9.23\tcc"
|
||||||
|
tcc.options.always = r"-IC:\Eigenes\compiler\tcc-0.9.23\include " &
|
||||||
|
r"-IC:\Eigenes\compiler\tcc-0.9.23\include\winapi"
|
||||||
@end
|
@end
|
||||||
tcc.options.debug = "-b"
|
tcc.options.debug = ""
|
||||||
tcc.options.always = ""
|
|
||||||
tcc.options.speed = ""
|
tcc.options.speed = ""
|
||||||
tcc.options.size = ""
|
tcc.options.size = ""
|
||||||
|
|
||||||
|
|
@ -146,7 +155,7 @@ icc.options.always = "-w"
|
||||||
icc.options.speed = "-O3 -ffast-math"
|
icc.options.speed = "-O3 -ffast-math"
|
||||||
icc.options.size = "-Os -ffast-math"
|
icc.options.size = "-Os -ffast-math"
|
||||||
|
|
||||||
@write "used default config file"
|
@write "used special config file"
|
||||||
|
|
||||||
@if ecmascript:
|
@if ecmascript:
|
||||||
@write "Target is ECMAScript! No unsafe features are allowed!"
|
@write "Target is ECMAScript! No unsafe features are allowed!"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
# Configuration file for the Nimrod Compiler.
|
# Configuration file for the Nimrod Compiler.
|
||||||
# Generated by the koch.py script.
|
|
||||||
# (c) 2008 Andreas Rumpf
|
# (c) 2008 Andreas Rumpf
|
||||||
|
|
||||||
# Feel free to edit the default values as you need.
|
# Feel free to edit the default values as you need.
|
||||||
|
|
@ -8,38 +7,42 @@
|
||||||
# @putenv "key" "val"
|
# @putenv "key" "val"
|
||||||
# Environment variables cannot be used in the options, however!
|
# Environment variables cannot be used in the options, however!
|
||||||
|
|
||||||
# Just call the compiler with several options:
|
cc = @if windows: llvm_gcc @else: gcc @end
|
||||||
cc = @if unix: gcc @else: vcc @end
|
|
||||||
lib="$nimrod/lib"
|
lib="$nimrod/lib"
|
||||||
path="$lib/base"
|
path="$lib/base"
|
||||||
path="$lib/base/gtk"
|
path="$lib/base/gtk"
|
||||||
path="$lib/base/cairo"
|
path="$lib/base/cairo"
|
||||||
path="$lib/base/x11"
|
path="$lib/base/x11"
|
||||||
|
path="$lib/base/sdl"
|
||||||
|
path="$lib/base/opengl"
|
||||||
|
path="$lib/base/zip"
|
||||||
path="$lib/windows"
|
path="$lib/windows"
|
||||||
path="$lib/posix"
|
path="$lib/posix"
|
||||||
path="$lib/ecmas"
|
path="$lib/ecmas"
|
||||||
path="$lib/extra"
|
path="$lib/extra"
|
||||||
|
|
||||||
@if release:
|
@if release:
|
||||||
checks:off
|
obj_checks:off
|
||||||
|
field_checks:off
|
||||||
|
range_checks:off
|
||||||
|
bound_checks:off
|
||||||
|
overflow_checks:off
|
||||||
|
assertions:off
|
||||||
|
|
||||||
stacktrace:off
|
stacktrace:off
|
||||||
debugger:off
|
debugger:off
|
||||||
line_dir:off
|
line_dir:off
|
||||||
|
opt:speed
|
||||||
@end
|
@end
|
||||||
|
|
||||||
# additional defines:
|
|
||||||
#define=""
|
|
||||||
# additional options always passed to the compiler:
|
# additional options always passed to the compiler:
|
||||||
force_build
|
--verbosity: "1"
|
||||||
line_dir=off
|
|
||||||
cfilecache=on
|
|
||||||
|
|
||||||
hint[LineTooLong]=off
|
hint[LineTooLong]=off
|
||||||
hint[XDeclaredButNotUsed]=off
|
#hint[XDeclaredButNotUsed]=off
|
||||||
|
|
||||||
@if unix:
|
@if unix:
|
||||||
passl= "-ldl"
|
@if not bsd: passl= "-ldl" @end
|
||||||
path = "$lib/base/gtk"
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@if icc:
|
@if icc:
|
||||||
|
|
@ -50,76 +53,43 @@ hint[XDeclaredButNotUsed]=off
|
||||||
# Configuration for the LLVM GCC compiler:
|
# Configuration for the LLVM GCC compiler:
|
||||||
@if windows:
|
@if windows:
|
||||||
llvm_gcc.path = r"$nimrod\dist\llvm-gcc4.2\bin"
|
llvm_gcc.path = r"$nimrod\dist\llvm-gcc4.2\bin"
|
||||||
|
@elif macosx:
|
||||||
|
llvm_gcc.path =
|
||||||
|
r"/Users/andreasrumpf/download/C/llvm-gcc4.2-2.3-x86-darwin8/bin"
|
||||||
@end
|
@end
|
||||||
llvm_gcc.options.debug = "-g"
|
llvm_gcc.options.debug = "-g"
|
||||||
llvm_gcc.options.always = "-w"
|
llvm_gcc.options.always = "-w"
|
||||||
llvm_gcc.options.speed = "-O3 -ffast-math"
|
llvm_gcc.options.speed = "-O2"
|
||||||
llvm_gcc.options.size = "-Os -ffast-math"
|
llvm_gcc.options.size = "-Os"
|
||||||
|
|
||||||
# Configuration for the Borland C++ Compiler:
|
|
||||||
@if windows:
|
|
||||||
bcc.path = r"C:\eigenes\compiler\cbuilder5\bin"
|
|
||||||
@end
|
|
||||||
bcc.options.debug = ""
|
|
||||||
# turn off warnings about unreachable code and inline procs:
|
|
||||||
bcc.options.always = "-w- -H- -q -RT- -a8 -w-8027 -w-8066"
|
|
||||||
bcc.options.speed = "-O2 -6"
|
|
||||||
bcc.options.size = "-O1 -6"
|
|
||||||
|
|
||||||
# Configuration for the Visual C/C++ compiler:
|
# Configuration for the Visual C/C++ compiler:
|
||||||
@if vcc:
|
@if vcc:
|
||||||
@prepend_env path r"C:\Programme\Microsoft Visual Studio 9.0\Common7\IDE;"
|
|
||||||
@prepend_env INCLUDE r"C:\Programme\Microsoft Visual Studio 9.0\VC\include;C:\Programme\Microsoft Visual Studio 9.0\VC\ATLMFC\INCLUDE;C:\Programme\Microsoft SDKs\Windows\v6.0A\Include;"
|
|
||||||
@prepend_env LIB r"C:\Programme\Microsoft Visual Studio 9.0\VC\lib;C:\Programme\Microsoft Visual Studio 9.0\SDK\v2.0\Lib;C:\Programme\Microsoft SDKs\Windows\v6.0A\Lib;"
|
|
||||||
passl: r"/F33554432" # set the stack size to 8 MB
|
passl: r"/F33554432" # set the stack size to 8 MB
|
||||||
@end
|
@end
|
||||||
@if windows:
|
|
||||||
vcc.path = r"C:\Programme\Microsoft Visual Studio 9.0\VC\bin"
|
|
||||||
@end
|
|
||||||
vcc.options.debug = "/RTC1 /ZI"
|
vcc.options.debug = "/RTC1 /ZI"
|
||||||
vcc.options.always = "/nologo"
|
vcc.options.always = "/nologo"
|
||||||
vcc.options.speed = "/Ogityb2 /G7 /arch:SSE2"
|
vcc.options.speed = "/Ox /arch:SSE2"
|
||||||
vcc.options.size = "/O1 /G7"
|
vcc.options.size = "/O1"
|
||||||
|
|
||||||
# Configuration for the Watcom C/C++ compiler:
|
|
||||||
@if windows:
|
|
||||||
wcc.path = r"C:\eigenes\compiler\watcom\binnt"
|
|
||||||
@end
|
|
||||||
wcc.options.debug = "-d2"
|
|
||||||
wcc.options.always = "-6 -zw -w-"
|
|
||||||
wcc.options.speed = "-ox -on -6 -d0 -fp6 -zW"
|
|
||||||
wcc.options.size = "-ox -on -6 -d0 -fp6 -zW"
|
|
||||||
|
|
||||||
# Configuration for the GNU C/C++ compiler:
|
# Configuration for the GNU C/C++ compiler:
|
||||||
@if windows:
|
@if windows:
|
||||||
gcc.path = r"C:\eigenes\compiler\mingw\bin"
|
gcc.path = r"C:\eigenes\compiler\mingw\bin"
|
||||||
@end
|
@end
|
||||||
|
#gcc.exe = "gcc-4.1"
|
||||||
|
#gcc.linkerExe = "gcc-4.1"
|
||||||
gcc.options.debug = "-g"
|
gcc.options.debug = "-g"
|
||||||
@if macosx:
|
@if macosx:
|
||||||
gcc.options.always = "-w -fasm-blocks"
|
gcc.options.always = "-w -fasm-blocks"
|
||||||
@else:
|
@else:
|
||||||
gcc.options.always = "-w"
|
gcc.options.always = "-w"
|
||||||
@end
|
@end
|
||||||
gcc.options.speed = "-O3 -ffast-math"
|
gcc.options.speed = "-O3 -fno-strict-aliasing"
|
||||||
gcc.options.size = "-Os -ffast-math"
|
gcc.options.size = "-Os"
|
||||||
|
|
||||||
# Configuration for the Digital Mars C/C++ compiler:
|
# Configuration for the Digital Mars C/C++ compiler:
|
||||||
@if windows:
|
@if windows:
|
||||||
dmc.path = r"C:\eigenes\compiler\d\dm\bin"
|
dmc.path = r"C:\eigenes\compiler\d\dm\bin"
|
||||||
@end
|
@end
|
||||||
dmc.options.debug = "-g"
|
|
||||||
dmc.options.always = "-Jm"
|
|
||||||
dmc.options.speed = "-ff -o -6"
|
|
||||||
dmc.options.size = "-ff -o -6"
|
|
||||||
|
|
||||||
# Configuration for the LCC compiler:
|
|
||||||
@if windows:
|
|
||||||
lcc.path = r"C:\eigenes\compiler\lcc\bin"
|
|
||||||
@end
|
|
||||||
lcc.options.debug = "-g5"
|
|
||||||
lcc.options.always = "-e1"
|
|
||||||
lcc.options.speed = "-O -p6"
|
|
||||||
lcc.options.size = "-O -p6"
|
|
||||||
|
|
||||||
# Configuration for the Tiny C Compiler:
|
# Configuration for the Tiny C Compiler:
|
||||||
@if windows:
|
@if windows:
|
||||||
|
|
@ -127,30 +97,4 @@ lcc.options.size = "-O -p6"
|
||||||
tcc.options.always = r"-IC:\Eigenes\compiler\tcc-0.9.23\include " &
|
tcc.options.always = r"-IC:\Eigenes\compiler\tcc-0.9.23\include " &
|
||||||
r"-IC:\Eigenes\compiler\tcc-0.9.23\include\winapi"
|
r"-IC:\Eigenes\compiler\tcc-0.9.23\include\winapi"
|
||||||
@end
|
@end
|
||||||
tcc.options.debug = ""
|
tcc.options.always = "-w"
|
||||||
tcc.options.speed = ""
|
|
||||||
tcc.options.size = ""
|
|
||||||
|
|
||||||
# Configuration for the Pelles C compiler:
|
|
||||||
@if windows:
|
|
||||||
pcc.path = r"C:\eigenes\compiler\pellesc\bin"
|
|
||||||
@end
|
|
||||||
pcc.options.debug = "-Zi"
|
|
||||||
pcc.options.always = "-Ze"
|
|
||||||
pcc.options.speed = "-Ox"
|
|
||||||
pcc.options.size = "-Os"
|
|
||||||
|
|
||||||
@if windows:
|
|
||||||
icc.path = r"c:\eignes\compiler\icc\bin"
|
|
||||||
@end
|
|
||||||
icc.options.debug = "-g"
|
|
||||||
icc.options.always = "-w"
|
|
||||||
icc.options.speed = "-O3 -ffast-math"
|
|
||||||
icc.options.size = "-Os -ffast-math"
|
|
||||||
|
|
||||||
@write "used special config file"
|
|
||||||
|
|
||||||
@if ecmascript:
|
|
||||||
@write "Target is ECMAScript! No unsafe features are allowed!"
|
|
||||||
@end
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,287 +0,0 @@
|
||||||
# This is the config file for the documentation generator.
|
|
||||||
# (c) 2008 Andreas Rumpf
|
|
||||||
# Feel free to edit the templates as you need.
|
|
||||||
|
|
||||||
doc.section = """
|
|
||||||
<div class="section" id="$sectionID">
|
|
||||||
<h1><a class="toc-backref" href="#$sectionTitleID">$sectionTitle</a></h1>
|
|
||||||
<dl class="item">
|
|
||||||
$content
|
|
||||||
</dl></div>
|
|
||||||
"""
|
|
||||||
|
|
||||||
doc.section.toc = """
|
|
||||||
<li>
|
|
||||||
<a class="reference" href="#$sectionID" id="$sectionTitleID">$sectionTitle</a>
|
|
||||||
<ul class="simple">
|
|
||||||
$content
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
"""
|
|
||||||
|
|
||||||
doc.item = """
|
|
||||||
<dt id="$itemID"><pre>$header</pre></dt>
|
|
||||||
<dd>
|
|
||||||
$desc
|
|
||||||
</dd>
|
|
||||||
"""
|
|
||||||
|
|
||||||
doc.item.toc = """
|
|
||||||
<li><a class="reference" href="#$itemID">$name</a></li>
|
|
||||||
"""
|
|
||||||
|
|
||||||
doc.toc = """
|
|
||||||
<div class="navigation">
|
|
||||||
<p class="topic-title first">Navigation</p>
|
|
||||||
<ul class="simple">
|
|
||||||
$content
|
|
||||||
</ul>
|
|
||||||
</div>"""
|
|
||||||
|
|
||||||
doc.body_toc = """
|
|
||||||
$tableofcontents
|
|
||||||
<div class="content">
|
|
||||||
$moduledesc
|
|
||||||
$content
|
|
||||||
</div>
|
|
||||||
"""
|
|
||||||
|
|
||||||
doc.body_no_toc = """
|
|
||||||
$moduledesc
|
|
||||||
$content
|
|
||||||
"""
|
|
||||||
|
|
||||||
doc.file = """<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
|
||||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
||||||
<!-- This file is generated by Nimrod. -->
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
||||||
<title>$title</title>
|
|
||||||
<style type="text/css">
|
|
||||||
|
|
||||||
span.DecNumber {color: blue}
|
|
||||||
span.BinNumber {color: blue}
|
|
||||||
span.HexNumber {color: blue}
|
|
||||||
span.OctNumber {color: blue}
|
|
||||||
span.FloatNumber {color: blue}
|
|
||||||
span.Identifier {color: black}
|
|
||||||
span.Keyword {font-weight: bold}
|
|
||||||
span.StringLit {color: blue}
|
|
||||||
span.LongStringLit {color: blue}
|
|
||||||
span.CharLit {color: blue}
|
|
||||||
span.EscapeSequence {color: black}
|
|
||||||
span.Operator {color: black}
|
|
||||||
span.Punctation {color: black}
|
|
||||||
span.Comment, span.LongComment {font-style:italic; color: green}
|
|
||||||
span.RegularExpression {color: pink}
|
|
||||||
span.TagStart {color: yellow}
|
|
||||||
span.TagEnd {color: yellow}
|
|
||||||
span.Key {color: blue}
|
|
||||||
span.Value {color: black}
|
|
||||||
span.RawData {color: blue}
|
|
||||||
span.Assembler {color: blue}
|
|
||||||
span.Preprocessor {color: yellow}
|
|
||||||
span.Directive {color: yellow}
|
|
||||||
span.Command, span.Rule, span.Hyperlink, span.Label, span.Reference,
|
|
||||||
span.Other {color: black}
|
|
||||||
|
|
||||||
div.navigation {
|
|
||||||
float: left; width: 20em;
|
|
||||||
margin: 0; padding: 0; /*
|
|
||||||
border: 1px dashed gold; */
|
|
||||||
outline: 3px outset #99ff99; //gold;
|
|
||||||
background-color: #99ff99;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.navigation ul {list-style-type: none;}
|
|
||||||
div.navigation ul li a, div.navigation ul li a:visited {
|
|
||||||
font-weight: bold;
|
|
||||||
color: #CC0000;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
div.navigation ul li a:hover {
|
|
||||||
font-weight: bold;
|
|
||||||
text-decoration: none;
|
|
||||||
outline: 2px outset gold;
|
|
||||||
background-color: gold; /* #779977;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
div.content {
|
|
||||||
margin-left: 20em;
|
|
||||||
padding: 0 1em;
|
|
||||||
border: 1px dashed gold;
|
|
||||||
min-width: 16em;
|
|
||||||
}
|
|
||||||
|
|
||||||
dl.item dd, dl.item dd p {
|
|
||||||
margin-top:3px;
|
|
||||||
}
|
|
||||||
dl.item dd pre {
|
|
||||||
margin-left: 15pt;
|
|
||||||
border: 0px;
|
|
||||||
}
|
|
||||||
dl.item dt, dl.item dt pre {
|
|
||||||
margin: 20pt 0 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre, span.tok {
|
|
||||||
background-color:#F9F9F9;
|
|
||||||
border:1px dotted #2F6FAB;
|
|
||||||
color:black;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
:Author: David Goodger
|
|
||||||
:Contact: goodger@python.org
|
|
||||||
:Date: Date: 2006-05-21 22:44:42 +0200 (Sun, 21 May 2006)
|
|
||||||
:Revision: Revision: 4564
|
|
||||||
:Copyright: This stylesheet has been placed in the public domain.
|
|
||||||
|
|
||||||
Default cascading style sheet for the HTML output of Docutils.
|
|
||||||
|
|
||||||
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
|
|
||||||
customize this style sheet.
|
|
||||||
*/
|
|
||||||
/* used to remove borders from tables and images */
|
|
||||||
.borderless, table.borderless td, table.borderless th { border: 0 }
|
|
||||||
|
|
||||||
table.borderless td, table.borderless th {
|
|
||||||
/* Override padding for "table.docutils td" with "! important".
|
|
||||||
The right padding separates the table cells. */
|
|
||||||
padding: 0 0.5em 0 0 ! important }
|
|
||||||
|
|
||||||
.first { margin-top: 0 ! important }
|
|
||||||
.last, .with-subtitle { margin-bottom: 0 ! important }
|
|
||||||
.hidden { display: none }
|
|
||||||
a.toc-backref { text-decoration: none ; color: black }
|
|
||||||
blockquote.epigraph { margin: 2em 5em ; }
|
|
||||||
dl.docutils dd { margin-bottom: 0.5em }
|
|
||||||
div.abstract { margin: 2em 5em }
|
|
||||||
div.abstract p.topic-title { font-weight: bold ; text-align: center }
|
|
||||||
div.admonition, div.attention, div.caution, div.danger, div.error,
|
|
||||||
div.hint, div.important, div.note, div.tip, div.warning {
|
|
||||||
margin: 2em ; border: medium outset ; padding: 1em }
|
|
||||||
div.admonition p.admonition-title, div.hint p.admonition-title,
|
|
||||||
div.important p.admonition-title, div.note p.admonition-title,
|
|
||||||
div.tip p.admonition-title { font-weight: bold ; font-family: sans-serif }
|
|
||||||
|
|
||||||
div.attention p.admonition-title, div.caution p.admonition-title,
|
|
||||||
div.danger p.admonition-title, div.error p.admonition-title,
|
|
||||||
div.warning p.admonition-title { color: red ; font-weight: bold ;
|
|
||||||
font-family: sans-serif }
|
|
||||||
|
|
||||||
/* Uncomment (and remove this text!) to get reduced vertical space in
|
|
||||||
compound paragraphs.
|
|
||||||
div.compound .compound-first, div.compound .compound-middle {
|
|
||||||
margin-bottom: 0.5em }
|
|
||||||
|
|
||||||
div.compound .compound-last, div.compound .compound-middle {
|
|
||||||
margin-top: 0.5em }
|
|
||||||
*/
|
|
||||||
|
|
||||||
div.dedication { margin: 2em 5em ; text-align: center ; font-style: italic }
|
|
||||||
div.dedication p.topic-title { font-weight: bold ; font-style: normal }
|
|
||||||
div.figure { margin-left: 2em ; margin-right: 2em }
|
|
||||||
div.footer, div.header { clear: both; font-size: smaller }
|
|
||||||
div.line-block { display: block ; margin-top: 1em ; margin-bottom: 1em }
|
|
||||||
div.line-block div.line-block { margin-top: 0 ; margin-bottom: 0 ;
|
|
||||||
margin-left: 1.5em }
|
|
||||||
div.sidebar { margin-left: 1em ; border: medium outset ;
|
|
||||||
padding: 1em ; background-color: #ffffee ; width: 40% ; float: right ;
|
|
||||||
clear: right }
|
|
||||||
|
|
||||||
div.sidebar p.rubric { font-family: sans-serif ; font-size: medium }
|
|
||||||
div.system-messages { margin: 5em }
|
|
||||||
div.system-messages h1 { color: red }
|
|
||||||
div.system-message { border: medium outset ; padding: 1em }
|
|
||||||
div.system-message p.system-message-title { color: red ; font-weight: bold }
|
|
||||||
div.topic { margin: 2em;}
|
|
||||||
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
|
|
||||||
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
|
|
||||||
margin-top: 0.4em }
|
|
||||||
h1.title { text-align: center }
|
|
||||||
h2.subtitle { text-align: center }
|
|
||||||
hr.docutils { width: 75% }
|
|
||||||
img.align-left { clear: left }
|
|
||||||
img.align-right { clear: right }
|
|
||||||
ol.simple, ul.simple { margin-bottom: 1em }
|
|
||||||
ol.arabic { list-style: decimal }
|
|
||||||
ol.loweralpha { list-style: lower-alpha }
|
|
||||||
ol.upperalpha { list-style: upper-alpha }
|
|
||||||
ol.lowerroman { list-style: lower-roman }
|
|
||||||
ol.upperroman { list-style: upper-roman }
|
|
||||||
p.attribution { text-align: right ; margin-left: 50% }
|
|
||||||
p.caption { font-style: italic }
|
|
||||||
p.credits { font-style: italic ; font-size: smaller }
|
|
||||||
p.label { white-space: nowrap }
|
|
||||||
p.rubric { font-weight:bold;font-size:larger;color:maroon;text-align:center}
|
|
||||||
p.sidebar-title {font-family: sans-serif ;font-weight: bold ;font-size: larger }
|
|
||||||
p.sidebar-subtitle {font-family: sans-serif ; font-weight: bold }
|
|
||||||
p.topic-title { font-weight: bold }
|
|
||||||
pre.address { margin-bottom: 0;margin-top:0;font-family:serif;font-size:100% }
|
|
||||||
pre.literal-block, pre.doctest-block {margin-left: 2em ;margin-right: 2em }
|
|
||||||
span.classifier {font-family: sans-serif;font-style: oblique }
|
|
||||||
span.classifier-delimiter {font-family: sans-serif;font-weight: bold }
|
|
||||||
span.interpreted {font-family: sans-serif }
|
|
||||||
span.option {white-space: nowrap }
|
|
||||||
span.pre {white-space: pre }
|
|
||||||
span.problematic {color: red }
|
|
||||||
span.section-subtitle {
|
|
||||||
/* font-size relative to parent (h1..h6 element) */
|
|
||||||
font-size: 80% }
|
|
||||||
|
|
||||||
table.citation { border-left: solid 1px gray; margin-left: 1px }
|
|
||||||
table.docinfo {margin: 2em 4em }
|
|
||||||
table.docutils {margin-top: 0.5em;margin-bottom: 0.5em }
|
|
||||||
table.footnote {border-left: solid 1px black;margin-left: 1px }
|
|
||||||
|
|
||||||
table.docutils td, table.docutils th,
|
|
||||||
table.docinfo td, table.docinfo th {padding-left: 0.5em;padding-right: 0.5em;
|
|
||||||
vertical-align: top}
|
|
||||||
|
|
||||||
table.docutils th.field-name, table.docinfo th.docinfo-name {
|
|
||||||
font-weight: bold;text-align: left;white-space: nowrap;padding-left: 0 }
|
|
||||||
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
|
|
||||||
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {font-size: 100% }
|
|
||||||
ul.auto-toc { list-style-type: none }
|
|
||||||
/*a.reference { color: #E00000; font-weight:bold;}
|
|
||||||
a.reference:hover {color: #E00000;background-color: #ffff00;display: margin;
|
|
||||||
font-weight:bold;}*/
|
|
||||||
|
|
||||||
</style>
|
|
||||||
<script type="text/javascript">
|
|
||||||
//<![CDATA[
|
|
||||||
function toggleElem(id) {
|
|
||||||
var e = document.getElementById(id);
|
|
||||||
e.style.display = e.style.display == 'none' ? 'block' : 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
var gOpen = 'none'
|
|
||||||
function toggleAll() {
|
|
||||||
gOpen = gOpen == 'none' ? 'block' : 'none';
|
|
||||||
var i = 1
|
|
||||||
while (1) {
|
|
||||||
var e = document.getElementById("m"+i)
|
|
||||||
if (!e) break;
|
|
||||||
e.style.display = gOpen
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
document.getElementById('toggleButton').value =
|
|
||||||
gOpen == 'none' ? 'Show Details' : 'Hide Details';
|
|
||||||
}
|
|
||||||
//]]>
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="document" id="documentId">
|
|
||||||
<h1 class="title">$title</h1>
|
|
||||||
$content
|
|
||||||
<small>Generated: $date $time UTC</small>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
@ -1,165 +0,0 @@
|
||||||
# Configuration file for the Nimrod Compiler.
|
|
||||||
# Generated by the koch.py script.
|
|
||||||
# (c) 2008 Andreas Rumpf
|
|
||||||
|
|
||||||
# Feel free to edit the default values as you need.
|
|
||||||
|
|
||||||
# You may set environment variables with
|
|
||||||
# @putenv "key" "val"
|
|
||||||
# Environment variables cannot be used in the options, however!
|
|
||||||
|
|
||||||
# Just call the compiler with several options:
|
|
||||||
cc = @if unix: gcc @else: vcc @end
|
|
||||||
lib="$nimrod/lib"
|
|
||||||
path="$lib/base"
|
|
||||||
path="$lib/base/gtk"
|
|
||||||
path="$lib/base/cairo"
|
|
||||||
path="$lib/base/x11"
|
|
||||||
path="$lib/windows"
|
|
||||||
path="$lib/posix"
|
|
||||||
path="$lib/ecmas"
|
|
||||||
path="$lib/extra"
|
|
||||||
|
|
||||||
@if release:
|
|
||||||
checks:off
|
|
||||||
stacktrace:off
|
|
||||||
debugger:off
|
|
||||||
line_dir:off
|
|
||||||
@end
|
|
||||||
|
|
||||||
# additional defines:
|
|
||||||
#define=""
|
|
||||||
# additional options always passed to the compiler:
|
|
||||||
force_build
|
|
||||||
line_dir=off
|
|
||||||
cfilecache=on
|
|
||||||
|
|
||||||
hint[LineTooLong]=off
|
|
||||||
hint[XDeclaredButNotUsed]=off
|
|
||||||
|
|
||||||
@if unix:
|
|
||||||
passl= "-ldl"
|
|
||||||
path = "$lib/base/gtk"
|
|
||||||
@end
|
|
||||||
|
|
||||||
@if icc:
|
|
||||||
passl = "-cxxlib"
|
|
||||||
passc = "-cxxlib"
|
|
||||||
@end
|
|
||||||
|
|
||||||
# Configuration for the LLVM GCC compiler:
|
|
||||||
@if windows:
|
|
||||||
llvm_gcc.path = r"$nimrod\dist\llvm-gcc4.2\bin"
|
|
||||||
@end
|
|
||||||
llvm_gcc.options.debug = "-g"
|
|
||||||
llvm_gcc.options.always = "-w"
|
|
||||||
llvm_gcc.options.speed = "-O3 -ffast-math"
|
|
||||||
llvm_gcc.options.size = "-Os -ffast-math"
|
|
||||||
|
|
||||||
# Configuration for the Borland C++ Compiler:
|
|
||||||
@if windows:
|
|
||||||
bcc.path = r"C:\eigenes\compiler\cbuilder5\bin"
|
|
||||||
@end
|
|
||||||
bcc.options.debug = ""
|
|
||||||
# turn off warnings about unreachable code and inline procs:
|
|
||||||
bcc.options.always = "-w- -H- -q -RT- -a8 -w-8027 -w-8066"
|
|
||||||
bcc.options.speed = "-O2 -6"
|
|
||||||
bcc.options.size = "-O1 -6"
|
|
||||||
|
|
||||||
# Configuration for the Visual C/C++ compiler:
|
|
||||||
#@if vcc:
|
|
||||||
# @prepend_env path r"C:\Eigenes\compiler\vcc2005\Common7\IDE;"
|
|
||||||
# @prepend_env INCLUDE r"C:\Eigenes\compiler\vcc2005\VC\include;C:\Eigenes\compiler\vcc2005\VC\ATLMFC\INCLUDE;"
|
|
||||||
# @prepend_env LIB r"C:\Eigenes\compiler\vcc2005\VC\lib;C:\Eigenes\compiler\vcc2005\SDK\v2.0\Lib;"
|
|
||||||
#@end
|
|
||||||
#@if windows:
|
|
||||||
# vcc.path = r"C:\Eigenes\compiler\vcc2005\VC\bin"
|
|
||||||
#@end
|
|
||||||
|
|
||||||
@if vcc:
|
|
||||||
@prepend_env path r"C:\Programme\Microsoft Visual Studio 9.0\Common7\IDE;"
|
|
||||||
@prepend_env INCLUDE r"C:\Programme\Microsoft Visual Studio 9.0\VC\include;C:\Programme\Microsoft Visual Studio 9.0\VC\ATLMFC\INCLUDE;C:\Programme\Microsoft SDKs\Windows\v6.0A\Include;"
|
|
||||||
@prepend_env LIB r"C:\Programme\Microsoft Visual Studio 9.0\VC\lib;C:\Programme\Microsoft Visual Studio 9.0\SDK\v2.0\Lib;C:\Programme\Microsoft SDKs\Windows\v6.0A\Lib;"
|
|
||||||
passl: r"/F8388608" # set the stack size to 8 MB
|
|
||||||
@end
|
|
||||||
@if windows:
|
|
||||||
vcc.path = r"C:\Programme\Microsoft Visual Studio 9.0\VC\bin"
|
|
||||||
@end
|
|
||||||
vcc.options.debug = "/RTC1 /ZI"
|
|
||||||
vcc.options.always = "/nologo"
|
|
||||||
vcc.options.speed = "/Ogityb2 /G7 /arch:SSE2"
|
|
||||||
vcc.options.size = "/O1 /G7"
|
|
||||||
|
|
||||||
# Configuration for the Watcom C/C++ compiler:
|
|
||||||
@if windows:
|
|
||||||
wcc.path = r"C:\eigenes\compiler\watcom\binnt"
|
|
||||||
@end
|
|
||||||
wcc.options.debug = "-d2"
|
|
||||||
wcc.options.always = "-6 -zw -w-"
|
|
||||||
wcc.options.speed = "-ox -on -6 -d0 -fp6 -zW"
|
|
||||||
wcc.options.size = "-ox -on -6 -d0 -fp6 -zW"
|
|
||||||
|
|
||||||
# Configuration for the GNU C/C++ compiler:
|
|
||||||
@if windows:
|
|
||||||
gcc.path = r"C:\eigenes\compiler\mingw\bin"
|
|
||||||
@end
|
|
||||||
gcc.options.debug = "-g"
|
|
||||||
@if macosx:
|
|
||||||
gcc.options.always = "-w -fasm-blocks"
|
|
||||||
@else:
|
|
||||||
gcc.options.always = "-w"
|
|
||||||
@end
|
|
||||||
gcc.options.speed = "-O3 -ffast-math"
|
|
||||||
gcc.options.size = "-Os -ffast-math"
|
|
||||||
|
|
||||||
# Configuration for the Digital Mars C/C++ compiler:
|
|
||||||
@if windows:
|
|
||||||
dmc.path = r"C:\eigenes\compiler\d\dm\bin"
|
|
||||||
@end
|
|
||||||
dmc.options.debug = "-g"
|
|
||||||
dmc.options.always = "-Jm"
|
|
||||||
dmc.options.speed = "-ff -o -6"
|
|
||||||
dmc.options.size = "-ff -o -6"
|
|
||||||
|
|
||||||
# Configuration for the LCC compiler:
|
|
||||||
@if windows:
|
|
||||||
lcc.path = r"C:\eigenes\compiler\lcc\bin"
|
|
||||||
@end
|
|
||||||
lcc.options.debug = "-g5"
|
|
||||||
lcc.options.always = "-e1"
|
|
||||||
lcc.options.speed = "-O -p6"
|
|
||||||
lcc.options.size = "-O -p6"
|
|
||||||
|
|
||||||
# Configuration for the Tiny C Compiler:
|
|
||||||
@if windows:
|
|
||||||
tcc.path = r"C:\Eigenes\compiler\tcc-0.9.23\tcc"
|
|
||||||
tcc.options.always = r"-IC:\Eigenes\compiler\tcc-0.9.23\include " &
|
|
||||||
r"-IC:\Eigenes\compiler\tcc-0.9.23\include\winapi"
|
|
||||||
@end
|
|
||||||
tcc.options.debug = ""
|
|
||||||
tcc.options.speed = ""
|
|
||||||
tcc.options.size = ""
|
|
||||||
|
|
||||||
# Configuration for the Pelles C compiler:
|
|
||||||
@if windows:
|
|
||||||
pcc.path = r"C:\eigenes\compiler\pellesc\bin"
|
|
||||||
@end
|
|
||||||
pcc.options.debug = "-Zi"
|
|
||||||
pcc.options.always = "-Ze"
|
|
||||||
pcc.options.speed = "-Ox"
|
|
||||||
pcc.options.size = "-Os"
|
|
||||||
|
|
||||||
@if windows:
|
|
||||||
icc.path = r"c:\eignes\compiler\icc\bin"
|
|
||||||
@end
|
|
||||||
icc.options.debug = "-g"
|
|
||||||
icc.options.always = "-w"
|
|
||||||
icc.options.speed = "-O3 -ffast-math"
|
|
||||||
icc.options.size = "-Os -ffast-math"
|
|
||||||
|
|
||||||
@write "used special config file"
|
|
||||||
|
|
||||||
@if ecmascript:
|
|
||||||
@write "Target is ECMAScript! No unsafe features are allowed!"
|
|
||||||
@end
|
|
||||||
|
|
||||||
2
configure
vendored
2
configure
vendored
|
|
@ -1,5 +1,5 @@
|
||||||
#! /usr/bin/env sh
|
#! /usr/bin/env sh
|
||||||
|
|
||||||
python koch.py $@ configure
|
echo "there is nothing to configure"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,21 +4,17 @@ Advanced commands::
|
||||||
gen_depend generate a DOT file containing the
|
gen_depend generate a DOT file containing the
|
||||||
module dependency graph
|
module dependency graph
|
||||||
list_def list all defined conditionals and exit
|
list_def list all defined conditionals and exit
|
||||||
rst2html converts a reStructuredText file to HTML
|
|
||||||
check checks the project for syntax and semantic
|
check checks the project for syntax and semantic
|
||||||
parse parses a single file (for debugging Nimrod)
|
parse parses a single file (for debugging Nimrod)
|
||||||
scan tokenizes a single file (for debugging Nimrod)
|
|
||||||
debugtrans for debugging the transformation pass
|
|
||||||
Advanced options:
|
Advanced options:
|
||||||
-w, --warnings:on|off warnings ON|OFF
|
-w, --warnings:on|off warnings ON|OFF
|
||||||
--warning[X]:on|off specific warning X ON|OFF
|
--warning[X]:on|off specific warning X ON|OFF
|
||||||
--hints:on|off hints ON|OFF
|
--hints:on|off hints ON|OFF
|
||||||
--hint[X]:on|off specific hint X ON|OFF
|
--hint[X]:on|off specific hint X ON|OFF
|
||||||
--cc:C_COMPILER set the C/C++ compiler to use
|
|
||||||
--lib:PATH set the system library path
|
--lib:PATH set the system library path
|
||||||
-c, --compile_only compile only; do not assemble or link
|
-c, --compile_only compile only; do not assemble or link
|
||||||
--no_linking compile but do not link
|
--no_linking compile but do not link
|
||||||
--gen_script generate a compile script (in the 'rod_gen'
|
--gen_script generate a compile script (in the 'nimcache'
|
||||||
subdirectory named 'compile_$project$scriptext')
|
subdirectory named 'compile_$project$scriptext')
|
||||||
--os:SYMBOL set the target operating system (cross-compilation)
|
--os:SYMBOL set the target operating system (cross-compilation)
|
||||||
--cpu:SYMBOL set the target processor (cross-compilation)
|
--cpu:SYMBOL set the target processor (cross-compilation)
|
||||||
|
|
@ -27,17 +23,13 @@ Advanced options:
|
||||||
-l, --passl:OPTION pass an option to the linker
|
-l, --passl:OPTION pass an option to the linker
|
||||||
--gen_mapping generate a mapping file containing
|
--gen_mapping generate a mapping file containing
|
||||||
(Nimrod, mangled) identifier pairs
|
(Nimrod, mangled) identifier pairs
|
||||||
--merge_output generate only one C output file
|
|
||||||
--line_dir:on|off generation of #line directive ON|OFF
|
--line_dir:on|off generation of #line directive ON|OFF
|
||||||
--checkpoints:on|off turn on|off checkpoints; for debugging Nimrod
|
--checkpoints:on|off turn on|off checkpoints; for debugging Nimrod
|
||||||
--skip_cfg do not read the general configuration file
|
--skip_cfg do not read the general configuration file
|
||||||
--skip_proj_cfg do not read the project's configuration file
|
--skip_proj_cfg do not read the project's configuration file
|
||||||
--import:MODULE_FILE import the given module implicitly for each module
|
--import:MODULE_FILE import the given module implicitly for each module
|
||||||
--maxerr:NUMBER stop compilation after NUMBER errors; broken!
|
|
||||||
--ast_cache:on|off caching of ASTs ON|OFF (default: OFF)
|
|
||||||
--c_file_cache:on|off caching of generated C files ON|OFF (default: OFF)
|
|
||||||
--index:FILE use FILE to generate a documenation index file
|
--index:FILE use FILE to generate a documenation index file
|
||||||
--putenv:key=value set an environment variable
|
--putenv:key=value set an environment variable
|
||||||
--list_cmd list the commands used to execute external programs
|
--list_cmd list the commands used to execute external programs
|
||||||
-v, --verbose show what Nimrod is doing
|
--verbosity:0|1|2|3 set Nimrod's verbosity level (0 is default)
|
||||||
--version show detailed version information
|
-v, --version show detailed version information
|
||||||
|
|
|
||||||
59
data/ast.yml
59
data/ast.yml
|
|
@ -8,61 +8,52 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
{
|
{
|
||||||
'SymFlag': [ # already 32 flags!
|
'SymFlag': [ # already 26 flags!
|
||||||
'sfTypeCheck', # wether macro parameters should be type checked
|
'sfUsed', # read access of sym (for warnings) or simply used
|
||||||
|
'sfStar', # symbol has * visibility
|
||||||
|
'sfMinus', # symbol has - visibility
|
||||||
|
'sfInInterface', # symbol is in interface section declared
|
||||||
|
'sfFromGeneric', # symbol is instantiation of a generic; this is needed
|
||||||
|
# for symbol file generation; such symbols should always
|
||||||
|
# be written into the ROD file
|
||||||
|
'sfGlobal', # symbol is at global scope
|
||||||
|
|
||||||
'sfForward', # symbol is forward directed
|
'sfForward', # symbol is forward directed
|
||||||
'sfImportc', # symbol is external; imported
|
'sfImportc', # symbol is external; imported
|
||||||
'sfExportc', # symbol is exported (under a specified name)
|
'sfExportc', # symbol is exported (under a specified name)
|
||||||
'sfVolatile', # variable is volatile
|
'sfVolatile', # variable is volatile
|
||||||
'sfUsed', # read access of sym (for warnings) or simply used
|
|
||||||
'sfWrite', # write access of variable (for hints)
|
|
||||||
'sfRegister', # variable should be placed in a register
|
'sfRegister', # variable should be placed in a register
|
||||||
'sfPure', # object is "pure" that means it has no type-information
|
'sfPure', # object is "pure" that means it has no type-information
|
||||||
'sfCodeGenerated', # wether we have already code generated for the proc
|
|
||||||
'sfPrivate', # symbol should be made private after module compilation
|
|
||||||
'sfGlobal', # symbol is at global scope
|
|
||||||
'sfResult', # variable is 'result' in proc
|
'sfResult', # variable is 'result' in proc
|
||||||
'sfNoSideEffect', # proc has no side effects
|
'sfNoSideEffect', # proc has no side effects
|
||||||
'sfMainModule', # module is the main module
|
'sfMainModule', # module is the main module
|
||||||
'sfSystemModule', # module is the system module
|
'sfSystemModule', # module is the system module
|
||||||
'sfNoReturn', # proc never returns (an exit proc)
|
'sfNoReturn', # proc never returns (an exit proc)
|
||||||
'sfAddrTaken', # the variable's address is taken (ex- or implicitely)
|
'sfAddrTaken', # the variable's address is taken (ex- or implicitely)
|
||||||
'sfInInterface', # symbol is in interface section declared
|
|
||||||
'sfNoStatic', # symbol is used within an iterator (needed for codegen)
|
|
||||||
# so it cannot be 'static' in the C code
|
|
||||||
# this is called 'nostatic' in the pragma section
|
|
||||||
'sfCompilerProc', # proc is a compiler proc, that is a C proc that is
|
'sfCompilerProc', # proc is a compiler proc, that is a C proc that is
|
||||||
# needed for the code generator
|
# needed for the code generator
|
||||||
'sfCppMethod', # proc is a C++ method
|
'sfCppMethod', # proc is a C++ method (not implemented yet)
|
||||||
'sfDiscriminant', # field is a discriminant in a record/object
|
'sfDiscriminant', # field is a discriminant in a record/object
|
||||||
'sfDeprecated', # symbol is deprecated
|
'sfDeprecated', # symbol is deprecated
|
||||||
'sfInClosure', # variable is accessed by a closure
|
'sfInClosure', # variable is accessed by a closure
|
||||||
'sfIsCopy', # symbol is a copy; needed for proper name mangling
|
'sfTypeCheck', # wether macro parameters should be type checked
|
||||||
'sfStar', # symbol has * visibility
|
'sfCompileTime', # proc can be evaluated at compile time
|
||||||
'sfMinus' # symbol has - visibility
|
'sfThreadVar', # variable is a thread variable
|
||||||
|
'sfMerge', # proc can be merged with itself
|
||||||
],
|
],
|
||||||
|
|
||||||
'TypeFlag': [
|
'TypeFlag': [
|
||||||
'tfIsDistinct', # better use this flag to make it easier for accessing
|
|
||||||
# typeKind in the code generators
|
|
||||||
'tfGeneric', # type is a generic one
|
|
||||||
'tfExternal', # type is external
|
|
||||||
'tfImported', # type is imported from C
|
|
||||||
'tfInfoGenerated', # whether we have generated type information for this type
|
|
||||||
'tfSemChecked', # used to mark types that's semantic has been checked;
|
|
||||||
# used to prevend endless loops during semantic checking
|
|
||||||
'tfHasOutParams', # for a proc or iterator p:
|
|
||||||
# it indicates that p has out or in out parameters: this
|
|
||||||
# is used to speed up semantic checking a bit
|
|
||||||
'tfEnumHasWholes', # enum cannot be mapped into a range
|
|
||||||
'tfVarargs', # procedure has C styled varargs
|
'tfVarargs', # procedure has C styled varargs
|
||||||
'tfFinal' # is the object final?
|
'tfFinal', # is the object final?
|
||||||
|
'tfAcyclic', # type is acyclic (for GC optimization)
|
||||||
|
'tfEnumHasWholes' # enum cannot be mapped into a range
|
||||||
],
|
],
|
||||||
|
|
||||||
'TypeKind': [ # order is important!
|
'TypeKind': [ # order is important!
|
||||||
# Don't forget to change hti.nim if you make a change here
|
# Don't forget to change hti.nim if you make a change here
|
||||||
'tyNone', 'tyBool', 'tyChar',
|
'tyNone', 'tyBool', 'tyChar',
|
||||||
'tyEmptySet', 'tyArrayConstr', 'tyNil',
|
'tyEmpty', 'tyArrayConstr', 'tyNil',
|
||||||
'tyGeneric',
|
'tyGeneric',
|
||||||
'tyGenericInst', # instantiated generic type
|
'tyGenericInst', # instantiated generic type
|
||||||
'tyGenericParam',
|
'tyGenericParam',
|
||||||
|
|
@ -89,7 +80,9 @@
|
||||||
'nfBase2', # nfBase10 is default, so not needed
|
'nfBase2', # nfBase10 is default, so not needed
|
||||||
'nfBase8',
|
'nfBase8',
|
||||||
'nfBase16',
|
'nfBase16',
|
||||||
'nfAllConst' # used to mark complex expressions constant
|
'nfAllConst', # used to mark complex expressions constant
|
||||||
|
'nfTransf', # node has been transformed
|
||||||
|
'nfSem', # node has been checked for semantics
|
||||||
],
|
],
|
||||||
|
|
||||||
'NodeKind': [ # these are pure nodes
|
'NodeKind': [ # these are pure nodes
|
||||||
|
|
@ -223,6 +216,8 @@
|
||||||
'nkBlockExpr', # a statement block ending in an expr; this is used
|
'nkBlockExpr', # a statement block ending in an expr; this is used
|
||||||
# to allowe powerful multi-line templates that open a
|
# to allowe powerful multi-line templates that open a
|
||||||
# temporary scope
|
# temporary scope
|
||||||
|
'nkStmtListType', # a statement list ending in a type; for macros
|
||||||
|
'nkBlockType', # a statement block ending in a type; for macros
|
||||||
'nkVm', # indicates a virtual instruction; integer field is
|
'nkVm', # indicates a virtual instruction; integer field is
|
||||||
# used for the concrete opcode
|
# used for the concrete opcode
|
||||||
|
|
||||||
|
|
@ -264,6 +259,8 @@
|
||||||
'skEnumField', # an identifier in an enum
|
'skEnumField', # an identifier in an enum
|
||||||
'skForVar', # a for loop variable
|
'skForVar', # a for loop variable
|
||||||
'skModule', # module identifier
|
'skModule', # module identifier
|
||||||
'skLabel' # a label (for block statement)
|
'skLabel', # a label (for block statement)
|
||||||
|
'skStub' # symbol is a stub and not yet loaded from the ROD
|
||||||
|
# file (it is loaded on demand, which may mean: never)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,10 @@
|
||||||
Usage::
|
Usage::
|
||||||
nimrod command [options] inputfile [arguments]
|
nimrod command [options] inputfile [arguments]
|
||||||
Command::
|
Command::
|
||||||
compile compile project with default code generator (C)
|
compile, c compile project with default code generator (C)
|
||||||
compile_to_c compile project with C code generator
|
compile_to_c, cc compile project with C code generator
|
||||||
compile_to_cpp compile project with C++ code generator
|
doc generate the documentation for inputfile
|
||||||
compile_to_ecmascript compile project to ECMAScript code (experimental)
|
rst2html converts a reStructuredText file to HTML
|
||||||
doc generate the documentation for inputfile;
|
|
||||||
with --run switch opens it with $BROWSER
|
|
||||||
Arguments:
|
Arguments:
|
||||||
arguments are passed to the program being run (if --run option is selected)
|
arguments are passed to the program being run (if --run option is selected)
|
||||||
Options:
|
Options:
|
||||||
|
|
@ -14,7 +12,8 @@ Options:
|
||||||
-o, --out:FILE set the output filename
|
-o, --out:FILE set the output filename
|
||||||
-d, --define:SYMBOL define a conditional symbol
|
-d, --define:SYMBOL define a conditional symbol
|
||||||
-u, --undef:SYMBOL undefine a conditional symbol
|
-u, --undef:SYMBOL undefine a conditional symbol
|
||||||
-b, --force_build force rebuilding of all modules
|
-f, --force_build force rebuilding of all modules
|
||||||
|
--symbol_files:on|off use symbol files to speed up compilation (buggy!)
|
||||||
--stack_trace:on|off code generation for stack trace ON|OFF
|
--stack_trace:on|off code generation for stack trace ON|OFF
|
||||||
--line_trace:on|off code generation for line trace ON|OFF
|
--line_trace:on|off code generation for line trace ON|OFF
|
||||||
--debugger:on|off turn Embedded Nimrod Debugger ON|OFF
|
--debugger:on|off turn Embedded Nimrod Debugger ON|OFF
|
||||||
|
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
0.1.0
|
|
||||||
* new config system
|
|
||||||
* new build system
|
|
||||||
* source renderer
|
|
||||||
* pas2nim integrated
|
|
||||||
* support for C++
|
|
||||||
* local variables are always initialized
|
|
||||||
* Rod file reader and writer
|
|
||||||
* new --out, -o command line options
|
|
||||||
* fixed bug in nimconf.pas: we now have several
|
|
||||||
string token types
|
|
||||||
* changed nkIdentDef to nkIdentDefs
|
|
||||||
* added type(expr) in the parser and the grammer
|
|
||||||
* added template
|
|
||||||
* added command calls
|
|
||||||
* added case in records/objects
|
|
||||||
* added --skip_proj_cfg switch for nim.dpr
|
|
||||||
* added missing features to pasparse
|
|
||||||
* rewrote the source generator
|
|
||||||
* ``addr`` and ``cast`` are now keywords; grammar updated
|
|
||||||
* implemented ` notation; grammar updated
|
|
||||||
* specification replaced by a manual
|
|
||||||
|
|
@ -3,16 +3,20 @@
|
||||||
[
|
[
|
||||||
'None',
|
'None',
|
||||||
'Defined',
|
'Defined',
|
||||||
'New',
|
|
||||||
'NewFinalize',
|
|
||||||
'Low',
|
'Low',
|
||||||
'High',
|
'High',
|
||||||
'SizeOf',
|
'SizeOf',
|
||||||
'RegisterFinalizer',
|
'Is',
|
||||||
'Succ',
|
'Succ',
|
||||||
'Pred',
|
'Pred',
|
||||||
'Inc',
|
'Inc',
|
||||||
'Dec',
|
'Dec',
|
||||||
|
'Ord',
|
||||||
|
|
||||||
|
'New',
|
||||||
|
'NewFinalize',
|
||||||
|
'NewSeq',
|
||||||
|
'RegisterFinalizer',
|
||||||
'LengthOpenArray',
|
'LengthOpenArray',
|
||||||
'LengthStr',
|
'LengthStr',
|
||||||
'LengthArray',
|
'LengthArray',
|
||||||
|
|
@ -20,8 +24,9 @@
|
||||||
'Incl',
|
'Incl',
|
||||||
'Excl',
|
'Excl',
|
||||||
'Card',
|
'Card',
|
||||||
'Ord',
|
|
||||||
'Chr',
|
'Chr',
|
||||||
|
'GCref',
|
||||||
|
'GCunref',
|
||||||
|
|
||||||
# binary arithmetic with and without overflow checking:
|
# binary arithmetic with and without overflow checking:
|
||||||
'AddI',
|
'AddI',
|
||||||
|
|
@ -161,7 +166,6 @@
|
||||||
'AppendSeqSeq',
|
'AppendSeqSeq',
|
||||||
'InRange',
|
'InRange',
|
||||||
'InSet',
|
'InSet',
|
||||||
'Is',
|
|
||||||
'Asgn',
|
'Asgn',
|
||||||
'Repr',
|
'Repr',
|
||||||
'Exit',
|
'Exit',
|
||||||
|
|
@ -170,15 +174,34 @@
|
||||||
'Assert',
|
'Assert',
|
||||||
'Swap',
|
'Swap',
|
||||||
'IsNil',
|
'IsNil',
|
||||||
|
'ArrToSeq',
|
||||||
|
|
||||||
# magic type constructors:
|
# magic types:
|
||||||
'Array',
|
'Array',
|
||||||
'OpenArray',
|
'OpenArray',
|
||||||
'Range',
|
'Range',
|
||||||
'Set',
|
'Set',
|
||||||
'Seq',
|
'Seq',
|
||||||
|
'Int',
|
||||||
|
'Int8',
|
||||||
|
'Int16',
|
||||||
|
'Int32',
|
||||||
|
'Int64',
|
||||||
|
'Float',
|
||||||
|
'Float32',
|
||||||
|
'Float64',
|
||||||
|
'Bool',
|
||||||
|
'Char',
|
||||||
|
'String',
|
||||||
|
'Cstring',
|
||||||
|
'Pointer',
|
||||||
|
'AnyEnum',
|
||||||
|
'EmptySet',
|
||||||
|
'IntSetBaseType',
|
||||||
|
'Nil',
|
||||||
|
|
||||||
# magic constants:
|
# magic constants:
|
||||||
|
'IsMainModule',
|
||||||
'CompileDate',
|
'CompileDate',
|
||||||
'CompileTime',
|
'CompileTime',
|
||||||
'NimrodVersion',
|
'NimrodVersion',
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,8 @@
|
||||||
{'errSizeTooBig': "computing the type's size produced an overflow"},
|
{'errSizeTooBig': "computing the type's size produced an overflow"},
|
||||||
{'errSetTooBig': 'set is too large'},
|
{'errSetTooBig': 'set is too large'},
|
||||||
{'errBaseTypeMustBeOrdinal': 'base type of a set must be an ordinal'},
|
{'errBaseTypeMustBeOrdinal': 'base type of a set must be an ordinal'},
|
||||||
{'errInheritanceOnlyWithNonFinalObjects': 'inheritance only works non-final objects'},
|
{'errInheritanceOnlyWithNonFinalObjects':
|
||||||
|
'inheritance only works with non-final objects'},
|
||||||
{'errInheritanceOnlyWithEnums': 'inheritance only works with an enum'},
|
{'errInheritanceOnlyWithEnums': 'inheritance only works with an enum'},
|
||||||
{'errIllegalRecursionInTypeX': "illegal recursion in type '$1'"},
|
{'errIllegalRecursionInTypeX': "illegal recursion in type '$1'"},
|
||||||
{'errCannotInstantiateX': "cannot instantiate: '$1'"},
|
{'errCannotInstantiateX': "cannot instantiate: '$1'"},
|
||||||
|
|
@ -278,16 +279,17 @@
|
||||||
|
|
||||||
# hints:
|
# hints:
|
||||||
{'hintSuccess': 'operation successful'},
|
{'hintSuccess': 'operation successful'},
|
||||||
|
{'hintSuccessX': 'operation successful ($1 lines compiled; $2 sec total)'},
|
||||||
{'hintLineTooLong': 'line too long'},
|
{'hintLineTooLong': 'line too long'},
|
||||||
{'hintXDeclaredButNotUsed': "'$1' is declared but not used"},
|
{'hintXDeclaredButNotUsed': "'$1' is declared but not used"},
|
||||||
{'hintConvToBaseNotNeeded': 'conversion to base object is not needed'},
|
{'hintConvToBaseNotNeeded': 'conversion to base object is not needed'},
|
||||||
{'hintConvFromXtoItselfNotNeeded': 'conversion from $1 to itself is pointless'},
|
{'hintConvFromXtoItselfNotNeeded': 'conversion from $1 to itself is pointless'},
|
||||||
{'hintExprAlwaysX': "expression evaluates always to '$1'"},
|
{'hintExprAlwaysX': "expression evaluates always to '$1'"},
|
||||||
{'hintMo2FileInvalid': "mo2 file '$1' is invalid"},
|
|
||||||
{'hintModuleHasChanged': "module '$1' has been changed"},
|
|
||||||
{'hintCannotOpenMo2File': "mo2 file '$1' does not exist"},
|
|
||||||
{'hintQuitCalled': "quit() called"},
|
{'hintQuitCalled': "quit() called"},
|
||||||
{'hintProcessing': "processing"},
|
{'hintProcessing': "processing $1"},
|
||||||
|
{'hintCodeBegin': "generated code listing:"},
|
||||||
|
{'hintCodeEnd': "end of listing"},
|
||||||
|
{'hintConf': "used config file '$1'"},
|
||||||
|
|
||||||
# user hint message:
|
# user hint message:
|
||||||
{'hintUser': '$1'}
|
{'hintUser': '$1'}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,2 @@
|
||||||
This directory contains data files in a format called YAML_. These files
|
This directory contains data files in Python or ordinary text format. These
|
||||||
are required for building Nimrod.
|
files are required for building Nimrod.
|
||||||
|
|
||||||
|
|
||||||
.. _YAML: http://www.yaml.org/
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ ast type definitions of the abstract syntax tree (AST) and
|
||||||
node constructors
|
node constructors
|
||||||
astalgo algorithms for containers of AST nodes; converting the
|
astalgo algorithms for containers of AST nodes; converting the
|
||||||
AST to YAML; the symbol table
|
AST to YAML; the symbol table
|
||||||
|
passes implement the passes managemer for passes over the AST
|
||||||
trees few algorithms for nodes; this module is less important
|
trees few algorithms for nodes; this module is less important
|
||||||
types module for traversing type graphs; also contain several
|
types module for traversing type graphs; also contain several
|
||||||
helpers for dealing with types
|
helpers for dealing with types
|
||||||
|
|
@ -23,19 +24,15 @@ semtypes contains the semantic checking phase for types
|
||||||
|
|
||||||
idents implements a general mapping from identifiers to an internal
|
idents implements a general mapping from identifiers to an internal
|
||||||
representation (``PIdent``) that is used, so that a simple
|
representation (``PIdent``) that is used, so that a simple
|
||||||
pointer comparison suffices to say whether two Nimrod
|
id-comparison suffices to say whether two Nimrod identifiers
|
||||||
identifiers are equivalent
|
are equivalent
|
||||||
|
|
||||||
ropes implements long strings using represented as trees for
|
ropes implements long strings using represented as trees for
|
||||||
lazy evaluation; used mainly by the code generators
|
lazy evaluation; used mainly by the code generators
|
||||||
|
|
||||||
ccgobj contains type definitions neeeded for C code generation
|
ccgobj contains type definitions neeeded for C code generation
|
||||||
and some helpers
|
and some helpers
|
||||||
ccgmangl contains the name mangler for converting Nimrod
|
|
||||||
identifiers to their C counterparts
|
|
||||||
ccgutils contains helpers for the C code generator
|
ccgutils contains helpers for the C code generator
|
||||||
ccgtemps contains the handling of temporary variables for the
|
|
||||||
C code generator
|
|
||||||
ccgtypes the generator for C types
|
ccgtypes the generator for C types
|
||||||
ccgstmts the generator for statements
|
ccgstmts the generator for statements
|
||||||
ccgexprs the generator for expressions
|
ccgexprs the generator for expressions
|
||||||
|
|
|
||||||
|
|
@ -28,10 +28,9 @@ castExpr ::= CAST BRACKET_LE optInd typeDesc BRACKERT_RI
|
||||||
PAR_LE optInd expr PAR_RI
|
PAR_LE optInd expr PAR_RI
|
||||||
addrExpr ::= ADDR PAR_LE optInd expr PAR_RI
|
addrExpr ::= ADDR PAR_LE optInd expr PAR_RI
|
||||||
symbol ::= ACC (KEYWORD | IDENT | operator | PAR_LE PAR_RI
|
symbol ::= ACC (KEYWORD | IDENT | operator | PAR_LE PAR_RI
|
||||||
| BRACKET_LE BRACKET_RI) ACC | IDENT
|
| BRACKET_LE BRACKET_RI | EQUALS | literal )+ ACC
|
||||||
accExpr ::= KEYWORD | IDENT | operator [DOT KEYWORD | IDENT | operator]
|
| IDENT
|
||||||
paramList
|
primary ::= ( prefixOperator optInd )* ( symbol | constructor |
|
||||||
primary ::= ( prefixOperator optInd )* ( IDENT | literal | ACC accExpr ACC
|
|
||||||
| castExpr | addrExpr ) (
|
| castExpr | addrExpr ) (
|
||||||
DOT optInd symbol
|
DOT optInd symbol
|
||||||
#| CURLY_LE namedTypeDescList CURLY_RI
|
#| CURLY_LE namedTypeDescList CURLY_RI
|
||||||
|
|
@ -49,11 +48,12 @@ literal ::= INT_LIT | INT8_LIT | INT16_LIT | INT32_LIT | INT64_LIT
|
||||||
| STR_LIT | RSTR_LIT | TRIPLESTR_LIT
|
| STR_LIT | RSTR_LIT | TRIPLESTR_LIT
|
||||||
| CHAR_LIT | RCHAR_LIT
|
| CHAR_LIT | RCHAR_LIT
|
||||||
| NIL
|
| NIL
|
||||||
|
|
||||||
|
constructor ::= literal
|
||||||
| BRACKET_LE optInd (expr [COLON expr] optComma )* BRACKET_RI # []-Constructor
|
| BRACKET_LE optInd (expr [COLON expr] optComma )* BRACKET_RI # []-Constructor
|
||||||
| CURLY_LE optInd (expr [DOTDOT expr] optComma )* CURLY_RI # {}-Constructor
|
| CURLY_LE optInd (expr [DOTDOT expr] optComma )* CURLY_RI # {}-Constructor
|
||||||
| PAR_LE optInd (expr [COLON expr] optComma )* PAR_RI # ()-Constructor
|
| PAR_LE optInd (expr [COLON expr] optComma )* PAR_RI # ()-Constructor
|
||||||
|
|
||||||
|
|
||||||
exprList ::= ( expr optComma )*
|
exprList ::= ( expr optComma )*
|
||||||
|
|
||||||
namedExpr ::= expr [EQUALS expr] # actually this is symbol EQUALS expr|expr
|
namedExpr ::= expr [EQUALS expr] # actually this is symbol EQUALS expr|expr
|
||||||
|
|
@ -170,7 +170,7 @@ objectCase ::= CASE expr COLON typeDesc [COMMENT]
|
||||||
(OF sliceList COLON [COMMENT] objectPart)*
|
(OF sliceList COLON [COMMENT] objectPart)*
|
||||||
[ELSE COLON [COMMENT] objectPart]
|
[ELSE COLON [COMMENT] objectPart]
|
||||||
|
|
||||||
objectPart ::= objectWhen | objectCase | objectIdentPart
|
objectPart ::= objectWhen | objectCase | objectIdentPart | NIL
|
||||||
| indPush objectPart (SAD objectPart)* DED
|
| indPush objectPart (SAD objectPart)* DED
|
||||||
tupleDesc ::= BRACKET_LE optInd ((symbol optComma)+ COLON typeDesc optComma)* BRACKET_RI
|
tupleDesc ::= BRACKET_LE optInd ((symbol optComma)+ COLON typeDesc optComma)* BRACKET_RI
|
||||||
|
|
||||||
|
|
|
||||||
189
doc/intern.txt
189
doc/intern.txt
|
|
@ -32,7 +32,7 @@ Path Purpose
|
||||||
``config`` configuration files for Nimrod go into here
|
``config`` configuration files for Nimrod go into here
|
||||||
``lib`` the Nimrod library lives here; ``rod`` depends
|
``lib`` the Nimrod library lives here; ``rod`` depends
|
||||||
on it!
|
on it!
|
||||||
``web`` website of Nimrod; generated by ``genweb.py``
|
``web`` website of Nimrod; generated by ``koch.py``
|
||||||
from the ``*.txt`` and ``*.tmpl`` files
|
from the ``*.txt`` and ``*.tmpl`` files
|
||||||
``koch`` the Koch Build System (written for Nimrod)
|
``koch`` the Koch Build System (written for Nimrod)
|
||||||
``obj`` generated ``*.obj`` files go into here
|
``obj`` generated ``*.obj`` files go into here
|
||||||
|
|
@ -49,20 +49,19 @@ and Free Pascal can compile the Nimrod compiler.
|
||||||
|
|
||||||
Requirements for bootstrapping:
|
Requirements for bootstrapping:
|
||||||
|
|
||||||
- Free Pascal (I used version 2.2); it may not be needed
|
- Free Pascal (I used version 2.2) [optional]
|
||||||
- Python (should work with 2.4 or higher) and the code generator *cog*
|
- Python (should work with version 1.5 or higher)
|
||||||
(included in this distribution!)
|
|
||||||
|
|
||||||
- C compiler -- one of:
|
- C compiler -- one of:
|
||||||
|
|
||||||
* win32-lcc
|
* win32-lcc (currently broken)
|
||||||
* Borland C++ (tested with 5.5)
|
* Borland C++ (tested with 5.5; currently broken)
|
||||||
* Microsoft C++
|
* Microsoft C++
|
||||||
* Digital Mars C++
|
* Digital Mars C++
|
||||||
* Watcom C++ (currently broken; a fix is welcome!)
|
* Watcom C++ (currently broken)
|
||||||
* GCC
|
* GCC
|
||||||
* Intel C++
|
* Intel C++
|
||||||
* Pelles C
|
* Pelles C (currently broken)
|
||||||
* llvm-gcc
|
* llvm-gcc
|
||||||
|
|
||||||
| Compiling the compiler is a simple matter of running:
|
| Compiling the compiler is a simple matter of running:
|
||||||
|
|
@ -75,7 +74,7 @@ If you want to debug the compiler, use the command::
|
||||||
|
|
||||||
The ``koch.py`` script is Nimrod's maintainance script: Everything that has
|
The ``koch.py`` script is Nimrod's maintainance script: Everything that has
|
||||||
been automated is accessible with it. It is a replacement for make and shell
|
been automated is accessible with it. It is a replacement for make and shell
|
||||||
scripting with the advantage that it is more portable and is easier to read.
|
scripting with the advantage that it is more portable.
|
||||||
|
|
||||||
|
|
||||||
Coding standards
|
Coding standards
|
||||||
|
|
@ -124,7 +123,7 @@ Complex assignments
|
||||||
|
|
||||||
We already knew the type information as a graph in the compiler.
|
We already knew the type information as a graph in the compiler.
|
||||||
Thus we need to serialize this graph as RTTI for C code generation.
|
Thus we need to serialize this graph as RTTI for C code generation.
|
||||||
Look at the files ``lib/typeinfo.nim``, ``lib/hti.nim`` for more information.
|
Look at the file ``lib/hti.nim`` for more information.
|
||||||
|
|
||||||
|
|
||||||
The Garbage Collector
|
The Garbage Collector
|
||||||
|
|
@ -135,18 +134,11 @@ Introduction
|
||||||
|
|
||||||
We use the term *cell* here to refer to everything that is traced
|
We use the term *cell* here to refer to everything that is traced
|
||||||
(sequences, refs, strings).
|
(sequences, refs, strings).
|
||||||
This section describes how the new GC works. The old algorithms
|
This section describes how the new GC works.
|
||||||
all had the same problem: Too complex to get them right. This one
|
|
||||||
tries to find the right compromise.
|
|
||||||
|
|
||||||
The basic algorithm is *Deferrent reference counting* with cycle detection.
|
The basic algorithm is *Deferrent reference counting* with cycle detection.
|
||||||
References in the stack are not counted for better performance and easier C
|
References in the stack are not counted for better performance and easier C
|
||||||
code generation. The GC starts by traversing the hardware stack and increments
|
code generation.
|
||||||
the reference count (RC) of every cell that it encounters. After the GC has
|
|
||||||
done its work the stack is traversed again and the RC of every cell
|
|
||||||
that it encounters are decremented again. Thus no marking bits in the RC are
|
|
||||||
needed. Between these stack traversals the GC has a complete accurate view over
|
|
||||||
the RCs.
|
|
||||||
|
|
||||||
Each cell has a header consisting of a RC and a pointer to its type
|
Each cell has a header consisting of a RC and a pointer to its type
|
||||||
descriptor. However the program does not know about these, so they are placed at
|
descriptor. However the program does not know about these, so they are placed at
|
||||||
|
|
@ -156,72 +148,44 @@ is extremely important that ``pointer`` is not confused with a ``PCell``
|
||||||
as this would lead to a memory corruption.
|
as this would lead to a memory corruption.
|
||||||
|
|
||||||
|
|
||||||
When to trigger a collection
|
|
||||||
----------------------------
|
|
||||||
|
|
||||||
Since there are really two different garbage collectors (reference counting
|
|
||||||
and mark and sweep) we use two different heuristics when to run the passes.
|
|
||||||
The RC-GC pass is fairly cheap: Thus we use an additive increase (7 pages)
|
|
||||||
for the RC_Threshold and a multiple increase for the CycleThreshold.
|
|
||||||
|
|
||||||
|
|
||||||
The AT and ZCT sets
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
The GC maintains two sets throughout the lifetime of
|
|
||||||
the program (plus two temporary ones). The AT (*any table*) simply contains
|
|
||||||
every cell. The ZCT (*zero count table*) contains every cell whose RC is
|
|
||||||
zero. This is used to reclaim most cells fast.
|
|
||||||
|
|
||||||
The ZCT contains redundant information -- the AT alone would suffice.
|
|
||||||
However, traversing the AT and look if the RC is zero would touch every living
|
|
||||||
cell in the heap! That's why the ZCT is updated whenever a RC drops to zero.
|
|
||||||
The ZCT is not updated when a RC is incremented from zero to one, as
|
|
||||||
this would be too costly.
|
|
||||||
|
|
||||||
|
|
||||||
The CellSet data structure
|
The CellSet data structure
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
The AT and ZCT depend on an extremely efficient datastructure for storing a
|
The GC depends on an extremely efficient datastructure for storing a
|
||||||
set of pointers - this is called a ``PCellSet`` in the source code.
|
set of pointers - this is called a ``TCellSet`` in the source code.
|
||||||
Inserting, deleting and searching are done in constant time. However,
|
Inserting, deleting and searching are done in constant time. However,
|
||||||
modifying a ``PCellSet`` during traversation leads to undefined behaviour.
|
modifying a ``TCellSet`` during traversation leads to undefined behaviour.
|
||||||
|
|
||||||
.. code-block:: Nimrod
|
.. code-block:: Nimrod
|
||||||
type
|
type
|
||||||
PCellSet # hidden
|
TCellSet # hidden
|
||||||
|
|
||||||
proc allocCellSet: PCellSet # make a new set
|
proc CellSetInit(s: var TCellSet) # initialize a new set
|
||||||
proc deallocCellSet(s: PCellSet) # empty the set and free its memory
|
proc CellSetDeinit(s: var TCellSet) # empty the set and free its memory
|
||||||
proc incl(s: PCellSet, elem: PCell) # include an element
|
proc incl(s: var TCellSet, elem: PCell) # include an element
|
||||||
proc excl(s: PCellSet, elem: PCell) # exclude an element
|
proc excl(s: var TCellSet, elem: PCell) # exclude an element
|
||||||
|
|
||||||
proc `in`(elem: PCell, s: PCellSet): bool
|
proc `in`(elem: PCell, s: TCellSet): bool # tests membership
|
||||||
|
|
||||||
iterator elements(s: PCellSet): (elem: PCell)
|
iterator elements(s: TCellSet): (elem: PCell)
|
||||||
|
|
||||||
|
|
||||||
All the operations have to be performed efficiently. Because a Cellset can
|
All the operations have to be perform efficiently. Because a Cellset can
|
||||||
become huge (the AT contains every allocated cell!) a hash table is not
|
become huge a hash table alone is not suitable for this.
|
||||||
suitable for this.
|
|
||||||
|
|
||||||
We use a mixture of bitset and patricia tree for this. One node in the
|
We use a mixture of bitset and hash table for this. The hash table maps *pages*
|
||||||
patricia tree contains a bitset that decribes a page of the operating system
|
to a page descriptor. The page descriptor contains a bit for any possible cell
|
||||||
(not always, but that doesn't matter).
|
address within this page. So including a cell is done as follows:
|
||||||
So including a cell is done as follows:
|
|
||||||
|
|
||||||
- Find the page descriptor for the page the cell belongs to.
|
- Find the page descriptor for the page the cell belongs to.
|
||||||
- Set the appropriate bit in the page descriptor indicating that the
|
- Set the appropriate bit in the page descriptor indicating that the
|
||||||
cell points to the start of a memory block.
|
cell points to the start of a memory block.
|
||||||
|
|
||||||
Removing a cell is analogous - the bit has to be set to zero.
|
Removing a cell is analogous - the bit has to be set to zero.
|
||||||
Single page descriptors are never deleted from the tree. Typically a page
|
Single page descriptors are never deleted from the hash table. This is not
|
||||||
descriptor is only 19 words big, so it does not waste much by not deleting
|
needed as the data structures need to be periodically rebuilt anyway.
|
||||||
it. Apart from that the AT and ZCT are rebuilt frequently, so removing a
|
|
||||||
single page descriptor from the tree is never necessary.
|
|
||||||
|
|
||||||
Complete traversal is done like so::
|
Complete traversal is done in this way::
|
||||||
|
|
||||||
for each page decriptor d:
|
for each page decriptor d:
|
||||||
for each bit in d:
|
for each bit in d:
|
||||||
|
|
@ -265,103 +229,12 @@ roughly like this:
|
||||||
Note that for systems with a continous stack (which most systems have)
|
Note that for systems with a continous stack (which most systems have)
|
||||||
the check whether the ref is on the stack is very cheap (only two
|
the check whether the ref is on the stack is very cheap (only two
|
||||||
comparisons). Another advantage of this scheme is that the code produced is
|
comparisons). Another advantage of this scheme is that the code produced is
|
||||||
a tiny bit smaller.
|
smaller.
|
||||||
|
|
||||||
|
|
||||||
The algorithm in pseudo-code
|
The algorithm in pseudo-code
|
||||||
----------------------------
|
----------------------------
|
||||||
Now we come to the nitty-gritty. The algorithm works in several phases.
|
To be written.
|
||||||
|
|
||||||
Phase 1 - Consider references from stack
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
::
|
|
||||||
|
|
||||||
for each pointer p in the stack: incRef(p)
|
|
||||||
|
|
||||||
This is necessary because references in the hardware stack are not traced for
|
|
||||||
better performance. After Phase 1 the RCs are accurate.
|
|
||||||
|
|
||||||
|
|
||||||
Phase 2 - Free the ZCT
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
This is how things used to (not) work::
|
|
||||||
|
|
||||||
for p in elements(ZCT):
|
|
||||||
if RC(p) == 0:
|
|
||||||
call finalizer of p
|
|
||||||
for c in children(p): decRef(c) # free its children recursively
|
|
||||||
# if necessary; the childrens RC >= 1, BUT they may still be in the ZCT!
|
|
||||||
free(p)
|
|
||||||
else:
|
|
||||||
remove p from the ZCT
|
|
||||||
|
|
||||||
Instead we do it this way. Note that the recursion is gone too!
|
|
||||||
::
|
|
||||||
|
|
||||||
newZCT = nil
|
|
||||||
for p in elements(ZCT):
|
|
||||||
if RC(p) == 0:
|
|
||||||
call finalizer of p
|
|
||||||
for c in children(p):
|
|
||||||
assert(RC(c) > 0)
|
|
||||||
dec(RC(c))
|
|
||||||
if RC(c) == 0:
|
|
||||||
if newZCT == nil: newZCT = allocCellSet()
|
|
||||||
incl(newZCT, c)
|
|
||||||
free(p)
|
|
||||||
else:
|
|
||||||
# nothing to do! We will use the newZCS
|
|
||||||
|
|
||||||
deallocCellSet(ZCT)
|
|
||||||
ZCT = newZCT
|
|
||||||
|
|
||||||
This phase is repeated until enough memory is available or the ZCT is nil.
|
|
||||||
If still not enough memory is available the cyclic detector gets its chance
|
|
||||||
to do something.
|
|
||||||
|
|
||||||
|
|
||||||
Phase 3 - Cycle detection
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
Cycle detection works by subtracting internal reference counts::
|
|
||||||
|
|
||||||
newAT = allocCellSet()
|
|
||||||
|
|
||||||
for y in elements(AT):
|
|
||||||
# pretend that y is dead:
|
|
||||||
for c in children(y):
|
|
||||||
dec(RC(c))
|
|
||||||
# note that this should not be done recursively as we have all needed
|
|
||||||
# pointers in the AT! This makes it more efficient too!
|
|
||||||
|
|
||||||
proc restore(y: PCell) =
|
|
||||||
# unfortunately, the recursion here cannot be eliminated easily
|
|
||||||
if y not_in newAT:
|
|
||||||
incl(newAT, y)
|
|
||||||
for c in children(y):
|
|
||||||
inc(RC(c)) # restore proper reference counts!
|
|
||||||
restore(c)
|
|
||||||
|
|
||||||
for y in elements(AT) with rc > 0:
|
|
||||||
restore(y)
|
|
||||||
|
|
||||||
for y in elements(AT) with rc == 0:
|
|
||||||
free(y) # if pretending worked, it was part of a cycle
|
|
||||||
|
|
||||||
AT = newAT
|
|
||||||
|
|
||||||
|
|
||||||
Phase 4 - Ignore references from stack again
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
::
|
|
||||||
|
|
||||||
for each pointer p in the stack:
|
|
||||||
dec(RC(p))
|
|
||||||
if RC(p) == 0: incl(ZCT, p)
|
|
||||||
|
|
||||||
Now the RCs correctly discard any references from the stack. One can also see
|
|
||||||
this as a temporary marking operation. Things that are referenced from stack
|
|
||||||
are marked during the GC's operarion and now have to be unmarked.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The compiler's architecture
|
The compiler's architecture
|
||||||
|
|
|
||||||
87
doc/lib.txt
87
doc/lib.txt
|
|
@ -57,12 +57,18 @@ Basic libraries
|
||||||
style-insensitive mode. An efficient string substitution operator ``%``
|
style-insensitive mode. An efficient string substitution operator ``%``
|
||||||
for the string table is also provided.
|
for the string table is also provided.
|
||||||
|
|
||||||
|
* `streams <streams.html>`_
|
||||||
|
This module provides a stream interface and two implementations thereof:
|
||||||
|
the `PFileStream` and the `PStringStream` which implement the stream
|
||||||
|
interface for Nimrod file objects (`TFile`) and strings. Other modules
|
||||||
|
may provide other implementations for this standard stream interface.
|
||||||
|
|
||||||
* `hashes <hashes.html>`_
|
* `hashes <hashes.html>`_
|
||||||
This module implements efficient computations of hash values for diverse
|
This module implements efficient computations of hash values for diverse
|
||||||
Nimrod types.
|
Nimrod types.
|
||||||
|
|
||||||
* `lexbase <lexbase.html>`_
|
* `lexbase <lexbase.html>`_
|
||||||
This is a low leve module that implements an extremely efficent buffering
|
This is a low level module that implements an extremely efficent buffering
|
||||||
scheme for lexers and parsers. This is used by the ``parsecfg`` module.
|
scheme for lexers and parsers. This is used by the ``parsecfg`` module.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -78,6 +84,8 @@ Advanced libaries
|
||||||
builds on the GTK interface. On Windows, native dialogs are shown if
|
builds on the GTK interface. On Windows, native dialogs are shown if
|
||||||
appropriate.
|
appropriate.
|
||||||
|
|
||||||
|
* `zipfiles <zipfiles.html>`_
|
||||||
|
This module implements a zip archive creator/reader/modifier.
|
||||||
|
|
||||||
Wrappers
|
Wrappers
|
||||||
========
|
========
|
||||||
|
|
@ -129,3 +137,80 @@ not contained in the distribution. You can then find them on the website.
|
||||||
Wrapper for the pango library.
|
Wrapper for the pango library.
|
||||||
* `pangoutils <pangoutils.html>`_
|
* `pangoutils <pangoutils.html>`_
|
||||||
Wrapper for the pangoutils library.
|
Wrapper for the pangoutils library.
|
||||||
|
* `gl <gl.html>`_
|
||||||
|
Part of the wrapper for OpenGL.
|
||||||
|
* `glext <glext.html>`_
|
||||||
|
Part of the wrapper for OpenGL.
|
||||||
|
* `glu <glu.html>`_
|
||||||
|
Part of the wrapper for OpenGL.
|
||||||
|
* `glut <glut.html>`_
|
||||||
|
Part of the wrapper for OpenGL.
|
||||||
|
* `glx <glx.html>`_
|
||||||
|
Part of the wrapper for OpenGL.
|
||||||
|
* `wingl <wingl.html>`_
|
||||||
|
Part of the wrapper for OpenGL.
|
||||||
|
* `lua <lua.html>`_
|
||||||
|
Part of the wrapper for Lua.
|
||||||
|
* `lualib <lualib.html>`_
|
||||||
|
Part of the wrapper for Lua.
|
||||||
|
* `lauxlib <lauxlib.html>`_
|
||||||
|
Part of the wrapper for Lua.
|
||||||
|
* `odbcsql <odbcsql.nim>`_
|
||||||
|
interface to the ODBC driver.
|
||||||
|
* `zlib <zlib.nim>`_
|
||||||
|
Wrapper for the zlib library.
|
||||||
|
* `sdl <sdl.html>`_
|
||||||
|
Part of the wrapper for SDL.
|
||||||
|
* `sdl_gfx <sdl_gfx.html>`_
|
||||||
|
Part of the wrapper for SDL.
|
||||||
|
* `sdl_image <sdl_image.html>`_
|
||||||
|
Part of the wrapper for SDL.
|
||||||
|
* `sdl_mixer <sdl_mixer.html>`_
|
||||||
|
Part of the wrapper for SDL.
|
||||||
|
* `sdl_net <sdl_net.html>`_
|
||||||
|
Part of the wrapper for SDL.
|
||||||
|
* `sdl_ttf <sdl_ttf.html>`_
|
||||||
|
Part of the wrapper for SDL.
|
||||||
|
* `smpeg <smpeg.html>`_
|
||||||
|
Part of the wrapper for SDL.
|
||||||
|
* `cursorfont <cursorfont.html>`_
|
||||||
|
Part of the wrapper for X11.
|
||||||
|
* `keysym <keysym.html>`_
|
||||||
|
Part of the wrapper for X11.
|
||||||
|
* `x <x.html>`_
|
||||||
|
Part of the wrapper for X11.
|
||||||
|
* `xatom <xatom.html>`_
|
||||||
|
Part of the wrapper for X11.
|
||||||
|
* `xcms <xcms.html>`_
|
||||||
|
Part of the wrapper for X11.
|
||||||
|
* `xf86dga <xf86dga.html>`_
|
||||||
|
Part of the wrapper for X11.
|
||||||
|
* `xf86vmode <xf86vmode.html>`_
|
||||||
|
Part of the wrapper for X11.
|
||||||
|
* `xi <xi.html>`_
|
||||||
|
Part of the wrapper for X11.
|
||||||
|
* `xinerama <xinerama.html>`_
|
||||||
|
Part of the wrapper for X11.
|
||||||
|
* `xkb <xkb.html>`_
|
||||||
|
Part of the wrapper for X11.
|
||||||
|
* `xkblib <xkblib.html>`_
|
||||||
|
Part of the wrapper for X11.
|
||||||
|
* `xlib <xlib.html>`_
|
||||||
|
Part of the wrapper for X11.
|
||||||
|
* `xrandr <xrandr.html>`_
|
||||||
|
Part of the wrapper for X11.
|
||||||
|
* `xrender <xrender.html>`_
|
||||||
|
Part of the wrapper for X11.
|
||||||
|
* `xresource <xresource.html>`_
|
||||||
|
Part of the wrapper for X11.
|
||||||
|
* `xshm <xshm.html>`_
|
||||||
|
Part of the wrapper for X11.
|
||||||
|
* `xutil <xutil.html>`_
|
||||||
|
Part of the wrapper for X11.
|
||||||
|
* `xv <xv.html>`_
|
||||||
|
Part of the wrapper for X11.
|
||||||
|
* `xvlib <xvlib.html>`_
|
||||||
|
Part of the wrapper for X11.
|
||||||
|
* `libzip <libzip.html>`_
|
||||||
|
Interface to the `lib zip <http://www.nih.at/libzip/index.html>`_ library by
|
||||||
|
Dieter Baron and Thomas Klausner.
|
||||||
|
|
|
||||||
|
|
@ -160,8 +160,8 @@ case-sensitive and even underscores are ignored:
|
||||||
this is that this allows programmers to use their own prefered spelling style
|
this is that this allows programmers to use their own prefered spelling style
|
||||||
and libraries written by different programmers cannot use incompatible
|
and libraries written by different programmers cannot use incompatible
|
||||||
conventions. The editors or IDE can show the identifiers as preferred. Another
|
conventions. The editors or IDE can show the identifiers as preferred. Another
|
||||||
advantage is that it frees the programmer from remembering the spelling of an
|
advantage is that it frees the programmer from remembering the exact spelling
|
||||||
identifier.
|
of an identifier.
|
||||||
|
|
||||||
|
|
||||||
Literal strings
|
Literal strings
|
||||||
|
|
@ -601,20 +601,20 @@ Array and sequence types
|
||||||
has the same type. Arrays always have a fixed length which is specified at
|
has the same type. Arrays always have a fixed length which is specified at
|
||||||
compile time (except for open arrays). They can be indexed by any ordinal type.
|
compile time (except for open arrays). They can be indexed by any ordinal type.
|
||||||
A parameter ``A`` may be an *open array*, in which case it is indexed by
|
A parameter ``A`` may be an *open array*, in which case it is indexed by
|
||||||
integers from 0 to ``len(A)-1``.
|
integers from 0 to ``len(A)-1``. An array expression may be constructed by the
|
||||||
|
array constructor ``[]``.
|
||||||
|
|
||||||
`Sequences`:idx: are similar to arrays but of dynamic length which may change
|
`Sequences`:idx: are similar to arrays but of dynamic length which may change
|
||||||
during runtime (like strings). A sequence ``S`` is always indexed by integers
|
during runtime (like strings). A sequence ``S`` is always indexed by integers
|
||||||
from 0 to ``len(S)-1`` and its bounds are checked. Sequences can also be
|
from 0 to ``len(S)-1`` and its bounds are checked. Sequences can be
|
||||||
constructed by the array constructor ``[]``.
|
constructed by the array constructor ``[]`` in conjunction with the array to
|
||||||
|
sequence operator ``@``. Another way to allocate space for a sequence is to
|
||||||
|
call the built-in ``newSeq`` procedure.
|
||||||
|
|
||||||
A sequence may be passed to a parameter that is of type *open array*, but
|
A sequence may be passed to a parameter that is of type *open array*, but
|
||||||
not to a multi-dimensional open array, because it is impossible to do so in an
|
not to a multi-dimensional open array, because it is impossible to do so in an
|
||||||
efficient manner.
|
efficient manner.
|
||||||
|
|
||||||
An array expression may be constructed by the array constructor ``[]``.
|
|
||||||
A constructed array is assignment compatible to a sequence.
|
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
|
|
@ -625,13 +625,13 @@ Example:
|
||||||
var
|
var
|
||||||
x: TIntArray
|
x: TIntArray
|
||||||
y: TIntSeq
|
y: TIntSeq
|
||||||
x = [1, 2, 3, 4, 5, 6] # [] this is the array constructor that is compatible
|
x = [1, 2, 3, 4, 5, 6] # [] this is the array constructor
|
||||||
# with arrays, open arrays and
|
y = @[1, 2, 3, 4, 5, 6] # the @ turns the array into a sequence
|
||||||
y = [1, 2, 3, 4, 5, 6] # sequences
|
|
||||||
|
|
||||||
The lower bound of an array may be received by the built-in proc
|
The lower bound of an array or sequence may be received by the built-in proc
|
||||||
``low()``, the higher bound by ``high()``. The length may be
|
``low()``, the higher bound by ``high()``. The length may be
|
||||||
received by ``len()``.
|
received by ``len()``. ``low()`` for a sequence or an open array always returns
|
||||||
|
0, as this is the first valid index.
|
||||||
|
|
||||||
Arrays are always bounds checked (at compile-time or at runtime). These
|
Arrays are always bounds checked (at compile-time or at runtime). These
|
||||||
checks can be disabled via pragmas or invoking the compiler with the
|
checks can be disabled via pragmas or invoking the compiler with the
|
||||||
|
|
@ -692,6 +692,48 @@ Object fields that should be visible outside from the defining module, have to
|
||||||
marked by ``*``. In contrast to tuples, different object types are
|
marked by ``*``. In contrast to tuples, different object types are
|
||||||
never *equivalent*.
|
never *equivalent*.
|
||||||
|
|
||||||
|
Object variants
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
Often an object hierarchy is overkill in certain situations where simple
|
||||||
|
`variant`:idx: types are needed.
|
||||||
|
|
||||||
|
An example:
|
||||||
|
|
||||||
|
.. code-block:: nimrod
|
||||||
|
|
||||||
|
# This is an example how an abstract syntax tree could be modelled in Nimrod
|
||||||
|
type
|
||||||
|
TNodeKind = enum # the different node types
|
||||||
|
nkInt, # a leaf with an integer value
|
||||||
|
nkFloat, # a leaf with a float value
|
||||||
|
nkString, # a leaf with a string value
|
||||||
|
nkAdd, # an addition
|
||||||
|
nkSub, # a subtraction
|
||||||
|
nkIf # an if statement
|
||||||
|
PNode = ref TNode
|
||||||
|
TNode = object
|
||||||
|
case kind: TNodeKind # the ``kind`` field is the discriminator
|
||||||
|
of nkInt: intVal: int
|
||||||
|
of nkFloat: floavVal: float
|
||||||
|
of nkString: strVal: string
|
||||||
|
of nkAdd, nkSub:
|
||||||
|
leftOp, rightOp: PNode
|
||||||
|
of nkIf:
|
||||||
|
condition, thenPart, elsePart: PNode
|
||||||
|
|
||||||
|
var
|
||||||
|
n: PNode
|
||||||
|
new(n) # creates a new node
|
||||||
|
n.kind = nkFloat
|
||||||
|
n.floatVal = 0.0 # valid, because ``n.kind==nkFloat``, so that it fits
|
||||||
|
# the following statement raises an `EInvalidField` exception, because
|
||||||
|
# n.kind's value does not fit:
|
||||||
|
n.strVal = ""
|
||||||
|
|
||||||
|
As can been seen from the example, an advantage to an object hierarchy is that
|
||||||
|
no casting between different object types is needed. Yet, access to invalid
|
||||||
|
object fields raises an exception.
|
||||||
|
|
||||||
|
|
||||||
Set type
|
Set type
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
|
|
@ -773,7 +815,7 @@ further information.
|
||||||
|
|
||||||
Special care has to be taken if an untraced object contains traced objects like
|
Special care has to be taken if an untraced object contains traced objects like
|
||||||
traced references, strings or sequences: In order to free everything properly,
|
traced references, strings or sequences: In order to free everything properly,
|
||||||
the built-in procedure ``finalize`` has to be called before freeing the
|
the built-in procedure ``GCunref`` has to be called before freeing the
|
||||||
untraced memory manually!
|
untraced memory manually!
|
||||||
|
|
||||||
.. XXX finalizers for traced objects
|
.. XXX finalizers for traced objects
|
||||||
|
|
@ -867,7 +909,7 @@ statement.
|
||||||
|
|
||||||
Statements are separated into `simple statements`:idx: and
|
Statements are separated into `simple statements`:idx: and
|
||||||
`complex statements`:idx:.
|
`complex statements`:idx:.
|
||||||
Simple statements are statements that cannot contain other statements, like
|
Simple statements are statements that cannot contain other statements like
|
||||||
assignments, calls or the ``return`` statement; complex statements can
|
assignments, calls or the ``return`` statement; complex statements can
|
||||||
contain other statements. To avoid the `dangling else problem`:idx:, complex
|
contain other statements. To avoid the `dangling else problem`:idx:, complex
|
||||||
statements always have to be intended::
|
statements always have to be intended::
|
||||||
|
|
@ -1028,10 +1070,10 @@ Example:
|
||||||
The `case`:idx: statement is similar to the if statement, but it represents
|
The `case`:idx: statement is similar to the if statement, but it represents
|
||||||
a multi-branch selection. The expression after the keyword ``case`` is
|
a multi-branch selection. The expression after the keyword ``case`` is
|
||||||
evaluated and if its value is in a *vallist* the corresponding statements
|
evaluated and if its value is in a *vallist* the corresponding statements
|
||||||
(after the ``of`` keyword) are executed. If the value is no given *vallist*
|
(after the ``of`` keyword) are executed. If the value is not in any
|
||||||
the ``else`` part is executed. If there is no ``else`` part and not all
|
given *slicelist* the ``else`` part is executed. If there is no ``else``
|
||||||
possible values that ``expr`` can hold occur in a ``vallist``, a static
|
part and not all possible values that ``expr`` can hold occur in a ``vallist``,
|
||||||
error is given. This holds only for expressions of ordinal types.
|
a static error is given. This holds only for expressions of ordinal types.
|
||||||
If the expression is not of an ordinal type, and no ``else`` part is
|
If the expression is not of an ordinal type, and no ``else`` part is
|
||||||
given, control just passes after the ``case`` statement.
|
given, control just passes after the ``case`` statement.
|
||||||
|
|
||||||
|
|
@ -1331,10 +1373,8 @@ is used if the caller does not provide a value for this parameter. Example:
|
||||||
`Operators`:idx: are procedures with a special operator symbol as identifier:
|
`Operators`:idx: are procedures with a special operator symbol as identifier:
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
proc `$` (x: int): string = # converts an integer to a string;
|
proc `$` (x: int): string =
|
||||||
# since it has one parameter this is a prefix
|
# converts an integer to a string; this is a prefix operator.
|
||||||
# operator. With two parameters it would be
|
|
||||||
# an infix operator.
|
|
||||||
return intToStr(x)
|
return intToStr(x)
|
||||||
|
|
||||||
Calling a procedure can be done in many different ways:
|
Calling a procedure can be done in many different ways:
|
||||||
|
|
@ -1557,7 +1597,7 @@ This is best illustrated by an example:
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
# Module A
|
# Module A
|
||||||
type
|
type
|
||||||
T1* = int
|
T1* = int # Module A exports the type ``T1``
|
||||||
import B # the compiler starts parsing B
|
import B # the compiler starts parsing B
|
||||||
|
|
||||||
proc main() =
|
proc main() =
|
||||||
|
|
@ -1660,12 +1700,19 @@ Nimrod source code. The conditional symbols go into a special symbol table.
|
||||||
The compiler defines the target processor and the target operating
|
The compiler defines the target processor and the target operating
|
||||||
system as conditional symbols.
|
system as conditional symbols.
|
||||||
|
|
||||||
|
Warning: The ``define`` pragma is deprecated as it conflicts with separate
|
||||||
|
compilation! One should use boolean constants as a replacement - this is
|
||||||
|
cleaner anyway.
|
||||||
|
|
||||||
|
|
||||||
undef pragma
|
undef pragma
|
||||||
------------
|
------------
|
||||||
The `undef`:idx: pragma the counterpart to the define pragma. It undefines a
|
The `undef`:idx: pragma the counterpart to the define pragma. It undefines a
|
||||||
conditional symbol.
|
conditional symbol.
|
||||||
|
|
||||||
|
Warning: The ``undef`` pragma is deprecated as it conflicts with separate
|
||||||
|
compilation!
|
||||||
|
|
||||||
|
|
||||||
error pragma
|
error pragma
|
||||||
------------
|
------------
|
||||||
|
|
|
||||||
115
doc/nimrodc.txt
115
doc/nimrodc.txt
|
|
@ -34,8 +34,15 @@ Advanced command line switches are:
|
||||||
|
|
||||||
Configuration file
|
Configuration file
|
||||||
------------------
|
------------------
|
||||||
The ``nimrod`` executable loads the configuration file ``config/nimrod.cfg``
|
The default configuration file is ``nimrod.cfg``. The ``nimrod`` executable
|
||||||
unless this is suppressed by the ``--skip_cfg`` command line option.
|
looks for it in the following directories (in this order):
|
||||||
|
|
||||||
|
1. ``/home/$user/.config/nimrod.cfg`` (UNIX) or ``$APPDATA/nimrod.cfg`` (Windows)
|
||||||
|
2. ``$nimrod/config/nimrod.cfg`` (UNIX, Windows)
|
||||||
|
3. ``/etc/nimrod.cfg`` (UNIX)
|
||||||
|
|
||||||
|
The search stops as soon as a configuration file has been found. The reading
|
||||||
|
of ``nimrod.cfg`` can be suppressed by the ``--skip_cfg`` command line option.
|
||||||
Configuration settings can be overwritten in a project specific
|
Configuration settings can be overwritten in a project specific
|
||||||
configuration file that is read automatically. This specific file has to
|
configuration file that is read automatically. This specific file has to
|
||||||
be in the same directory as the project and be of the same name, except
|
be in the same directory as the project and be of the same name, except
|
||||||
|
|
@ -47,11 +54,10 @@ Command line settings have priority over configuration file settings.
|
||||||
Nimrod's directory structure
|
Nimrod's directory structure
|
||||||
----------------------------
|
----------------------------
|
||||||
The generated files that Nimrod produces all go into a subdirectory called
|
The generated files that Nimrod produces all go into a subdirectory called
|
||||||
``rod_gen``. This makes it easy to write a script that deletes all generated
|
``nimcache`` in your project directory. This makes it easy to delete all
|
||||||
files. For example the generated C code for the module ``path/modA.nim``
|
generated files.
|
||||||
will become ``path/rod_gen/modA.c``.
|
|
||||||
|
|
||||||
However, the generated C code is not platform independant! C code generated for
|
However, the generated C code is not platform independant. C code generated for
|
||||||
Linux does not compile on Windows, for instance. The comment on top of the
|
Linux does not compile on Windows, for instance. The comment on top of the
|
||||||
C file lists the OS, CPU and CC the file has been compiled for.
|
C file lists the OS, CPU and CC the file has been compiled for.
|
||||||
|
|
||||||
|
|
@ -77,10 +83,46 @@ Because Nimrod generates C code it needs some "red tape" to work properly.
|
||||||
Thus lots of options and pragmas for tweaking the generated C code are
|
Thus lots of options and pragmas for tweaking the generated C code are
|
||||||
available.
|
available.
|
||||||
|
|
||||||
|
Importc Pragma
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
The `importc`:idx: pragma provides a means to import a type, a variable, or a
|
||||||
|
procedure from C. The optional argument is a string containing the C
|
||||||
|
identifier. If the argument is missing, the C name is the Nimrod
|
||||||
|
identifier *exactly as spelled*:
|
||||||
|
|
||||||
|
.. code-block::
|
||||||
|
proc printf(formatstr: cstring) {.importc: "printf", varargs.}
|
||||||
|
|
||||||
|
|
||||||
|
Exportc Pragma
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
The `exportc`:idx: pragma provides a means to export a type, a variable, or a
|
||||||
|
procedure to C. The optional argument is a string containing the C
|
||||||
|
identifier. If the argument is missing, the C name is the Nimrod
|
||||||
|
identifier *exactly as spelled*:
|
||||||
|
|
||||||
|
.. code-block:: Nimrod
|
||||||
|
proc callme(formatstr: cstring) {.exportc: "callMe", varargs.}
|
||||||
|
|
||||||
|
|
||||||
|
Dynlib Pragma
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
With the `dynlib`:idx: pragma a procedure or a variable can be imported from
|
||||||
|
a dynamic library (``.dll`` files for Windows, ``lib*.so`` files for UNIX). The
|
||||||
|
non-optional argument has to be the name of the dynamic library:
|
||||||
|
|
||||||
|
.. code-block:: Nimrod
|
||||||
|
proc gtk_image_new(): PGtkWidget {.cdecl, dynlib: "libgtk-x11-2.0.so", importc.}
|
||||||
|
|
||||||
|
In general, importing a dynamic library does not require any special linker
|
||||||
|
options or linking with import libraries. This also
|
||||||
|
implies that no *devel* packages need to be installed.
|
||||||
|
|
||||||
|
|
||||||
No_decl Pragma
|
No_decl Pragma
|
||||||
~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~
|
||||||
The `no_decl`:idx: pragma can be applied to almost any symbol (variable, proc,
|
The `no_decl`:idx: pragma can be applied to almost any symbol (variable, proc,
|
||||||
type, etc.) and is one of the most important for interoperability with C:
|
type, etc.) and is sometimes useful for interoperability with C:
|
||||||
It tells Nimrod that it should not generate a declaration for the symbol in
|
It tells Nimrod that it should not generate a declaration for the symbol in
|
||||||
the C code. Thus it makes the following possible, for example:
|
the C code. Thus it makes the following possible, for example:
|
||||||
|
|
||||||
|
|
@ -89,17 +131,7 @@ the C code. Thus it makes the following possible, for example:
|
||||||
EOF {.importc: "EOF", no_decl.}: cint # pretend EOF was a variable, as
|
EOF {.importc: "EOF", no_decl.}: cint # pretend EOF was a variable, as
|
||||||
# Nimrod does not know its value
|
# Nimrod does not know its value
|
||||||
|
|
||||||
Varargs Pragma
|
However, the ``header`` pragma is often the better alternative.
|
||||||
~~~~~~~~~~~~~~
|
|
||||||
The `varargs`:idx: pragma can be applied to procedures only. It tells Nimrod
|
|
||||||
that the proc can take a variable number of parameters after the last
|
|
||||||
specified parameter. Nimrod string values will be converted to C
|
|
||||||
strings automatically:
|
|
||||||
|
|
||||||
.. code-block:: Nimrod
|
|
||||||
proc printf(formatstr: cstring) {.nodecl, varargs.}
|
|
||||||
|
|
||||||
printf("hallo %s", "world") # "world" will be passed as C string
|
|
||||||
|
|
||||||
|
|
||||||
Header Pragma
|
Header Pragma
|
||||||
|
|
@ -119,12 +151,25 @@ in angle brackets: ``<>``. If no angle brackets are given, Nimrod
|
||||||
encloses the header file in ``""`` in the generated C code.
|
encloses the header file in ``""`` in the generated C code.
|
||||||
|
|
||||||
|
|
||||||
|
Varargs Pragma
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
The `varargs`:idx: pragma can be applied to procedures only. It tells Nimrod
|
||||||
|
that the proc can take a variable number of parameters after the last
|
||||||
|
specified parameter. Nimrod string values will be converted to C
|
||||||
|
strings automatically:
|
||||||
|
|
||||||
|
.. code-block:: Nimrod
|
||||||
|
proc printf(formatstr: cstring) {.nodecl, varargs.}
|
||||||
|
|
||||||
|
printf("hallo %s", "world") # "world" will be passed as C string
|
||||||
|
|
||||||
|
|
||||||
No_static Pragma
|
No_static Pragma
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
The `no_static`:idx: pragma can be applied to almost any symbol and specifies
|
The `no_static`:idx: pragma can be applied to almost any symbol and specifies
|
||||||
that it shall not be declared ``static`` in the generated C code. Note that
|
that it shall not be declared ``static`` in the generated C code. Note that
|
||||||
symbols in the interface part of a module never get declared ``static``, so
|
symbols in the interface part of a module never get declared ``static``, so
|
||||||
only in special cases is this pragma necessary.
|
only in very special cases this pragma is necessary.
|
||||||
|
|
||||||
|
|
||||||
Line_dir Option
|
Line_dir Option
|
||||||
|
|
@ -171,8 +216,29 @@ The `register`:idx: pragma is for variables only. It declares the variable as
|
||||||
in a hardware register for faster access. C compilers usually ignore this
|
in a hardware register for faster access. C compilers usually ignore this
|
||||||
though and for good reason: Often they do a better job without it anyway.
|
though and for good reason: Often they do a better job without it anyway.
|
||||||
|
|
||||||
In highly specific cases (a dispatch loop of interpreters for example) it
|
In highly specific cases (a dispatch loop of an bytecode interpreter for
|
||||||
may provide benefits, though.
|
example) it may provide benefits, though.
|
||||||
|
|
||||||
|
|
||||||
|
Acyclic Pragma
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
The `acyclic`:idx: pragma can be used for object types to mark them as acyclic
|
||||||
|
even though they seem to be cyclic. This is an **optimization** for the garbage
|
||||||
|
collector to not consider objects of this type as part of a cycle::
|
||||||
|
|
||||||
|
type
|
||||||
|
PNode = ref TNode
|
||||||
|
TNode {.acyclic, final.} = object
|
||||||
|
left, right: PNode
|
||||||
|
data: string
|
||||||
|
|
||||||
|
In the example a tree structure is declared with the ``TNode`` type. Note that
|
||||||
|
the type definition is recursive thus the GC has to assume that objects of
|
||||||
|
this type may form a cyclic graph. The ``acyclic`` pragma passes the
|
||||||
|
information that this cannot happen to the GC. If the programmer uses the
|
||||||
|
``acyclic`` pragma for data types that are in reality cyclic, the GC may leak
|
||||||
|
memory, but nothing worse happens.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Disabling certain messages
|
Disabling certain messages
|
||||||
|
|
@ -244,12 +310,17 @@ efficient than any hand-coded scheme.
|
||||||
The ECMAScript code generator
|
The ECMAScript code generator
|
||||||
=============================
|
=============================
|
||||||
|
|
||||||
|
Note: As of version 0.7.0 the ECMAScript code generator is not maintained any
|
||||||
|
longer. Help if you are interested.
|
||||||
|
|
||||||
Note: I use the term `ECMAScript`:idx: here instead of `JavaScript`:idx:, since
|
Note: I use the term `ECMAScript`:idx: here instead of `JavaScript`:idx:, since
|
||||||
it is the proper term.
|
it is the proper term.
|
||||||
|
|
||||||
|
The ECMAScript code generator is experimental!
|
||||||
|
|
||||||
Nimrod targets ECMAScript 1.5 which is supported by any widely used browser.
|
Nimrod targets ECMAScript 1.5 which is supported by any widely used browser.
|
||||||
Since ECMAScript does not have a portable means to include another module,
|
Since ECMAScript does not have a portable means to include another module,
|
||||||
Nimrod just generate a long ``.js`` file.
|
Nimrod just generates a long ``.js`` file.
|
||||||
|
|
||||||
Features or modules that the ECMAScript platform does not support are not
|
Features or modules that the ECMAScript platform does not support are not
|
||||||
available. This includes:
|
available. This includes:
|
||||||
|
|
|
||||||
1297
doc/spec.txt
1297
doc/spec.txt
File diff suppressed because it is too large
Load diff
7627
doc/theindex.txt
7627
doc/theindex.txt
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,7 @@
|
||||||
|
# The beginning of an IDE for Nimrod
|
||||||
|
# (c) 2008 Andreas Rumpf
|
||||||
|
|
||||||
import glib2, gtk2, libglade2, dialogs
|
import glib2, gtk2, libglade2, dialogs, parseopt
|
||||||
|
|
||||||
proc on_window_destroy(obj: PGtkObject, data: pointer) {.cdecl.} =
|
proc on_window_destroy(obj: PGtkObject, data: pointer) {.cdecl.} =
|
||||||
gtk_main_quit()
|
gtk_main_quit()
|
||||||
|
|
|
||||||
55
install.txt
55
install.txt
|
|
@ -9,18 +9,19 @@ Note:
|
||||||
A C compiler is required - knowledge of C is not!
|
A C compiler is required - knowledge of C is not!
|
||||||
|
|
||||||
The GNU C Compiler is fully supported, other compilers may work. The C compiler
|
The GNU C Compiler is fully supported, other compilers may work. The C compiler
|
||||||
should be in your ``$PATH`` (most likely the case). Note that some Linux
|
should be in your ``$PATH`` (most likely the case). Note that some few Linux
|
||||||
distributions do not ship with a GCC compiler preinstalled - then you have to
|
distributions do not ship with a GCC compiler preinstalled - then you have to
|
||||||
install it.
|
install it.
|
||||||
|
|
||||||
After you have made sure that a C compiler is available, install Nimrod
|
Install Nimrod by downloading the appropriate ``.zip`` file and extracting it
|
||||||
by downloading the appropriate ``.zip`` file and extracting it to a
|
to a directory of your choice. The Nimrod Compiler will stay in this
|
||||||
directory of your choice. The Nimrod Compiler will stay in this
|
directory (unless you copy it somewhere else). The compiler does not need
|
||||||
directory; do not use a temporary one! Good choices are ``/opt/nimrod`` or -
|
write access to its directory anymore, so copying the nimrod folder to ``/opt``
|
||||||
if you don't have root access - ``~/programs/nimrod``.
|
does work.
|
||||||
|
|
||||||
Then run the following command::
|
Then run the following command::
|
||||||
|
|
||||||
python koch.py install
|
sh build.sh
|
||||||
|
|
||||||
Unlike other software, Nimrod does not distribute its files over the whole file
|
Unlike other software, Nimrod does not distribute its files over the whole file
|
||||||
hierarchy. This has the advantage that you can deinstall it by just deleting
|
hierarchy. This has the advantage that you can deinstall it by just deleting
|
||||||
|
|
@ -39,48 +40,26 @@ need to install Apple's developer's tools for the GNU Compiler Collection
|
||||||
though.
|
though.
|
||||||
|
|
||||||
|
|
||||||
Installation on Windows - the easy way
|
Installation on Windows
|
||||||
--------------------------------------
|
-----------------------
|
||||||
|
|
||||||
Install Nimrod by downloading and running
|
Install Nimrod by downloading and running
|
||||||
the ``nimrod_windows_$version.exe`` file. The installation procedure detects
|
the ``nimrod_$version.exe`` file. As default, the ``LLVM-GCC``
|
||||||
which C compilers are installed and writes the ``config/nimrod.cfg`` file
|
compiler is used that is bundled with this installer. You can change
|
||||||
for you. If no installed C compiler is found, the ``LLVM-GCC`` compiler is
|
the configuration file to use another C compiler.
|
||||||
used that is bundled with this installer. So it should just work.
|
|
||||||
|
|
||||||
|
Currently, the following C compilers are supported under Windows:
|
||||||
Installation on Windows - the hard way
|
|
||||||
--------------------------------------
|
|
||||||
|
|
||||||
Windows does not ship with a C compiler; you have to install one. The
|
|
||||||
following C compilers are supported under Windows:
|
|
||||||
|
|
||||||
- | Microsoft's Visual C++
|
- | Microsoft's Visual C++
|
||||||
| http://msdn.microsoft.com/visualc
|
| http://msdn.microsoft.com/visualc
|
||||||
| (You may need the SDK too - but not the full one: Essential are only
|
| (You need the SDK too - but not the full one: Essential are only
|
||||||
the win32api header files and import libraries.)
|
the win32api header files and import libraries.)
|
||||||
- | Borland C++ (5.5 or above; including Borland C++Builder)
|
|
||||||
| http://www.borland.com/downloads/download_cbuilder.html
|
|
||||||
| (Download the package under "compiler" - this requires registration though.)
|
|
||||||
- | Gnu C Compiler (the mingw version; the cygwin version has not been tested!)
|
- | Gnu C Compiler (the mingw version; the cygwin version has not been tested!)
|
||||||
| http://www.mingw.org/download.shtml
|
| http://www.mingw.org/download.shtml
|
||||||
- | LLVM with GNU C/C++ frontend
|
- | LLVM with GNU C/C++ frontend
|
||||||
| http://llvm.org/releases/download.html#2.2
|
| http://llvm.org/releases/download.html#2.2
|
||||||
- | Digital Mars C++
|
- | Digital Mars C++
|
||||||
| http://www.digitalmars.com/download/freecompiler.html
|
| http://www.digitalmars.com/download/freecompiler.html
|
||||||
- | Pelles C Compiler (bootstrapping does not work with PCC!)
|
|
||||||
| http://www.smorgasbordet.com/pellesc
|
|
||||||
- | Lcc-win32 (bootstrapping does not work with LCC!)
|
|
||||||
| http://www.cs.virginia.edu/~lcc-win32
|
|
||||||
|
|
||||||
All of the above compilers are available for free!
|
For faster compile times I recommend Digital Mars C++ -- it is easy to install
|
||||||
(The first three are the easiest to install.) If you want a small download,
|
and a small package.
|
||||||
choose Digital Mars C++ -- it is easy to install and only about 3 MB.
|
|
||||||
If you want the highest possible performance, go for Microsoft's Visual C++ or
|
|
||||||
LLVM.
|
|
||||||
|
|
||||||
After you have made sure that a C compiler is available, install
|
|
||||||
Nimrod by downloading the appropriate .zip file and extracting it to a
|
|
||||||
directory of your choice. The Nimrod Compiler will stay in this
|
|
||||||
directory; do not use a temporary one! Then adapt the ``config/nimrod.cfg``
|
|
||||||
file appropriately. You should add Nimrod to your ``$PATH``.
|
|
||||||
|
|
|
||||||
662
kochmod.py
662
kochmod.py
|
|
@ -1,662 +0,0 @@
|
||||||
# This is kochmod, a simple module for make-like functionality.
|
|
||||||
# For further documentation see koch.txt or koch.html.
|
|
||||||
# (c) 2007 Andreas Rumpf
|
|
||||||
|
|
||||||
VERSION = "1.0.4"
|
|
||||||
|
|
||||||
import os, os.path, inspect, re, shutil, glob, cPickle, zlib, string, \
|
|
||||||
getopt, sys
|
|
||||||
from types import *
|
|
||||||
|
|
||||||
def Error(msg): sys.exit("[Koch] *** ERROR: " + msg)
|
|
||||||
def Warn(msg): print "[Koch] *** WARNING: " + msg
|
|
||||||
def Echo(msg): print "[Koch] " + msg
|
|
||||||
def _Info(msg): print "[Koch] " + msg
|
|
||||||
|
|
||||||
_FINGERPRINTS_FILE = "koch.dat"
|
|
||||||
# in this file all the fingerprints are kept to allow recognizing when a file
|
|
||||||
# has changed. This works reliably, which cannot be said from just taking
|
|
||||||
# filetime-stamps.
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
def FileCmp(filenameA, filenameB):
|
|
||||||
SIZE = 4096*2
|
|
||||||
result = True
|
|
||||||
a = file(filenameA, "rb")
|
|
||||||
b = file(filenameB, "rb")
|
|
||||||
while True:
|
|
||||||
x = a.read(SIZE)
|
|
||||||
y = b.read(SIZE)
|
|
||||||
if x != y:
|
|
||||||
result = False
|
|
||||||
break
|
|
||||||
elif len(x) < SIZE: # EOF?
|
|
||||||
break
|
|
||||||
a.close()
|
|
||||||
b.close()
|
|
||||||
return result
|
|
||||||
|
|
||||||
# ---------------- C Compilers ------------------------------------------------
|
|
||||||
|
|
||||||
# We support the following C compilers:
|
|
||||||
C_Compilers = ["gcc", "lcc", "bcc", "dmc", "wcc", "tcc", "pcc", "ucc", "llvm"]
|
|
||||||
|
|
||||||
_CC_Info = [
|
|
||||||
dict(
|
|
||||||
name = "gcc",
|
|
||||||
objExt = "o",
|
|
||||||
optSpeed = " -O3 -ffast-math ",
|
|
||||||
optSize = " -Os -ffast-math ",
|
|
||||||
comp = "gcc -c $options $include -o $objfile $file",
|
|
||||||
buildGui = " -mwindows",
|
|
||||||
buildDll = " -mdll",
|
|
||||||
link = "gcc $options $buildgui $builddll -o $exefile $objfiles",
|
|
||||||
includeCmd = " -I",
|
|
||||||
debug = "",
|
|
||||||
defineValue = " -D$name=$value",
|
|
||||||
define = " -D$name",
|
|
||||||
undef = " -U$name",
|
|
||||||
pic = "-fPIC"
|
|
||||||
), dict(
|
|
||||||
name = "lcc",
|
|
||||||
objExt = "obj",
|
|
||||||
optSpeed = " -O -p6 ",
|
|
||||||
optSize = " -O -p6 ",
|
|
||||||
comp = "lcc -e1 $options $include -Fo$objfile $file",
|
|
||||||
buildGui = " -subsystem windows",
|
|
||||||
buildDll = " -dll",
|
|
||||||
link = "lcclnk $options $buildgui $builddll -O $exefile $objfiles",
|
|
||||||
includeCmd = " -I",
|
|
||||||
debug = " -g5 ",
|
|
||||||
defineValue = " -D$name=$value",
|
|
||||||
define = " -D$name",
|
|
||||||
undef = " -U$name",
|
|
||||||
pic = ""
|
|
||||||
), dict(
|
|
||||||
name = "bcc",
|
|
||||||
objExt = "obj",
|
|
||||||
optSpeed = " -O2 -6 ",
|
|
||||||
optSize = " -O1 -6 ",
|
|
||||||
comp = "bcc32 -c -H- -q -RT- -a8 $options $include -o$objfile $file",
|
|
||||||
buildGui = " -tW",
|
|
||||||
buildDll = " -tWD",
|
|
||||||
link = "bcc32 $options $buildgui $builddll -e$exefile $objfiles",
|
|
||||||
includeCmd = " -I",
|
|
||||||
debug = "",
|
|
||||||
defineValue = " -D$name=$value",
|
|
||||||
define = " -D$name",
|
|
||||||
undef = " -U$name",
|
|
||||||
pic = ""
|
|
||||||
), dict(
|
|
||||||
name = "dmc",
|
|
||||||
objExt = "obj",
|
|
||||||
optSpeed = " -ff -o -6 ",
|
|
||||||
optSize = " -ff -o -6 ",
|
|
||||||
comp = "dmc -c -Jm $options $include -o$objfile $file",
|
|
||||||
buildGui = " -L/exet:nt/su:windows",
|
|
||||||
buildDll = " -WD",
|
|
||||||
link = "dmc $options $buildgui $builddll -o$exefile $objfiles",
|
|
||||||
includeCmd = " -I",
|
|
||||||
debug = " -g ",
|
|
||||||
defineValue = " -D$name=$value",
|
|
||||||
define = " -D$name",
|
|
||||||
undef = " -U$name", # XXX: dmc does not have -U ?
|
|
||||||
pic = ""
|
|
||||||
), dict(
|
|
||||||
name = "wcc",
|
|
||||||
objExt = "obj",
|
|
||||||
optSpeed = " -ox -on -6 -d0 -fp6 -zW ",
|
|
||||||
optSize = "",
|
|
||||||
comp = "wcl386 -c -6 -zw $options $include -fo=$objfile $file",
|
|
||||||
buildGui = " -bw",
|
|
||||||
buildDll = " -bd",
|
|
||||||
link = "wcl386 $options $buildgui $builddll -fe=$exefile $objfiles ",
|
|
||||||
includeCmd = " -i=",
|
|
||||||
debug = " -d2 ",
|
|
||||||
defineValue = " -d$name=$value",
|
|
||||||
define = " -d$name",
|
|
||||||
undef = " -u$name",
|
|
||||||
pic = ""
|
|
||||||
), dict(
|
|
||||||
name = "vcc",
|
|
||||||
objExt = "obj",
|
|
||||||
optSpeed = " /Ogityb2 /G7 /arch:SSE2 ",
|
|
||||||
optSize = " /O1 /G7 ",
|
|
||||||
comp = "cl /c $options $include /Fo$objfile $file",
|
|
||||||
buildGui = " /link /SUBSYSTEM:WINDOWS ",
|
|
||||||
buildDll = " /LD",
|
|
||||||
link = "cl $options $builddll /Fe$exefile $objfiles $buildgui",
|
|
||||||
includeCmd = " /I",
|
|
||||||
debug = " /GZ /Zi ",
|
|
||||||
defineValue = " /D$name=$value",
|
|
||||||
define = " /D$name",
|
|
||||||
undef = " /U$name",
|
|
||||||
pic = ""
|
|
||||||
), dict(
|
|
||||||
name = "tcc",
|
|
||||||
objExt = "o",
|
|
||||||
optSpeed = "", # Tiny C has no optimizer
|
|
||||||
optSize = "",
|
|
||||||
comp = "tcc -c $options $include -o $objfile $file",
|
|
||||||
buildGui = "UNAVAILABLE!",
|
|
||||||
buildDll = " -shared",
|
|
||||||
link = "tcc -o $exefile $options $buildgui $builddll $objfiles",
|
|
||||||
includeCmd = " -I",
|
|
||||||
debug = " -b ",
|
|
||||||
defineValue = " -D$name=$value",
|
|
||||||
define = " -D$name",
|
|
||||||
undef = " -U$name",
|
|
||||||
pic = ""
|
|
||||||
), dict(
|
|
||||||
name = "pcc", # Pelles C
|
|
||||||
objExt = "obj",
|
|
||||||
optSpeed = " -Ox ",
|
|
||||||
optSize = " -Os ",
|
|
||||||
comp = "cc -c $options $include -Fo$objfile $file",
|
|
||||||
buildGui = " -SUBSYSTEM:WINDOWS",
|
|
||||||
buildDll = " -DLL",
|
|
||||||
link = "cc $options $buildgui $builddll -OUT:$exefile $objfiles",
|
|
||||||
includeCmd = " -I",
|
|
||||||
debug = " -Zi ",
|
|
||||||
defineValue = " -D$name=$value",
|
|
||||||
define = " -D$name",
|
|
||||||
undef = " -U$name",
|
|
||||||
pic = ""
|
|
||||||
), dict(
|
|
||||||
name = "ucc",
|
|
||||||
objExt = "o",
|
|
||||||
optSpeed = " -O3 ",
|
|
||||||
optSize = " -O1 ",
|
|
||||||
comp = "cc -c $options $include -o $objfile $file",
|
|
||||||
buildGui = "",
|
|
||||||
buildDll = " -shared ",
|
|
||||||
link = "cc -o $exefile $options $buildgui $builddll $objfiles",
|
|
||||||
includeCmd = " -I",
|
|
||||||
debug = "",
|
|
||||||
defineValue = " -D$name=$value",
|
|
||||||
define = " -D$name",
|
|
||||||
undef = " -U$name",
|
|
||||||
pic = ""
|
|
||||||
), dict(
|
|
||||||
name = "llvm_gcc", # its options are the same as GCC's
|
|
||||||
objExt = "o",
|
|
||||||
optSpeed = " -O3 -ffast-math ",
|
|
||||||
optSize = " -Os -ffast-math ",
|
|
||||||
comp = "llvm-gcc -c $options $include -o $objfile $file",
|
|
||||||
buildGui = " -mwindows",
|
|
||||||
buildDll = " -mdll",
|
|
||||||
link = "llvm-gcc $options $buildgui $builddll -o $exefile $objfiles",
|
|
||||||
includeCmd = " -I",
|
|
||||||
debug = "",
|
|
||||||
defineValue = " -D$name=$value",
|
|
||||||
define = " -D$name",
|
|
||||||
undef = " -U$name",
|
|
||||||
pic = "-fPIC"
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
# --------------- little helpers ---------------------------------------------
|
|
||||||
|
|
||||||
def Subs(frmt, **substitution):
|
|
||||||
if isinstance(frmt, basestring):
|
|
||||||
return string.Template(frmt).substitute(substitution)
|
|
||||||
else:
|
|
||||||
return tuple([string.Template(x).substitute(substitution) for x in frmt])
|
|
||||||
|
|
||||||
def SafeSubs(frmt, **substitution):
|
|
||||||
return string.Template(frmt).safe_substitute(substitution)
|
|
||||||
|
|
||||||
_baseDir = os.getcwd()
|
|
||||||
BaseDir = _baseDir
|
|
||||||
|
|
||||||
def Path(a):
|
|
||||||
# Gets a UNIX like path and converts it to a path on this platform.
|
|
||||||
# With UNIX like, I mean: slashes, not backslashes, only relative
|
|
||||||
# paths ('../etc' can be used)
|
|
||||||
result = a
|
|
||||||
if os.sep != "/": result = result.replace("/", os.sep)
|
|
||||||
if os.pardir != "..": result = result.replace("..", os.pardir)
|
|
||||||
return result
|
|
||||||
|
|
||||||
def Join(*args):
|
|
||||||
result = ""
|
|
||||||
for a in args[:-1]:
|
|
||||||
result += a
|
|
||||||
if result[-1] != "/":
|
|
||||||
result += "/"
|
|
||||||
result += args[-1]
|
|
||||||
return result.replace("//", "/")
|
|
||||||
|
|
||||||
def Exec(command):
|
|
||||||
c = Path(command)
|
|
||||||
Echo(c)
|
|
||||||
result = os.system(c)
|
|
||||||
if result != 0: Error("execution of an external program failed")
|
|
||||||
return result
|
|
||||||
|
|
||||||
def TryExec(command):
|
|
||||||
c = Path(command)
|
|
||||||
Echo(c)
|
|
||||||
result = os.system(c)
|
|
||||||
return result
|
|
||||||
|
|
||||||
def RawExec(command):
|
|
||||||
Echo(command)
|
|
||||||
result = os.system(command)
|
|
||||||
if result != 0: Error("execution of an external program failed")
|
|
||||||
return result
|
|
||||||
|
|
||||||
def Move(src, dest):
|
|
||||||
s = Path(src)
|
|
||||||
d = Path(dest)
|
|
||||||
try:
|
|
||||||
shutil.move(s, d)
|
|
||||||
except IOError, OSError:
|
|
||||||
Warn("could not move %s to %s" % (s, d))
|
|
||||||
|
|
||||||
def Copy(src, dest):
|
|
||||||
s = Path(src)
|
|
||||||
d = Path(dest)
|
|
||||||
try:
|
|
||||||
shutil.copyfile(s, d)
|
|
||||||
except IOError, OSError:
|
|
||||||
Warn("could not copy %s to %s" % (s, d))
|
|
||||||
|
|
||||||
def Remove(f):
|
|
||||||
try:
|
|
||||||
os.remove(Path(f))
|
|
||||||
except OSError:
|
|
||||||
Warn("could not remove: %s" % f)
|
|
||||||
|
|
||||||
def RemoveDir(f):
|
|
||||||
try:
|
|
||||||
shutil.rmtree(Path(f))
|
|
||||||
except OSError:
|
|
||||||
Warn("could not remove: %s" % f)
|
|
||||||
|
|
||||||
def Exists(f): return os.path.exists(Path(f))
|
|
||||||
|
|
||||||
def Chdir(dest):
|
|
||||||
d = Path(dest)
|
|
||||||
try:
|
|
||||||
os.chdir(d)
|
|
||||||
except OSError:
|
|
||||||
Warn("could not switch to directory: " + d)
|
|
||||||
|
|
||||||
def Mkdir(dest):
|
|
||||||
d = Path(dest)
|
|
||||||
try:
|
|
||||||
os.mkdir(d)
|
|
||||||
except OSError:
|
|
||||||
Warn("could not create directory: " + d)
|
|
||||||
|
|
||||||
def Glob(pattern): # needed because glob.glob() is buggy on Windows 95:
|
|
||||||
# things like tests/t*.mor won't work
|
|
||||||
global _baseDir
|
|
||||||
(head, tail) = os.path.split(Path(pattern))
|
|
||||||
try:
|
|
||||||
os.chdir(os.path.join(_baseDir, head))
|
|
||||||
result = []
|
|
||||||
for f in glob.glob(tail):
|
|
||||||
result.append(os.path.join(head, f))
|
|
||||||
except OSError:
|
|
||||||
result = []
|
|
||||||
finally:
|
|
||||||
os.chdir(_baseDir)
|
|
||||||
return result
|
|
||||||
|
|
||||||
def FilenameNoExt(f):
|
|
||||||
return os.path.splitext(os.path.basename(f))[0]
|
|
||||||
|
|
||||||
def _Ext(trunc, posixFormat, winFormat):
|
|
||||||
(head, tail) = os.path.split(Path(trunc))
|
|
||||||
if os.name == "posix": frmt = posixFormat
|
|
||||||
else: frmt = winFormat
|
|
||||||
return os.path.join(head, Subs(frmt, trunc=tail))
|
|
||||||
|
|
||||||
def DynExt(trunc):
|
|
||||||
"""Makes a dynamic library out of a trunc. This means it either
|
|
||||||
does '${trunc}.dll' or 'lib${trunc}.so'.
|
|
||||||
"""
|
|
||||||
return _Ext(trunc, 'lib${trunc}.so', '${trunc}.dll')
|
|
||||||
|
|
||||||
def LibExt(trunc):
|
|
||||||
"""Makes a static library out of a trunc. This means it either
|
|
||||||
does '${trunc}.lib' or '${trunc}.a'.
|
|
||||||
"""
|
|
||||||
return _Ext(trunc, '${trunc}.a', '${trunc}.lib')
|
|
||||||
|
|
||||||
def ScriptExt(trunc):
|
|
||||||
"""Makes a script out of a trunc. This means it either
|
|
||||||
does '${trunc}.bat' or '${trunc}.sh'.
|
|
||||||
"""
|
|
||||||
return _Ext(trunc, '${trunc}.sh', '${trunc}.bat')
|
|
||||||
|
|
||||||
def ExeExt(trunc):
|
|
||||||
"""Makes an executable out of a trunc. This means it either
|
|
||||||
does '${trunc}.exe' or '${trunc}'.
|
|
||||||
"""
|
|
||||||
return _Ext(trunc, '${trunc}', '${trunc}.exe')
|
|
||||||
|
|
||||||
def MakeExecutable(file):
|
|
||||||
os.chmod(file, 493)
|
|
||||||
|
|
||||||
# ----------------- Dependency Analyser Core ---------------------------------
|
|
||||||
# We simply store the rules in a list until building the things. Checking is
|
|
||||||
# also delayed.
|
|
||||||
_rules = {}
|
|
||||||
_importantTargets = [] # used for command line switches
|
|
||||||
_commands = {} # other commands
|
|
||||||
# a command is a tuple: (name, description, function, number of arguments)
|
|
||||||
|
|
||||||
def Command(name, desc, func, args=0):
|
|
||||||
"""if args == -1, a variable number of arguments is given to the ``func``
|
|
||||||
as a list"""
|
|
||||||
_commands[name] = (desc, func, args)
|
|
||||||
|
|
||||||
def _applyPath(x):
|
|
||||||
if type(x) == ListType:
|
|
||||||
return map(Path, x)
|
|
||||||
else:
|
|
||||||
return Path(x)
|
|
||||||
|
|
||||||
def Rule(name = None, desc = "", prereqs = [], cmds = None, outputfile = None,
|
|
||||||
modifies = []):
|
|
||||||
"""Defines a rule. Name must be a single word, not a file!"""
|
|
||||||
if not name:
|
|
||||||
t = "#" + str(len(_rules.keys()))
|
|
||||||
else:
|
|
||||||
t = name
|
|
||||||
if t in _rules: Error("target '%s' already exists!" % t)
|
|
||||||
_rules[t] = (_applyPath(prereqs), cmds, outputfile, _applyPath(modifies))
|
|
||||||
if desc:
|
|
||||||
_importantTargets.append((t, desc))
|
|
||||||
|
|
||||||
|
|
||||||
class Changed(object):
|
|
||||||
""" Returns a Changed object. This object evals to true if one of the
|
|
||||||
given files has changed, false otherwise in a boolean context. You have
|
|
||||||
to call the object's success() method if the building has been a success.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
c = Changed("unique_name", "file1.pas file2.pas file3.pas")
|
|
||||||
if c:
|
|
||||||
Exec("fpc file1.pas")
|
|
||||||
# Exec raises an exception if it fails, thus if we get to here, it was
|
|
||||||
# a success:
|
|
||||||
c.success()
|
|
||||||
"""
|
|
||||||
def __init__(self, id, files, explain=False,
|
|
||||||
fingerprintsfile=_FINGERPRINTS_FILE):
|
|
||||||
# load the fingerprints file:
|
|
||||||
# fingerprints is a dict[target, files] where files is a dict[filename, hash]
|
|
||||||
self.fingers = {} # default value
|
|
||||||
if Exists(fingerprintsfile):
|
|
||||||
try:
|
|
||||||
self.fingers = cPickle.load(file(fingerprintsfile))
|
|
||||||
except OSError:
|
|
||||||
Error("Cannot read from " + fingerprintsfile)
|
|
||||||
self.filename = fingerprintsfile
|
|
||||||
self.id = id
|
|
||||||
self.files = files
|
|
||||||
self._hashStr = zlib.adler32 # our hash function
|
|
||||||
self.explain = explain
|
|
||||||
|
|
||||||
def _hashFile(self, f):
|
|
||||||
x = file(f)
|
|
||||||
result = self._hashStr(x.read())
|
|
||||||
x.close() # for other Python implementations
|
|
||||||
return result
|
|
||||||
|
|
||||||
def __nonzero__(self):
|
|
||||||
if type(self.files) == type(""):
|
|
||||||
self.files = self.files.split()
|
|
||||||
result = False
|
|
||||||
target = self.id
|
|
||||||
if not (target in self.fingers):
|
|
||||||
self.fingers[target] = {}
|
|
||||||
if self.explain: _Info("no entries for target '%s'" % target)
|
|
||||||
result = True
|
|
||||||
for d in self.files:
|
|
||||||
if Exists(d):
|
|
||||||
n = self._hashFile(d)
|
|
||||||
if d not in self.fingers[target] or n != self.fingers[target][d]:
|
|
||||||
result = True
|
|
||||||
if self.explain: _Info("'%s' modified since last build" % d)
|
|
||||||
self.fingers[target][d] = n
|
|
||||||
else:
|
|
||||||
Warn("'%s' does not exist!" % d)
|
|
||||||
result = True
|
|
||||||
return result
|
|
||||||
|
|
||||||
def update(self, filename):
|
|
||||||
self.fingers[self.id][filename] = self._hashFile(filename)
|
|
||||||
|
|
||||||
def success(self):
|
|
||||||
cPickle.dump(self.fingers, file(self.filename, "w+"))
|
|
||||||
|
|
||||||
|
|
||||||
class _Koch(object):
|
|
||||||
def _loadFingerprints(self, filename):
|
|
||||||
# fingerprints is a dict[target, files] where files is a dict[filename, hash]
|
|
||||||
if Exists(filename):
|
|
||||||
try:
|
|
||||||
self.fingers = cPickle.load(file(filename))
|
|
||||||
except OSError:
|
|
||||||
Error("Cannot read from " + filename)
|
|
||||||
else:
|
|
||||||
self.fingers = {} # we have no fingerprints :-(
|
|
||||||
|
|
||||||
def _saveFingerprints(self, filename):
|
|
||||||
cPickle.dump(self.fingers, file(filename, "w+"))
|
|
||||||
|
|
||||||
def __init__(self, options):
|
|
||||||
self._loadFingerprints(_FINGERPRINTS_FILE)
|
|
||||||
self.newfingers = {}
|
|
||||||
self.rules = _rules
|
|
||||||
self._hashStr = zlib.adler32 # our hash function
|
|
||||||
self.options = options
|
|
||||||
|
|
||||||
def _doRebuild(self, cmd):
|
|
||||||
if cmd is None: return 0
|
|
||||||
if type(cmd) is StringType:
|
|
||||||
if cmd:
|
|
||||||
c = Path(cmd)
|
|
||||||
_Info(c)
|
|
||||||
return os.system(c)
|
|
||||||
else:
|
|
||||||
return 0
|
|
||||||
elif type(cmd) is FunctionType:
|
|
||||||
return cmd()
|
|
||||||
elif type(cmd) is ListType:
|
|
||||||
for c in cmd:
|
|
||||||
res = self._doRebuild(c)
|
|
||||||
if res != 0: break
|
|
||||||
return res
|
|
||||||
else:
|
|
||||||
Error("invalid rule: command must be a string or a function")
|
|
||||||
|
|
||||||
def _hashFile(self, f):
|
|
||||||
x = file(f)
|
|
||||||
result = self._hashStr(x.read())
|
|
||||||
x.close() # for other Python implementations
|
|
||||||
return result
|
|
||||||
|
|
||||||
def _getDeps(self, target):
|
|
||||||
depslist = self.rules[target][0]
|
|
||||||
if type(depslist) is StringType:
|
|
||||||
result = depslist.split()
|
|
||||||
elif type(depslist) is FunctionType:
|
|
||||||
result = depslist()
|
|
||||||
elif type(depslist) is ListType:
|
|
||||||
result = []
|
|
||||||
for d in depslist:
|
|
||||||
if type(d) is StringType:
|
|
||||||
result.append(d)
|
|
||||||
elif type(d) is FunctionType:
|
|
||||||
result.append(d())
|
|
||||||
else:
|
|
||||||
Error("invalid rule: prereqs must be a string, list, or a function")
|
|
||||||
for i in range(0, len(result)):
|
|
||||||
result[i] = Path(result[i])
|
|
||||||
return result
|
|
||||||
|
|
||||||
def _hasChanged(self, target, d):
|
|
||||||
if not (target in self.newfingers):
|
|
||||||
self.newfingers[target] = {}
|
|
||||||
if Exists(d):
|
|
||||||
n = self._hashFile(d)
|
|
||||||
self.newfingers[target][d] = n
|
|
||||||
if not (target in self.fingers): return True
|
|
||||||
if not (d in self.fingers[target]): return True
|
|
||||||
return n != self.fingers[target][d]
|
|
||||||
else:
|
|
||||||
Warn("'%s' does not exist!" % d)
|
|
||||||
return True
|
|
||||||
|
|
||||||
def _makeAux(self, target, callstack={}):
|
|
||||||
# returns "uptodate", "updated", "failed"
|
|
||||||
UPTODATE = 1
|
|
||||||
UPDATED = 2
|
|
||||||
FAILED = 3
|
|
||||||
|
|
||||||
if target in callstack: return callstack[target]
|
|
||||||
|
|
||||||
def explain(msg):
|
|
||||||
if 'explain' in self.options: _Info(msg)
|
|
||||||
|
|
||||||
if not (target in self.rules): return UPTODATE # target is up to date
|
|
||||||
callstack[target] = UPTODATE # assume uptodate until proven otherwise
|
|
||||||
result = UPTODATE
|
|
||||||
|
|
||||||
# retrieve the dependencies:
|
|
||||||
deps = self._getDeps(target)
|
|
||||||
for d in deps:
|
|
||||||
if d[0] == '#':
|
|
||||||
t = d[1:]
|
|
||||||
if not (t in self.rules):
|
|
||||||
Error("reference to unknown target '%s'" % t)
|
|
||||||
# it is a target!
|
|
||||||
#callstack[t] = # XXX: prevend endless recursion!
|
|
||||||
res = self._makeAux(t, callstack)
|
|
||||||
result = max(result, res)
|
|
||||||
if res == UPDATED:
|
|
||||||
explain("will build '%s' because '%s' modified since last build" %
|
|
||||||
(target, d))
|
|
||||||
elif res == FAILED:
|
|
||||||
explain("cannot build '%s' because '%s' failed" %
|
|
||||||
(target, d))
|
|
||||||
elif self._hasChanged(target, d):
|
|
||||||
explain("will build '%s' because '%s' modified since last build" %
|
|
||||||
(target, d))
|
|
||||||
result = max(result, UPDATED)
|
|
||||||
if self.rules[target][2]: # check if output file exists:
|
|
||||||
if not Exists(self.rules[target][2]):
|
|
||||||
explain("will build '%s' because output file '%s' does not exist" %
|
|
||||||
(target, self.rules[target][2]))
|
|
||||||
result = max(result, UPDATED)
|
|
||||||
|
|
||||||
if result == UPTODATE and 'force' in self.options:
|
|
||||||
explain("will build '%s' because forced" % target)
|
|
||||||
result = max(result, UPDATED)
|
|
||||||
|
|
||||||
if result == UPDATED:
|
|
||||||
_Info("building target '%s'" % target)
|
|
||||||
buildRes = self._doRebuild(self.rules[target][1])
|
|
||||||
if buildRes is None:
|
|
||||||
Error("builder for target '%s' did not return an int" % target)
|
|
||||||
result = FAILED
|
|
||||||
elif buildRes != 0:
|
|
||||||
result = FAILED
|
|
||||||
elif result == UPTODATE:
|
|
||||||
_Info("'%s' is up to date" % target)
|
|
||||||
callstack[target] = result
|
|
||||||
if result == UPDATED: # building was successful, so update fingerprints:
|
|
||||||
if not (target in self.newfingers):
|
|
||||||
# for phony targets this check is needed
|
|
||||||
self.newfingers[target] = {}
|
|
||||||
for m in self.rules[target][3]: # look for changed files
|
|
||||||
self._hasChanged(target, m) # call for its side-effects
|
|
||||||
self.fingers[target] = self.newfingers[target]
|
|
||||||
return result
|
|
||||||
|
|
||||||
def make(self, target):
|
|
||||||
self._makeAux(target)
|
|
||||||
self._saveFingerprints(_FINGERPRINTS_FILE)
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
def SplitArg(s):
|
|
||||||
if ':' in s: c = ':'
|
|
||||||
elif '=' in s: c = '='
|
|
||||||
else: return (s, '')
|
|
||||||
i = s.find(c)
|
|
||||||
return (s[:i], s[i+1:])
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
def _writeUsage():
|
|
||||||
print("Usage: koch.py [options] command/target [command/target...]\n"
|
|
||||||
"Options:\n"
|
|
||||||
" --force, -b, -f forces rebuilding\n"
|
|
||||||
" --help, -h shows this help\n"
|
|
||||||
" --explain, -e explain why a target is built\n"
|
|
||||||
"Available targets:")
|
|
||||||
for t in _importantTargets:
|
|
||||||
print(" " + t[0] + " " * (23-len(t[0])) + t[1])
|
|
||||||
if len(_commands) > 0:
|
|
||||||
print("Available commands:")
|
|
||||||
for k, v in _commands.iteritems():
|
|
||||||
print(" " + k + " " * (23-len(k)) + v[0])
|
|
||||||
sys.exit(2)
|
|
||||||
|
|
||||||
def Koch(defaultTarget):
|
|
||||||
argv = sys.argv[1:]
|
|
||||||
|
|
||||||
options = {}
|
|
||||||
i = 0
|
|
||||||
# process general options:
|
|
||||||
while i < len(argv):
|
|
||||||
if argv[i][0] == '-':
|
|
||||||
if argv[i] in ("-h", "--help"): _writeUsage()
|
|
||||||
elif argv[i] in ("-b", "-B", "--force", "-f"): options['force'] = True
|
|
||||||
elif argv[i] in ("--explain", "-e"): options['explain'] = True
|
|
||||||
else: Error("invalid option: '%s'" % argv[i])
|
|
||||||
else: break # BUGFIX
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
k = _Koch(options)
|
|
||||||
|
|
||||||
# process commands:
|
|
||||||
i = 0
|
|
||||||
while i < len(argv):
|
|
||||||
if argv[i][0] != '-': # process target/command
|
|
||||||
if argv[i] in _rules:
|
|
||||||
k.make(argv[i])
|
|
||||||
elif argv[i] in _commands:
|
|
||||||
cmd = argv[i]
|
|
||||||
n = _commands[cmd][2]
|
|
||||||
args = []
|
|
||||||
if n < 0: upperBound = len(argv)-1
|
|
||||||
else: upperBound = i+n
|
|
||||||
while i+1 <= upperBound:
|
|
||||||
if i+1 >= len(argv):
|
|
||||||
Error("command '%s' expects %d arguments" % (cmd, n))
|
|
||||||
args.append(argv[i+1])
|
|
||||||
i += 1
|
|
||||||
if n < 0: _commands[cmd][1](args)
|
|
||||||
else: _commands[cmd][1](*args)
|
|
||||||
else:
|
|
||||||
Error("Invalid target/command: " + argv[i])
|
|
||||||
|
|
||||||
i += 1
|
|
||||||
if len(argv) == 0:
|
|
||||||
k.make(defaultTarget)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
Error("You should execute the file 'koch.py' or consult\n"
|
|
||||||
"the documentation to see how to build this software.")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -47,7 +47,7 @@ else:
|
||||||
# only Mac OS X has this shit
|
# only Mac OS X has this shit
|
||||||
|
|
||||||
proc c_longjmp(jmpb: C_JmpBuf, retval: cint) {.nodecl, importc: "longjmp".}
|
proc c_longjmp(jmpb: C_JmpBuf, retval: cint) {.nodecl, importc: "longjmp".}
|
||||||
proc c_setjmp(jmpb: var C_JmpBuf) {.nodecl, importc: "setjmp".}
|
proc c_setjmp(jmpb: var C_JmpBuf): cint {.nodecl, importc: "setjmp".}
|
||||||
|
|
||||||
proc c_signal(sig: cint, handler: proc (a: cint) {.noconv.}) {.
|
proc c_signal(sig: cint, handler: proc (a: cint) {.noconv.}) {.
|
||||||
importc: "signal", header: "<signal.h>".}
|
importc: "signal", header: "<signal.h>".}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Nimrod's Runtime Library
|
# Nimrod's Runtime Library
|
||||||
# (c) Copyright 2006 Andreas Rumpf
|
# (c) Copyright 2008 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -10,11 +10,11 @@
|
||||||
|
|
||||||
# simple integer arithmetic with overflow checking
|
# simple integer arithmetic with overflow checking
|
||||||
|
|
||||||
proc raiseOverflow {.exportc: "raiseOverflow".} =
|
proc raiseOverflow {.compilerproc, noinline.} =
|
||||||
# a single proc to reduce code size to a minimum
|
# a single proc to reduce code size to a minimum
|
||||||
raise newException(EOverflow, "over- or underflow")
|
raise newException(EOverflow, "over- or underflow")
|
||||||
|
|
||||||
proc raiseDivByZero {.exportc: "raiseDivByZero".} =
|
proc raiseDivByZero {.exportc: "raiseDivByZero", noinline.} =
|
||||||
raise newException(EDivByZero, "divison by zero")
|
raise newException(EDivByZero, "divison by zero")
|
||||||
|
|
||||||
proc addInt64(a, b: int64): int64 {.compilerProc, inline.} =
|
proc addInt64(a, b: int64): int64 {.compilerProc, inline.} =
|
||||||
|
|
@ -75,9 +75,9 @@ proc mulInt64(a, b: int64): int64 {.compilerproc.} =
|
||||||
var
|
var
|
||||||
resAsFloat, floatProd: float64
|
resAsFloat, floatProd: float64
|
||||||
result = a *% b
|
result = a *% b
|
||||||
floatProd = float64(a) # conversion
|
floatProd = toBiggestFloat(a) # conversion
|
||||||
floatProd = floatProd * float64(b)
|
floatProd = floatProd * toBiggestFloat(b)
|
||||||
resAsFloat = float64(result)
|
resAsFloat = toBiggestFloat(result)
|
||||||
|
|
||||||
# Fast path for normal case: small multiplicands, and no info
|
# Fast path for normal case: small multiplicands, and no info
|
||||||
# is lost in either method.
|
# is lost in either method.
|
||||||
|
|
@ -101,16 +101,14 @@ proc absInt(a: int): int {.compilerProc, inline.} =
|
||||||
else: return -a
|
else: return -a
|
||||||
raiseOverflow()
|
raiseOverflow()
|
||||||
|
|
||||||
when defined(I386) and (defined(vcc) or defined(wcc) or defined(dmc)):
|
const
|
||||||
# or defined(gcc)):
|
asmVersion = defined(I386) and (defined(vcc) or defined(wcc) or defined(dmc))
|
||||||
{.define: asmVersion.}
|
|
||||||
# my Version of Borland C++Builder does not have
|
# my Version of Borland C++Builder does not have
|
||||||
# tasm32, which is needed for assembler blocks
|
# tasm32, which is needed for assembler blocks
|
||||||
# this is why Borland is not included in the 'when'
|
# this is why Borland is not included in the 'when'
|
||||||
else:
|
useInline = not asmVersion
|
||||||
{.define: useInline.}
|
|
||||||
|
|
||||||
when defined(asmVersion) and defined(gcc):
|
when asmVersion and defined(gcc):
|
||||||
proc addInt(a, b: int): int {.compilerProc, pure, inline.}
|
proc addInt(a, b: int): int {.compilerProc, pure, inline.}
|
||||||
proc subInt(a, b: int): int {.compilerProc, pure, inline.}
|
proc subInt(a, b: int): int {.compilerProc, pure, inline.}
|
||||||
proc mulInt(a, b: int): int {.compilerProc, pure, inline.}
|
proc mulInt(a, b: int): int {.compilerProc, pure, inline.}
|
||||||
|
|
@ -118,7 +116,7 @@ when defined(asmVersion) and defined(gcc):
|
||||||
proc modInt(a, b: int): int {.compilerProc, pure, inline.}
|
proc modInt(a, b: int): int {.compilerProc, pure, inline.}
|
||||||
proc negInt(a: int): int {.compilerProc, pure, inline.}
|
proc negInt(a: int): int {.compilerProc, pure, inline.}
|
||||||
|
|
||||||
elif defined(asmVersion):
|
elif asmVersion:
|
||||||
proc addInt(a, b: int): int {.compilerProc, pure.}
|
proc addInt(a, b: int): int {.compilerProc, pure.}
|
||||||
proc subInt(a, b: int): int {.compilerProc, pure.}
|
proc subInt(a, b: int): int {.compilerProc, pure.}
|
||||||
proc mulInt(a, b: int): int {.compilerProc, pure.}
|
proc mulInt(a, b: int): int {.compilerProc, pure.}
|
||||||
|
|
@ -126,7 +124,7 @@ elif defined(asmVersion):
|
||||||
proc modInt(a, b: int): int {.compilerProc, pure.}
|
proc modInt(a, b: int): int {.compilerProc, pure.}
|
||||||
proc negInt(a: int): int {.compilerProc, pure.}
|
proc negInt(a: int): int {.compilerProc, pure.}
|
||||||
|
|
||||||
elif defined(useInline):
|
elif useInline:
|
||||||
proc addInt(a, b: int): int {.compilerProc, inline.}
|
proc addInt(a, b: int): int {.compilerProc, inline.}
|
||||||
proc subInt(a, b: int): int {.compilerProc, inline.}
|
proc subInt(a, b: int): int {.compilerProc, inline.}
|
||||||
proc mulInt(a, b: int): int {.compilerProc.}
|
proc mulInt(a, b: int): int {.compilerProc.}
|
||||||
|
|
@ -145,7 +143,7 @@ else:
|
||||||
|
|
||||||
# implementation:
|
# implementation:
|
||||||
|
|
||||||
when defined(asmVersion) and not defined(gcc):
|
when asmVersion and not defined(gcc):
|
||||||
# assembler optimized versions for compilers that
|
# assembler optimized versions for compilers that
|
||||||
# have an intel syntax assembler:
|
# have an intel syntax assembler:
|
||||||
proc addInt(a, b: int): int =
|
proc addInt(a, b: int): int =
|
||||||
|
|
@ -210,7 +208,7 @@ when defined(asmVersion) and not defined(gcc):
|
||||||
theEnd:
|
theEnd:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
elif defined(asmVersion) and defined(gcc):
|
elif asmVersion and defined(gcc):
|
||||||
proc addInt(a, b: int): int =
|
proc addInt(a, b: int): int =
|
||||||
asm """ "addl %1,%%eax\n"
|
asm """ "addl %1,%%eax\n"
|
||||||
"jno 1\n"
|
"jno 1\n"
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ proc genericAssign(dest, src: Pointer, mt: PNimType) =
|
||||||
of tyString: # a leaf
|
of tyString: # a leaf
|
||||||
var s2 = cast[ppointer](s)^
|
var s2 = cast[ppointer](s)^
|
||||||
if s2 != nil: # nil strings are possible!
|
if s2 != nil: # nil strings are possible!
|
||||||
unsureAsgnRef(cast[ppointer](dest), copyString(cast[mstring](s2)))
|
unsureAsgnRef(cast[ppointer](dest), copyString(cast[NimString](s2)))
|
||||||
else:
|
else:
|
||||||
var x = cast[ppointer](dest)
|
var x = cast[ppointer](dest)
|
||||||
x^ = nil
|
x^ = nil
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ else:
|
||||||
|
|
||||||
type
|
type
|
||||||
PByte = cstring
|
PByte = cstring
|
||||||
cairo_status_t* = enum
|
TCairoStatus* = enum
|
||||||
CAIRO_STATUS_SUCCESS = 0, CAIRO_STATUS_NO_MEMORY,
|
CAIRO_STATUS_SUCCESS = 0, CAIRO_STATUS_NO_MEMORY,
|
||||||
CAIRO_STATUS_INVALID_RESTORE, CAIRO_STATUS_INVALID_POP_GROUP,
|
CAIRO_STATUS_INVALID_RESTORE, CAIRO_STATUS_INVALID_POP_GROUP,
|
||||||
CAIRO_STATUS_NO_CURRENT_POINT, CAIRO_STATUS_INVALID_MATRIX,
|
CAIRO_STATUS_NO_CURRENT_POINT, CAIRO_STATUS_INVALID_MATRIX,
|
||||||
|
|
@ -69,93 +69,93 @@ type
|
||||||
CAIRO_STATUS_PATTERN_TYPE_MISMATCH, CAIRO_STATUS_INVALID_CONTENT,
|
CAIRO_STATUS_PATTERN_TYPE_MISMATCH, CAIRO_STATUS_INVALID_CONTENT,
|
||||||
CAIRO_STATUS_INVALID_FORMAT, CAIRO_STATUS_INVALID_VISUAL,
|
CAIRO_STATUS_INVALID_FORMAT, CAIRO_STATUS_INVALID_VISUAL,
|
||||||
CAIRO_STATUS_FILE_NOT_FOUND, CAIRO_STATUS_INVALID_DASH
|
CAIRO_STATUS_FILE_NOT_FOUND, CAIRO_STATUS_INVALID_DASH
|
||||||
cairo_operator_t* = enum
|
TCairoOperator* = enum
|
||||||
CAIRO_OPERATOR_CLEAR, CAIRO_OPERATOR_SOURCE, CAIRO_OPERATOR_OVER,
|
CAIRO_OPERATOR_CLEAR, CAIRO_OPERATOR_SOURCE, CAIRO_OPERATOR_OVER,
|
||||||
CAIRO_OPERATOR_IN, CAIRO_OPERATOR_OUT, CAIRO_OPERATOR_ATOP,
|
CAIRO_OPERATOR_IN, CAIRO_OPERATOR_OUT, CAIRO_OPERATOR_ATOP,
|
||||||
CAIRO_OPERATOR_DEST, CAIRO_OPERATOR_DEST_OVER, CAIRO_OPERATOR_DEST_IN,
|
CAIRO_OPERATOR_DEST, CAIRO_OPERATOR_DEST_OVER, CAIRO_OPERATOR_DEST_IN,
|
||||||
CAIRO_OPERATOR_DEST_OUT, CAIRO_OPERATOR_DEST_ATOP, CAIRO_OPERATOR_XOR,
|
CAIRO_OPERATOR_DEST_OUT, CAIRO_OPERATOR_DEST_ATOP, CAIRO_OPERATOR_XOR,
|
||||||
CAIRO_OPERATOR_ADD, CAIRO_OPERATOR_SATURATE
|
CAIRO_OPERATOR_ADD, CAIRO_OPERATOR_SATURATE
|
||||||
cairo_antialias_t* = enum
|
TCairoAntialias* = enum
|
||||||
CAIRO_ANTIALIAS_DEFAULT, CAIRO_ANTIALIAS_NONE, CAIRO_ANTIALIAS_GRAY,
|
CAIRO_ANTIALIAS_DEFAULT, CAIRO_ANTIALIAS_NONE, CAIRO_ANTIALIAS_GRAY,
|
||||||
CAIRO_ANTIALIAS_SUBPIXEL
|
CAIRO_ANTIALIAS_SUBPIXEL
|
||||||
cairo_fill_rule_t* = enum
|
TCairoFillRule* = enum
|
||||||
CAIRO_FILL_RULE_WINDING, CAIRO_FILL_RULE_EVEN_ODD
|
CAIRO_FILL_RULE_WINDING, CAIRO_FILL_RULE_EVEN_ODD
|
||||||
cairo_line_cap_t* = enum
|
TCairoLineCap* = enum
|
||||||
CAIRO_LINE_CAP_BUTT, CAIRO_LINE_CAP_ROUND, CAIRO_LINE_CAP_SQUARE
|
CAIRO_LINE_CAP_BUTT, CAIRO_LINE_CAP_ROUND, CAIRO_LINE_CAP_SQUARE
|
||||||
cairo_line_join_t* = enum
|
TCairoLineJoin* = enum
|
||||||
CAIRO_LINE_JOIN_MITER, CAIRO_LINE_JOIN_ROUND, CAIRO_LINE_JOIN_BEVEL
|
CAIRO_LINE_JOIN_MITER, CAIRO_LINE_JOIN_ROUND, CAIRO_LINE_JOIN_BEVEL
|
||||||
cairo_font_slant_t* = enum
|
TCairoFontSlant* = enum
|
||||||
CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_SLANT_ITALIC, CAIRO_FONT_SLANT_OBLIQUE
|
CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_SLANT_ITALIC, CAIRO_FONT_SLANT_OBLIQUE
|
||||||
cairo_font_weight_t* = enum
|
TCairoFontWeight* = enum
|
||||||
CAIRO_FONT_WEIGHT_NORMAL, CAIRO_FONT_WEIGHT_BOLD
|
CAIRO_FONT_WEIGHT_NORMAL, CAIRO_FONT_WEIGHT_BOLD
|
||||||
cairo_subpixel_order_t* = enum
|
TCairoSubpixelOrder* = enum
|
||||||
CAIRO_SUBPIXEL_ORDER_DEFAULT, CAIRO_SUBPIXEL_ORDER_RGB,
|
CAIRO_SUBPIXEL_ORDER_DEFAULT, CAIRO_SUBPIXEL_ORDER_RGB,
|
||||||
CAIRO_SUBPIXEL_ORDER_BGR, CAIRO_SUBPIXEL_ORDER_VRGB,
|
CAIRO_SUBPIXEL_ORDER_BGR, CAIRO_SUBPIXEL_ORDER_VRGB,
|
||||||
CAIRO_SUBPIXEL_ORDER_VBGR
|
CAIRO_SUBPIXEL_ORDER_VBGR
|
||||||
cairo_hint_style_t* = enum
|
TCairoHintStyle* = enum
|
||||||
CAIRO_HINT_STYLE_DEFAULT, CAIRO_HINT_STYLE_NONE, CAIRO_HINT_STYLE_SLIGHT,
|
CAIRO_HINT_STYLE_DEFAULT, CAIRO_HINT_STYLE_NONE, CAIRO_HINT_STYLE_SLIGHT,
|
||||||
CAIRO_HINT_STYLE_MEDIUM, CAIRO_HINT_STYLE_FULL
|
CAIRO_HINT_STYLE_MEDIUM, CAIRO_HINT_STYLE_FULL
|
||||||
cairo_hint_metrics_t* = enum
|
TCairoHintMetrics* = enum
|
||||||
CAIRO_HINT_METRICS_DEFAULT, CAIRO_HINT_METRICS_OFF, CAIRO_HINT_METRICS_ON
|
CAIRO_HINT_METRICS_DEFAULT, CAIRO_HINT_METRICS_OFF, CAIRO_HINT_METRICS_ON
|
||||||
cairo_path_data_type_t* = enum
|
TCairoPathDataType* = enum
|
||||||
CAIRO_PATH_MOVE_TO, CAIRO_PATH_LINE_TO, CAIRO_PATH_CURVE_TO,
|
CAIRO_PATH_MOVE_TO, CAIRO_PATH_LINE_TO, CAIRO_PATH_CURVE_TO,
|
||||||
CAIRO_PATH_CLOSE_PATH
|
CAIRO_PATH_CLOSE_PATH
|
||||||
cairo_content_t* = enum
|
TCairoContent* = enum
|
||||||
CAIRO_CONTENT_COLOR = 0x00001000, CAIRO_CONTENT_ALPHA = 0x00002000,
|
CAIRO_CONTENT_COLOR = 0x00001000, CAIRO_CONTENT_ALPHA = 0x00002000,
|
||||||
CAIRO_CONTENT_COLOR_ALPHA = 0x00003000
|
CAIRO_CONTENT_COLOR_ALPHA = 0x00003000
|
||||||
cairo_format_t* = enum
|
TCairoFormat* = enum
|
||||||
CAIRO_FORMAT_ARGB32, CAIRO_FORMAT_RGB24, CAIRO_FORMAT_A8, CAIRO_FORMAT_A1
|
CAIRO_FORMAT_ARGB32, CAIRO_FORMAT_RGB24, CAIRO_FORMAT_A8, CAIRO_FORMAT_A1
|
||||||
cairo_extend_t* = enum
|
TCairoExtend* = enum
|
||||||
CAIRO_EXTEND_NONE, CAIRO_EXTEND_REPEAT, CAIRO_EXTEND_REFLECT,
|
CAIRO_EXTEND_NONE, CAIRO_EXTEND_REPEAT, CAIRO_EXTEND_REFLECT,
|
||||||
CAIRO_EXTEND_PAD
|
CAIRO_EXTEND_PAD
|
||||||
cairo_filter_t* = enum
|
TCairoFilter* = enum
|
||||||
CAIRO_FILTER_FAST, CAIRO_FILTER_GOOD, CAIRO_FILTER_BEST,
|
CAIRO_FILTER_FAST, CAIRO_FILTER_GOOD, CAIRO_FILTER_BEST,
|
||||||
CAIRO_FILTER_NEAREST, CAIRO_FILTER_BILINEAR, CAIRO_FILTER_GAUSSIAN
|
CAIRO_FILTER_NEAREST, CAIRO_FILTER_BILINEAR, CAIRO_FILTER_GAUSSIAN
|
||||||
cairo_font_type_t* = enum
|
TCairoFontType* = enum
|
||||||
CAIRO_FONT_TYPE_TOY, CAIRO_FONT_TYPE_FT, CAIRO_FONT_TYPE_WIN32,
|
CAIRO_FONT_TYPE_TOY, CAIRO_FONT_TYPE_FT, CAIRO_FONT_TYPE_WIN32,
|
||||||
CAIRO_FONT_TYPE_ATSUI
|
CAIRO_FONT_TYPE_ATSUI
|
||||||
cairo_pattern_type_t* = enum
|
TCairoPatternType* = enum
|
||||||
CAIRO_PATTERN_TYPE_SOLID, CAIRO_PATTERN_TYPE_SURFACE,
|
CAIRO_PATTERN_TYPE_SOLID, CAIRO_PATTERN_TYPE_SURFACE,
|
||||||
CAIRO_PATTERN_TYPE_LINEAR, CAIRO_PATTERN_TYPE_RADIAL
|
CAIRO_PATTERN_TYPE_LINEAR, CAIRO_PATTERN_TYPE_RADIAL
|
||||||
cairo_surface_type_t* = enum
|
TCairoSurfaceType* = enum
|
||||||
CAIRO_SURFACE_TYPE_IMAGE, CAIRO_SURFACE_TYPE_PDF, CAIRO_SURFACE_TYPE_PS,
|
CAIRO_SURFACE_TYPE_IMAGE, CAIRO_SURFACE_TYPE_PDF, CAIRO_SURFACE_TYPE_PS,
|
||||||
CAIRO_SURFACE_TYPE_XLIB, CAIRO_SURFACE_TYPE_XCB, CAIRO_SURFACE_TYPE_GLITZ,
|
CAIRO_SURFACE_TYPE_XLIB, CAIRO_SURFACE_TYPE_XCB, CAIRO_SURFACE_TYPE_GLITZ,
|
||||||
CAIRO_SURFACE_TYPE_QUARTZ, CAIRO_SURFACE_TYPE_WIN32,
|
CAIRO_SURFACE_TYPE_QUARTZ, CAIRO_SURFACE_TYPE_WIN32,
|
||||||
CAIRO_SURFACE_TYPE_BEOS, CAIRO_SURFACE_TYPE_DIRECTFB,
|
CAIRO_SURFACE_TYPE_BEOS, CAIRO_SURFACE_TYPE_DIRECTFB,
|
||||||
CAIRO_SURFACE_TYPE_SVG, CAIRO_SURFACE_TYPE_OS2
|
CAIRO_SURFACE_TYPE_SVG, CAIRO_SURFACE_TYPE_OS2
|
||||||
cairo_svg_version_t* = enum
|
TCairoSvgVersion* = enum
|
||||||
CAIRO_SVG_VERSION_1_1, CAIRO_SVG_VERSION_1_2
|
CAIRO_SVG_VERSION_1_1, CAIRO_SVG_VERSION_1_2
|
||||||
Pcairo_surface_t* = ref cairo_surface_t
|
PCairoSurface* = ptr TCairoSurface
|
||||||
PPcairo_surface_t* = ref Pcairo_surface_t
|
PPCairoSurface* = ptr PCairoSurface
|
||||||
Pcairo_t* = ref cairo_t
|
PCairo* = ptr TCairo
|
||||||
Pcairo_pattern_t* = ref cairo_pattern_t
|
PCairoPattern* = ptr TCairoPattern
|
||||||
Pcairo_font_options_t* = ref cairo_font_options_t
|
PCairoFontOptions* = ptr TCairoFontOptions
|
||||||
Pcairo_font_face_t* = ref cairo_font_face_t
|
PCairoFontFace* = ptr TCairoFontFace
|
||||||
Pcairo_scaled_font_t* = ref cairo_scaled_font_t
|
PCairoScaledFont* = ptr TCairoScaledFont
|
||||||
Pcairo_bool_t* = ref cairo_bool_t
|
PCairoBool* = ptr TCairoBool
|
||||||
cairo_bool_t* = int32
|
TCairoBool* = int32
|
||||||
Pcairo_matrix_t* = ref cairo_matrix_t
|
PCairoMatrix* = ptr TCairoMatrix
|
||||||
Pcairo_user_data_key_t* = ref cairo_user_data_key_t
|
PCairoUserDataKey* = ptr TCairoUserDataKey
|
||||||
Pcairo_glyph_t* = ref cairo_glyph_t
|
PCairoGlyph* = ptr TCairoGlyph
|
||||||
Pcairo_text_extents_t* = ref cairo_text_extents_t
|
PCairoTextExtents* = ptr TCairoTextExtents
|
||||||
Pcairo_font_extents_t* = ref cairo_font_extents_t
|
PCairoFontExtents* = ptr TCairoFontExtents
|
||||||
Pcairo_path_data_type_t* = ref cairo_path_data_type_t
|
PCairoPathDataType* = ptr TCairoPathDataType
|
||||||
Pcairo_path_data_t* = ref cairo_path_data_t
|
PCairoPathData* = ptr TCairoPathData
|
||||||
Pcairo_path_t* = ref cairo_path_t
|
PCairoPath* = ptr TCairoPath
|
||||||
Pcairo_rectangle_t* = ref cairo_rectangle_t
|
PCairoRectangle* = ptr TCairoRectangle
|
||||||
Pcairo_rectangle_list_t* = ref cairo_rectangle_list_t
|
PCairoRectangleList* = ptr TCairoRectangleList
|
||||||
cairo_destroy_func_t* = proc (data: Pointer){.cdecl.}
|
TCairoDestroyFunc* = proc (data: Pointer){.cdecl.}
|
||||||
cairo_write_func_t* = proc (closure: Pointer, data: PByte, len: int32): cairo_status_t{.
|
TCairoWriteFunc* = proc (closure: Pointer, data: PByte, len: int32): TCairoStatus{.
|
||||||
cdecl.}
|
cdecl.}
|
||||||
cairo_read_func_t* = proc (closure: Pointer, data: PByte, len: int32): cairo_status_t{.
|
TCairoReadFunc* = proc (closure: Pointer, data: PByte, len: int32): TCairoStatus{.
|
||||||
cdecl.}
|
cdecl.}
|
||||||
cairo_t* {.final.} = object #OPAQUE
|
TCairo* {.final.} = object #OPAQUE
|
||||||
cairo_surface_t* {.final.} = object #OPAQUE
|
TCairoSurface* {.final.} = object #OPAQUE
|
||||||
cairo_pattern_t* {.final.} = object #OPAQUE
|
TCairoPattern* {.final.} = object #OPAQUE
|
||||||
cairo_scaled_font_t* {.final.} = object #OPAQUE
|
TCairoScaledFont* {.final.} = object #OPAQUE
|
||||||
cairo_font_face_t* {.final.} = object #OPAQUE
|
TCairoFontFace* {.final.} = object #OPAQUE
|
||||||
cairo_font_options_t* {.final.} = object #OPAQUE
|
TCairoFontOptions* {.final.} = object #OPAQUE
|
||||||
cairo_matrix_t* {.final.} = object
|
TCairoMatrix* {.final.} = object
|
||||||
xx: float64
|
xx: float64
|
||||||
yx: float64
|
yx: float64
|
||||||
xy: float64
|
xy: float64
|
||||||
|
|
@ -163,15 +163,15 @@ type
|
||||||
x0: float64
|
x0: float64
|
||||||
y0: float64
|
y0: float64
|
||||||
|
|
||||||
cairo_user_data_key_t* {.final.} = object
|
TCairoUserDataKey* {.final.} = object
|
||||||
unused: int32
|
unused: int32
|
||||||
|
|
||||||
cairo_glyph_t* {.final.} = object
|
TCairoGlyph* {.final.} = object
|
||||||
index: int32
|
index: int32
|
||||||
x: float64
|
x: float64
|
||||||
y: float64
|
y: float64
|
||||||
|
|
||||||
cairo_text_extents_t* {.final.} = object
|
TCairoTextExtents* {.final.} = object
|
||||||
x_bearing: float64
|
x_bearing: float64
|
||||||
y_bearing: float64
|
y_bearing: float64
|
||||||
width: float64
|
width: float64
|
||||||
|
|
@ -179,30 +179,30 @@ type
|
||||||
x_advance: float64
|
x_advance: float64
|
||||||
y_advance: float64
|
y_advance: float64
|
||||||
|
|
||||||
cairo_font_extents_t* {.final.} = object
|
TCairoFontExtents* {.final.} = object
|
||||||
ascent: float64
|
ascent: float64
|
||||||
descent: float64
|
descent: float64
|
||||||
height: float64
|
height: float64
|
||||||
max_x_advance: float64
|
max_x_advance: float64
|
||||||
max_y_advance: float64
|
max_y_advance: float64
|
||||||
|
|
||||||
cairo_path_data_t* {.final.} = object #* _type : cairo_path_data_type_t;
|
TCairoPathData* {.final.} = object #* _type : TCairoPathDataType;
|
||||||
# length : LongInt;
|
# length : LongInt;
|
||||||
# end
|
# end
|
||||||
x: float64
|
x: float64
|
||||||
y: float64
|
y: float64
|
||||||
|
|
||||||
cairo_path_t* {.final.} = object
|
TCairoPath* {.final.} = object
|
||||||
status: cairo_status_t
|
status: TCairoStatus
|
||||||
data: Pcairo_path_data_t
|
data: PCairoPathData
|
||||||
num_data: int32
|
num_data: int32
|
||||||
|
|
||||||
cairo_rectangle_t* {.final.} = object
|
TCairoRectangle* {.final.} = object
|
||||||
x, y, width, height: float64
|
x, y, width, height: float64
|
||||||
|
|
||||||
cairo_rectangle_list_t* {.final.} = object
|
TCairoRectangleList* {.final.} = object
|
||||||
status: cairo_status_t
|
status: TCairoStatus
|
||||||
rectangles: Pcairo_rectangle_t
|
rectangles: PCairoRectangle
|
||||||
num_rectangles: int32
|
num_rectangles: int32
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -211,480 +211,480 @@ proc cairo_version_string*(): cstring{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
#Helper function to retrieve decoded version
|
#Helper function to retrieve decoded version
|
||||||
proc cairo_version*(major, minor, micro: var int32)
|
proc cairo_version*(major, minor, micro: var int32)
|
||||||
#* Functions for manipulating state objects
|
#* Functions for manipulating state objects
|
||||||
proc cairo_create*(target: Pcairo_surface_t): Pcairo_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_create*(target: PCairoSurface): PCairo{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_reference*(cr: Pcairo_t): Pcairo_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_reference*(cr: PCairo): PCairo{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_destroy*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_destroy*(cr: PCairo){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_get_reference_count*(cr: Pcairo_t): int32{.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_get_reference_count*(cr: PCairo): int32{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_get_user_data*(cr: Pcairo_t, key: Pcairo_user_data_key_t): pointer{.
|
proc cairo_get_user_data*(cr: PCairo, key: PCairoUserDataKey): pointer{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_set_user_data*(cr: PCairo_t, key: Pcairo_user_data_key_t,
|
proc cairo_set_user_data*(cr: PCairo, key: PCairoUserDataKey,
|
||||||
user_data: Pointer, destroy: cairo_destroy_func_t): cairo_status_t{.
|
user_data: Pointer, destroy: TCairoDestroyFunc): TCairoStatus{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_save*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_save*(cr: PCairo){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_restore*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_restore*(cr: PCairo){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_push_group*(cr: PCairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_push_group*(cr: PCairo){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_push_group_with_content*(cr: PCairo_t, content: cairo_content_t){.
|
proc cairo_push_group_with_content*(cr: PCairo, content: TCairoContent){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pop_group*(cr: PCairo_t): Pcairo_pattern_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_pop_group*(cr: PCairo): PCairoPattern{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pop_group_to_source*(cr: PCairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_pop_group_to_source*(cr: PCairo){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
#* Modify state
|
#* Modify state
|
||||||
proc cairo_set_operator*(cr: Pcairo_t, op: cairo_operator_t){.cdecl, importc,
|
proc cairo_set_operator*(cr: PCairo, op: TCairoOperator){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_set_source*(cr: Pcairo_t, source: Pcairo_pattern_t){.cdecl, importc,
|
proc cairo_set_source*(cr: PCairo, source: PCairoPattern){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_set_source_rgb*(cr: Pcairo_t, red, green, blue: float64){.cdecl, importc,
|
proc cairo_set_source_rgb*(cr: PCairo, red, green, blue: float64){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_set_source_rgba*(cr: Pcairo_t, red, green, blue, alpha: float64){.
|
proc cairo_set_source_rgba*(cr: PCairo, red, green, blue, alpha: float64){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_set_source_surface*(cr: Pcairo_t, surface: Pcairo_surface_t,
|
proc cairo_set_source_surface*(cr: PCairo, surface: PCairoSurface,
|
||||||
x, y: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
x, y: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_set_tolerance*(cr: Pcairo_t, tolerance: float64){.cdecl, importc,
|
proc cairo_set_tolerance*(cr: PCairo, tolerance: float64){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_set_antialias*(cr: Pcairo_t, antialias: cairo_antialias_t){.cdecl, importc,
|
proc cairo_set_antialias*(cr: PCairo, antialias: TCairoAntialias){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_set_fill_rule*(cr: Pcairo_t, fill_rule: cairo_fill_rule_t){.cdecl, importc,
|
proc cairo_set_fill_rule*(cr: PCairo, fill_rule: TCairoFillRule){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_set_line_width*(cr: Pcairo_t, width: float64){.cdecl, importc,
|
proc cairo_set_line_width*(cr: PCairo, width: float64){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_set_line_cap*(cr: Pcairo_t, line_cap: cairo_line_cap_t){.cdecl, importc,
|
proc cairo_set_line_cap*(cr: PCairo, line_cap: TCairoLineCap){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_set_line_join*(cr: Pcairo_t, line_join: cairo_line_join_t){.cdecl, importc,
|
proc cairo_set_line_join*(cr: PCairo, line_join: TCairoLineJoin){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_set_dash*(cr: Pcairo_t, dashes: openarray[float64],
|
proc cairo_set_dash*(cr: PCairo, dashes: openarray[float64],
|
||||||
offset: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
offset: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_set_miter_limit*(cr: Pcairo_t, limit: float64){.cdecl, importc,
|
proc cairo_set_miter_limit*(cr: PCairo, limit: float64){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_translate*(cr: Pcairo_t, tx, ty: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_translate*(cr: PCairo, tx, ty: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_scale*(cr: Pcairo_t, sx, sy: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_scale*(cr: PCairo, sx, sy: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_rotate*(cr: Pcairo_t, angle: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_rotate*(cr: PCairo, angle: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_transform*(cr: Pcairo_t, matrix: Pcairo_matrix_t){.cdecl, importc,
|
proc cairo_transform*(cr: PCairo, matrix: PCairoMatrix){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_set_matrix*(cr: Pcairo_t, matrix: Pcairo_matrix_t){.cdecl, importc,
|
proc cairo_set_matrix*(cr: PCairo, matrix: PCairoMatrix){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_identity_matrix*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_identity_matrix*(cr: PCairo){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_user_to_device*(cr: Pcairo_t, x, y: var float64){.cdecl, importc,
|
proc cairo_user_to_device*(cr: PCairo, x, y: var float64){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_user_to_device_distance*(cr: Pcairo_t, dx, dy: var float64){.cdecl, importc,
|
proc cairo_user_to_device_distance*(cr: PCairo, dx, dy: var float64){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_device_to_user*(cr: Pcairo_t, x, y: var float64){.cdecl, importc,
|
proc cairo_device_to_user*(cr: PCairo, x, y: var float64){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_device_to_user_distance*(cr: Pcairo_t, dx, dy: var float64){.cdecl, importc,
|
proc cairo_device_to_user_distance*(cr: PCairo, dx, dy: var float64){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
#* Path creation functions
|
#* Path creation functions
|
||||||
proc cairo_new_path*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_new_path*(cr: PCairo){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_move_to*(cr: Pcairo_t, x, y: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_move_to*(cr: PCairo, x, y: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_new_sub_path*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_new_sub_path*(cr: PCairo){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_line_to*(cr: Pcairo_t, x, y: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_line_to*(cr: PCairo, x, y: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_curve_to*(cr: Pcairo_t, x1, y1, x2, y2, x3, y3: float64){.cdecl, importc,
|
proc cairo_curve_to*(cr: PCairo, x1, y1, x2, y2, x3, y3: float64){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_arc*(cr: Pcairo_t, xc, yc, radius, angle1, angle2: float64){.cdecl, importc,
|
proc cairo_arc*(cr: PCairo, xc, yc, radius, angle1, angle2: float64){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_arc_negative*(cr: Pcairo_t, xc, yc, radius, angle1, angle2: float64){.
|
proc cairo_arc_negative*(cr: PCairo, xc, yc, radius, angle1, angle2: float64){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_rel_move_to*(cr: Pcairo_t, dx, dy: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_rel_move_to*(cr: PCairo, dx, dy: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_rel_line_to*(cr: Pcairo_t, dx, dy: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_rel_line_to*(cr: PCairo, dx, dy: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_rel_curve_to*(cr: Pcairo_t, dx1, dy1, dx2, dy2, dx3, dy3: float64){.
|
proc cairo_rel_curve_to*(cr: PCairo, dx1, dy1, dx2, dy2, dx3, dy3: float64){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_rectangle*(cr: Pcairo_t, x, y, width, height: float64){.cdecl, importc,
|
proc cairo_rectangle*(cr: PCairo, x, y, width, height: float64){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_close_path*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_close_path*(cr: PCairo){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
#* Painting functions
|
#* Painting functions
|
||||||
proc cairo_paint*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_paint*(cr: PCairo){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_paint_with_alpha*(cr: Pcairo_t, alpha: float64){.cdecl, importc,
|
proc cairo_paint_with_alpha*(cr: PCairo, alpha: float64){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_mask*(cr: Pcairo_t, pattern: Pcairo_pattern_t){.cdecl, importc,
|
proc cairo_mask*(cr: PCairo, pattern: PCairoPattern){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_mask_surface*(cr: Pcairo_t, surface: Pcairo_surface_t,
|
proc cairo_mask_surface*(cr: PCairo, surface: PCairoSurface,
|
||||||
surface_x, surface_y: float64){.cdecl, importc,
|
surface_x, surface_y: float64){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_stroke*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_stroke*(cr: PCairo){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_stroke_preserve*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_stroke_preserve*(cr: PCairo){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_fill*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_fill*(cr: PCairo){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_fill_preserve*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_fill_preserve*(cr: PCairo){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_copy_page*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_copy_page*(cr: PCairo){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_show_page*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_show_page*(cr: PCairo){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
#* Insideness testing
|
#* Insideness testing
|
||||||
proc cairo_in_stroke*(cr: Pcairo_t, x, y: float64): cairo_bool_t{.cdecl, importc,
|
proc cairo_in_stroke*(cr: PCairo, x, y: float64): TCairoBool{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_in_fill*(cr: Pcairo_t, x, y: float64): cairo_bool_t{.cdecl, importc,
|
proc cairo_in_fill*(cr: PCairo, x, y: float64): TCairoBool{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
#* Rectangular extents
|
#* Rectangular extents
|
||||||
proc cairo_stroke_extents*(cr: Pcairo_t, x1, y1, x2, y2: var float64){.cdecl, importc,
|
proc cairo_stroke_extents*(cr: PCairo, x1, y1, x2, y2: var float64){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_fill_extents*(cr: Pcairo_t, x1, y1, x2, y2: var float64){.cdecl, importc,
|
proc cairo_fill_extents*(cr: PCairo, x1, y1, x2, y2: var float64){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
#* Clipping
|
#* Clipping
|
||||||
proc cairo_reset_clip*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_reset_clip*(cr: PCairo){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_clip*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_clip*(cr: PCairo){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_clip_preserve*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_clip_preserve*(cr: PCairo){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_clip_extents*(cr: Pcairo_t, x1, y1, x2, y2: var float64){.cdecl, importc,
|
proc cairo_clip_extents*(cr: PCairo, x1, y1, x2, y2: var float64){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_copy_clip_rectangle_list*(cr: Pcairo_t): Pcairo_rectangle_list_t{.
|
proc cairo_copy_clip_rectangle_list*(cr: PCairo): PCairoRectangleList{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_rectangle_list_destroy*(rectangle_list: Pcairo_rectangle_list_t){.
|
proc cairo_rectangle_list_destroy*(rectangle_list: PCairoRectangleList){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
#* Font/Text functions
|
#* Font/Text functions
|
||||||
proc cairo_font_options_create*(): Pcairo_font_options_t{.cdecl, importc,
|
proc cairo_font_options_create*(): PCairoFontOptions{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_font_options_copy*(original: Pcairo_font_options_t): Pcairo_font_options_t{.
|
proc cairo_font_options_copy*(original: PCairoFontOptions): PCairoFontOptions{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_font_options_destroy*(options: Pcairo_font_options_t){.cdecl, importc,
|
proc cairo_font_options_destroy*(options: PCairoFontOptions){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_font_options_status*(options: Pcairo_font_options_t): cairo_status_t{.
|
proc cairo_font_options_status*(options: PCairoFontOptions): TCairoStatus{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_font_options_merge*(options, other: Pcairo_font_options_t){.cdecl, importc,
|
proc cairo_font_options_merge*(options, other: PCairoFontOptions){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_font_options_equal*(options, other: Pcairo_font_options_t): cairo_bool_t{.
|
proc cairo_font_options_equal*(options, other: PCairoFontOptions): TCairoBool{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_font_options_hash*(options: Pcairo_font_options_t): int32{.cdecl, importc,
|
proc cairo_font_options_hash*(options: PCairoFontOptions): int32{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_font_options_set_antialias*(options: Pcairo_font_options_t,
|
proc cairo_font_options_set_antialias*(options: PCairoFontOptions,
|
||||||
antialias: cairo_antialias_t){.cdecl, importc,
|
antialias: TCairoAntialias){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_font_options_get_antialias*(options: Pcairo_font_options_t): cairo_antialias_t{.
|
proc cairo_font_options_get_antialias*(options: PCairoFontOptions): TCairoAntialias{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_font_options_set_subpixel_order*(options: Pcairo_font_options_t,
|
proc cairo_font_options_set_subpixel_order*(options: PCairoFontOptions,
|
||||||
subpixel_order: cairo_subpixel_order_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
subpixel_order: TCairoSubpixelOrder){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_font_options_get_subpixel_order*(options: Pcairo_font_options_t): cairo_subpixel_order_t{.
|
proc cairo_font_options_get_subpixel_order*(options: PCairoFontOptions): TCairoSubpixelOrder{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_font_options_set_hint_style*(options: Pcairo_font_options_t,
|
proc cairo_font_options_set_hint_style*(options: PCairoFontOptions,
|
||||||
hint_style: cairo_hint_style_t){.cdecl, importc,
|
hint_style: TCairoHintStyle){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_font_options_get_hint_style*(options: Pcairo_font_options_t): cairo_hint_style_t{.
|
proc cairo_font_options_get_hint_style*(options: PCairoFontOptions): TCairoHintStyle{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_font_options_set_hint_metrics*(options: Pcairo_font_options_t,
|
proc cairo_font_options_set_hint_metrics*(options: PCairoFontOptions,
|
||||||
hint_metrics: cairo_hint_metrics_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
hint_metrics: TCairoHintMetrics){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_font_options_get_hint_metrics*(options: Pcairo_font_options_t): cairo_hint_metrics_t{.
|
proc cairo_font_options_get_hint_metrics*(options: PCairoFontOptions): TCairoHintMetrics{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
#* This interface is for dealing with text as text, not caring about the
|
#* This interface is for dealing with text as text, not caring about the
|
||||||
# font object inside the the cairo_t.
|
# font object inside the the TCairo.
|
||||||
proc cairo_select_font_face*(cr: Pcairo_t, family: cstring,
|
proc cairo_select_font_face*(cr: PCairo, family: cstring,
|
||||||
slant: cairo_font_slant_t,
|
slant: TCairoFontSlant,
|
||||||
weight: cairo_font_weight_t){.cdecl, importc,
|
weight: TCairoFontWeight){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_set_font_size*(cr: Pcairo_t, size: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_set_font_size*(cr: PCairo, size: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_set_font_matrix*(cr: Pcairo_t, matrix: Pcairo_matrix_t){.cdecl, importc,
|
proc cairo_set_font_matrix*(cr: PCairo, matrix: PCairoMatrix){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_get_font_matrix*(cr: Pcairo_t, matrix: Pcairo_matrix_t){.cdecl, importc,
|
proc cairo_get_font_matrix*(cr: PCairo, matrix: PCairoMatrix){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_set_font_options*(cr: Pcairo_t, options: Pcairo_font_options_t){.
|
proc cairo_set_font_options*(cr: PCairo, options: PCairoFontOptions){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_get_font_options*(cr: Pcairo_t, options: Pcairo_font_options_t){.
|
proc cairo_get_font_options*(cr: PCairo, options: PCairoFontOptions){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_set_font_face*(cr: Pcairo_t, font_face: Pcairo_font_face_t){.cdecl, importc,
|
proc cairo_set_font_face*(cr: PCairo, font_face: PCairoFontFace){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_get_font_face*(cr: Pcairo_t): Pcairo_font_face_t{.cdecl, importc,
|
proc cairo_get_font_face*(cr: PCairo): PCairoFontFace{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_set_scaled_font*(cr: PCairo_t, scaled_font: Pcairo_scaled_font_t){.
|
proc cairo_set_scaled_font*(cr: PCairo, scaled_font: PCairoScaledFont){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_get_scaled_font*(cr: Pcairo_t): Pcairo_scaled_font_t{.cdecl, importc,
|
proc cairo_get_scaled_font*(cr: PCairo): PCairoScaledFont{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_show_text*(cr: Pcairo_t, utf8: cstring){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_show_text*(cr: PCairo, utf8: cstring){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_show_glyphs*(cr: Pcairo_t, glyphs: Pcairo_glyph_t, num_glyphs: int32){.
|
proc cairo_show_glyphs*(cr: PCairo, glyphs: PCairoGlyph, num_glyphs: int32){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_text_path*(cr: Pcairo_t, utf8: cstring){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_text_path*(cr: PCairo, utf8: cstring){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_glyph_path*(cr: Pcairo_t, glyphs: Pcairo_glyph_t, num_glyphs: int32){.
|
proc cairo_glyph_path*(cr: PCairo, glyphs: PCairoGlyph, num_glyphs: int32){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_text_extents*(cr: Pcairo_t, utf8: cstring,
|
proc cairo_text_extents*(cr: PCairo, utf8: cstring,
|
||||||
extents: Pcairo_text_extents_t){.cdecl, importc,
|
extents: PCairoTextExtents){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_glyph_extents*(cr: Pcairo_t, glyphs: Pcairo_glyph_t,
|
proc cairo_glyph_extents*(cr: PCairo, glyphs: PCairoGlyph,
|
||||||
num_glyphs: int32, extents: Pcairo_text_extents_t){.
|
num_glyphs: int32, extents: PCairoTextExtents){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_font_extents*(cr: Pcairo_t, extents: Pcairo_font_extents_t){.cdecl, importc,
|
proc cairo_font_extents*(cr: PCairo, extents: PCairoFontExtents){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
#* Generic identifier for a font style
|
#* Generic identifier for a font style
|
||||||
proc cairo_font_face_reference*(font_face: Pcairo_font_face_t): Pcairo_font_face_t{.
|
proc cairo_font_face_reference*(font_face: PCairoFontFace): PCairoFontFace{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_font_face_destroy*(font_face: Pcairo_font_face_t){.cdecl, importc,
|
proc cairo_font_face_destroy*(font_face: PCairoFontFace){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_font_face_get_reference_count*(font_face: Pcairo_font_face_t): int32{.
|
proc cairo_font_face_get_reference_count*(font_face: PCairoFontFace): int32{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_font_face_status*(font_face: Pcairo_font_face_t): cairo_status_t{.
|
proc cairo_font_face_status*(font_face: PCairoFontFace): TCairoStatus{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_font_face_get_type*(font_face: Pcairo_font_face_t): cairo_font_type_t{.
|
proc cairo_font_face_get_type*(font_face: PCairoFontFace): TCairoFontType{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_font_face_get_user_data*(font_face: Pcairo_font_face_t,
|
proc cairo_font_face_get_user_data*(font_face: PCairoFontFace,
|
||||||
key: Pcairo_user_data_key_t): pointer{.
|
key: PCairoUserDataKey): pointer{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_font_face_set_user_data*(font_face: Pcairo_font_face_t,
|
proc cairo_font_face_set_user_data*(font_face: PCairoFontFace,
|
||||||
key: Pcairo_user_data_key_t,
|
key: PCairoUserDataKey,
|
||||||
user_data: pointer,
|
user_data: pointer,
|
||||||
destroy: cairo_destroy_func_t): cairo_status_t{.
|
destroy: TCairoDestroyFunc): TCairoStatus{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
#* Portable interface to general font features
|
#* Portable interface to general font features
|
||||||
proc cairo_scaled_font_create*(font_face: Pcairo_font_face_t,
|
proc cairo_scaled_font_create*(font_face: PCairoFontFace,
|
||||||
font_matrix: Pcairo_matrix_t,
|
font_matrix: PCairoMatrix,
|
||||||
ctm: Pcairo_matrix_t,
|
ctm: PCairoMatrix,
|
||||||
options: Pcairo_font_options_t): Pcairo_scaled_font_t{.
|
options: PCairoFontOptions): PCairoScaledFont{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_scaled_font_reference*(scaled_font: Pcairo_scaled_font_t): Pcairo_scaled_font_t{.
|
proc cairo_scaled_font_reference*(scaled_font: PCairoScaledFont): PCairoScaledFont{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_scaled_font_destroy*(scaled_font: Pcairo_scaled_font_t){.cdecl, importc,
|
proc cairo_scaled_font_destroy*(scaled_font: PCairoScaledFont){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_scaled_font_get_reference_count*(scaled_font: Pcairo_scaled_font_t): int32{.
|
proc cairo_scaled_font_get_reference_count*(scaled_font: PCairoScaledFont): int32{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_scaled_font_status*(scaled_font: Pcairo_scaled_font_t): cairo_status_t{.
|
proc cairo_scaled_font_status*(scaled_font: PCairoScaledFont): TCairoStatus{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_scaled_font_get_type*(scaled_font: Pcairo_scaled_font_t): cairo_font_type_t{.
|
proc cairo_scaled_font_get_type*(scaled_font: PCairoScaledFont): TCairoFontType{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_scaled_font_get_user_data*(scaled_font: Pcairo_scaled_font_t,
|
proc cairo_scaled_font_get_user_data*(scaled_font: PCairoScaledFont,
|
||||||
key: Pcairo_user_data_key_t): Pointer{.
|
key: PCairoUserDataKey): Pointer{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_scaled_font_set_user_data*(scaled_font: Pcairo_scaled_font_t,
|
proc cairo_scaled_font_set_user_data*(scaled_font: PCairoScaledFont,
|
||||||
key: Pcairo_user_data_key_t,
|
key: PCairoUserDataKey,
|
||||||
user_data: Pointer,
|
user_data: Pointer,
|
||||||
destroy: cairo_destroy_func_t): cairo_status_t{.
|
destroy: TCairoDestroyFunc): TCairoStatus{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_scaled_font_extents*(scaled_font: Pcairo_scaled_font_t,
|
proc cairo_scaled_font_extents*(scaled_font: PCairoScaledFont,
|
||||||
extents: Pcairo_font_extents_t){.cdecl, importc,
|
extents: PCairoFontExtents){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_scaled_font_text_extents*(scaled_font: Pcairo_scaled_font_t,
|
proc cairo_scaled_font_text_extents*(scaled_font: PCairoScaledFont,
|
||||||
utf8: cstring,
|
utf8: cstring,
|
||||||
extents: Pcairo_text_extents_t){.cdecl, importc,
|
extents: PCairoTextExtents){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_scaled_font_glyph_extents*(scaled_font: Pcairo_scaled_font_t,
|
proc cairo_scaled_font_glyph_extents*(scaled_font: PCairoScaledFont,
|
||||||
glyphs: Pcairo_glyph_t, num_glyphs: int32,
|
glyphs: PCairoGlyph, num_glyphs: int32,
|
||||||
extents: Pcairo_text_extents_t){.cdecl, importc,
|
extents: PCairoTextExtents){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_scaled_font_get_font_face*(scaled_font: Pcairo_scaled_font_t): Pcairo_font_face_t{.
|
proc cairo_scaled_font_get_font_face*(scaled_font: PCairoScaledFont): PCairoFontFace{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_scaled_font_get_font_matrix*(scaled_font: Pcairo_scaled_font_t,
|
proc cairo_scaled_font_get_font_matrix*(scaled_font: PCairoScaledFont,
|
||||||
font_matrix: Pcairo_matrix_t){.cdecl, importc,
|
font_matrix: PCairoMatrix){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_scaled_font_get_ctm*(scaled_font: Pcairo_scaled_font_t,
|
proc cairo_scaled_font_get_ctm*(scaled_font: PCairoScaledFont,
|
||||||
ctm: Pcairo_matrix_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
ctm: PCairoMatrix){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_scaled_font_get_font_options*(scaled_font: Pcairo_scaled_font_t,
|
proc cairo_scaled_font_get_font_options*(scaled_font: PCairoScaledFont,
|
||||||
options: Pcairo_font_options_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
options: PCairoFontOptions){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
#* Query functions
|
#* Query functions
|
||||||
proc cairo_get_operator*(cr: Pcairo_t): cairo_operator_t{.cdecl, importc,
|
proc cairo_get_operator*(cr: PCairo): TCairoOperator{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_get_source*(cr: Pcairo_t): Pcairo_pattern_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_get_source*(cr: PCairo): PCairoPattern{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_get_tolerance*(cr: Pcairo_t): float64{.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_get_tolerance*(cr: PCairo): float64{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_get_antialias*(cr: Pcairo_t): cairo_antialias_t{.cdecl, importc,
|
proc cairo_get_antialias*(cr: PCairo): TCairoAntialias{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_get_current_point*(cr: Pcairo_t, x, y: var float64){.cdecl, importc,
|
proc cairo_get_current_point*(cr: PCairo, x, y: var float64){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_get_fill_rule*(cr: Pcairo_t): cairo_fill_rule_t{.cdecl, importc,
|
proc cairo_get_fill_rule*(cr: PCairo): TCairoFillRule{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_get_line_width*(cr: Pcairo_t): float64{.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_get_line_width*(cr: PCairo): float64{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_get_line_cap*(cr: Pcairo_t): cairo_line_cap_t{.cdecl, importc,
|
proc cairo_get_line_cap*(cr: PCairo): TCairoLineCap{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_get_line_join*(cr: Pcairo_t): cairo_line_join_t{.cdecl, importc,
|
proc cairo_get_line_join*(cr: PCairo): TCairoLineJoin{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_get_miter_limit*(cr: Pcairo_t): float64{.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_get_miter_limit*(cr: PCairo): float64{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_get_dash_count*(cr: Pcairo_t): int32{.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_get_dash_count*(cr: PCairo): int32{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_get_dash*(cr: Pcairo_t, dashes, offset: var float64){.cdecl, importc,
|
proc cairo_get_dash*(cr: PCairo, dashes, offset: var float64){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_get_matrix*(cr: Pcairo_t, matrix: Pcairo_matrix_t){.cdecl, importc,
|
proc cairo_get_matrix*(cr: PCairo, matrix: PCairoMatrix){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_get_target*(cr: Pcairo_t): Pcairo_surface_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_get_target*(cr: PCairo): PCairoSurface{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_get_group_target*(cr: Pcairo_t): Pcairo_surface_t{.cdecl, importc,
|
proc cairo_get_group_target*(cr: PCairo): PCairoSurface{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_copy_path*(cr: Pcairo_t): Pcairo_path_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_copy_path*(cr: PCairo): PCairoPath{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_copy_path_flat*(cr: Pcairo_t): Pcairo_path_t{.cdecl, importc,
|
proc cairo_copy_path_flat*(cr: PCairo): PCairoPath{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_append_path*(cr: Pcairo_t, path: Pcairo_path_t){.cdecl, importc,
|
proc cairo_append_path*(cr: PCairo, path: PCairoPath){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_path_destroy*(path: Pcairo_path_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_path_destroy*(path: PCairoPath){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
#* Error status queries
|
#* Error status queries
|
||||||
proc cairo_status*(cr: Pcairo_t): cairo_status_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_status*(cr: PCairo): TCairoStatus{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_status_to_string*(status: cairo_status_t): cstring{.cdecl, importc,
|
proc cairo_status_to_string*(status: TCairoStatus): cstring{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
#* Surface manipulation
|
#* Surface manipulation
|
||||||
proc cairo_surface_create_similar*(other: Pcairo_surface_t,
|
proc cairo_surface_create_similar*(other: PCairoSurface,
|
||||||
content: cairo_content_t,
|
content: TCairoContent,
|
||||||
width, height: int32): Pcairo_surface_t{.
|
width, height: int32): PCairoSurface{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_surface_reference*(surface: Pcairo_surface_t): Pcairo_surface_t{.
|
proc cairo_surface_reference*(surface: PCairoSurface): PCairoSurface{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_surface_finish*(surface: Pcairo_surface_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_surface_finish*(surface: PCairoSurface){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_surface_destroy*(surface: Pcairo_surface_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_surface_destroy*(surface: PCairoSurface){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_surface_get_reference_count*(surface: Pcairo_surface_t): int32{.
|
proc cairo_surface_get_reference_count*(surface: PCairoSurface): int32{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_surface_status*(surface: Pcairo_surface_t): cairo_status_t{.cdecl, importc,
|
proc cairo_surface_status*(surface: PCairoSurface): TCairoStatus{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_surface_get_type*(surface: Pcairo_surface_t): cairo_surface_type_t{.
|
proc cairo_surface_get_type*(surface: PCairoSurface): TCairoSurfaceType{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_surface_get_content*(surface: Pcairo_surface_t): cairo_content_t{.
|
proc cairo_surface_get_content*(surface: PCairoSurface): TCairoContent{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_surface_write_to_png*(surface: Pcairo_surface_t, filename: cstring): cairo_status_t{.
|
proc cairo_surface_write_to_png*(surface: PCairoSurface, filename: cstring): TCairoStatus{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_surface_write_to_png_stream*(surface: Pcairo_surface_t,
|
proc cairo_surface_write_to_png_stream*(surface: PCairoSurface,
|
||||||
write_func: cairo_write_func_t,
|
write_func: TCairoWriteFunc,
|
||||||
closure: pointer): cairo_status_t{.
|
closure: pointer): TCairoStatus{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_surface_get_user_data*(surface: Pcairo_surface_t,
|
proc cairo_surface_get_user_data*(surface: PCairoSurface,
|
||||||
key: Pcairo_user_data_key_t): pointer{.cdecl, importc,
|
key: PCairoUserDataKey): pointer{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_surface_set_user_data*(surface: Pcairo_surface_t,
|
proc cairo_surface_set_user_data*(surface: PCairoSurface,
|
||||||
key: Pcairo_user_data_key_t,
|
key: PCairoUserDataKey,
|
||||||
user_data: pointer,
|
user_data: pointer,
|
||||||
destroy: cairo_destroy_func_t): cairo_status_t{.
|
destroy: TCairoDestroyFunc): TCairoStatus{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_surface_get_font_options*(surface: Pcairo_surface_t,
|
proc cairo_surface_get_font_options*(surface: PCairoSurface,
|
||||||
options: Pcairo_font_options_t){.cdecl, importc,
|
options: PCairoFontOptions){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_surface_flush*(surface: Pcairo_surface_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_surface_flush*(surface: PCairoSurface){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_surface_mark_dirty*(surface: Pcairo_surface_t){.cdecl, importc,
|
proc cairo_surface_mark_dirty*(surface: PCairoSurface){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_surface_mark_dirty_rectangle*(surface: Pcairo_surface_t,
|
proc cairo_surface_mark_dirty_rectangle*(surface: PCairoSurface,
|
||||||
x, y, width, height: int32){.cdecl, importc, dynlib: LIB_CAIRO.}
|
x, y, width, height: int32){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_surface_set_device_offset*(surface: Pcairo_surface_t,
|
proc cairo_surface_set_device_offset*(surface: PCairoSurface,
|
||||||
x_offset, y_offset: float64){.cdecl, importc,
|
x_offset, y_offset: float64){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_surface_get_device_offset*(surface: Pcairo_surface_t,
|
proc cairo_surface_get_device_offset*(surface: PCairoSurface,
|
||||||
x_offset, y_offset: var float64){.cdecl, importc,
|
x_offset, y_offset: var float64){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_surface_set_fallback_resolution*(surface: Pcairo_surface_t,
|
proc cairo_surface_set_fallback_resolution*(surface: PCairoSurface,
|
||||||
x_pixels_per_inch, y_pixels_per_inch: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
x_pixels_per_inch, y_pixels_per_inch: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
#* Image-surface functions
|
#* Image-surface functions
|
||||||
proc cairo_image_surface_create*(format: cairo_format_t, width, height: int32): Pcairo_surface_t{.
|
proc cairo_image_surface_create*(format: TCairoFormat, width, height: int32): PCairoSurface{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_image_surface_create_for_data*(data: Pbyte, format: cairo_format_t,
|
proc cairo_image_surface_create_for_data*(data: Pbyte, format: TCairoFormat,
|
||||||
width, height, stride: int32): Pcairo_surface_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
width, height, stride: int32): PCairoSurface{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_image_surface_get_data*(surface: Pcairo_surface_t): cstring{.cdecl, importc,
|
proc cairo_image_surface_get_data*(surface: PCairoSurface): cstring{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_image_surface_get_format*(surface: Pcairo_surface_t): cairo_format_t{.
|
proc cairo_image_surface_get_format*(surface: PCairoSurface): TCairoFormat{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_image_surface_get_width*(surface: Pcairo_surface_t): int32{.cdecl, importc,
|
proc cairo_image_surface_get_width*(surface: PCairoSurface): int32{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_image_surface_get_height*(surface: Pcairo_surface_t): int32{.cdecl, importc,
|
proc cairo_image_surface_get_height*(surface: PCairoSurface): int32{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_image_surface_get_stride*(surface: Pcairo_surface_t): int32{.cdecl, importc,
|
proc cairo_image_surface_get_stride*(surface: PCairoSurface): int32{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_image_surface_create_from_png*(filename: cstring): Pcairo_surface_t{.
|
proc cairo_image_surface_create_from_png*(filename: cstring): PCairoSurface{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_image_surface_create_from_png_stream*(read_func: cairo_read_func_t,
|
proc cairo_image_surface_create_from_png_stream*(read_func: TCairoReadFunc,
|
||||||
closure: pointer): Pcairo_surface_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
closure: pointer): PCairoSurface{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
#* Pattern creation functions
|
#* Pattern creation functions
|
||||||
proc cairo_pattern_create_rgb*(red, green, blue: float64): Pcairo_pattern_t{.
|
proc cairo_pattern_create_rgb*(red, green, blue: float64): PCairoPattern{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pattern_create_rgba*(red, green, blue, alpha: float64): Pcairo_pattern_t{.
|
proc cairo_pattern_create_rgba*(red, green, blue, alpha: float64): PCairoPattern{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pattern_create_for_surface*(surface: Pcairo_surface_t): Pcairo_pattern_t{.
|
proc cairo_pattern_create_for_surface*(surface: PCairoSurface): PCairoPattern{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pattern_create_linear*(x0, y0, x1, y1: float64): Pcairo_pattern_t{.
|
proc cairo_pattern_create_linear*(x0, y0, x1, y1: float64): PCairoPattern{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pattern_create_radial*(cx0, cy0, radius0, cx1, cy1, radius1: float64): Pcairo_pattern_t{.
|
proc cairo_pattern_create_radial*(cx0, cy0, radius0, cx1, cy1, radius1: float64): PCairoPattern{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pattern_reference*(pattern: Pcairo_pattern_t): Pcairo_pattern_t{.
|
proc cairo_pattern_reference*(pattern: PCairoPattern): PCairoPattern{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pattern_destroy*(pattern: Pcairo_pattern_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_pattern_destroy*(pattern: PCairoPattern){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pattern_get_reference_count*(pattern: Pcairo_pattern_t): int32{.
|
proc cairo_pattern_get_reference_count*(pattern: PCairoPattern): int32{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pattern_status*(pattern: Pcairo_pattern_t): cairo_status_t{.cdecl, importc,
|
proc cairo_pattern_status*(pattern: PCairoPattern): TCairoStatus{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pattern_get_user_data*(pattern: Pcairo_pattern_t,
|
proc cairo_pattern_get_user_data*(pattern: PCairoPattern,
|
||||||
key: Pcairo_user_data_key_t): Pointer{.cdecl, importc,
|
key: PCairoUserDataKey): Pointer{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pattern_set_user_data*(pattern: Pcairo_pattern_t,
|
proc cairo_pattern_set_user_data*(pattern: PCairoPattern,
|
||||||
key: Pcairo_user_data_key_t,
|
key: PCairoUserDataKey,
|
||||||
user_data: Pointer,
|
user_data: Pointer,
|
||||||
destroy: cairo_destroy_func_t): cairo_status_t{.
|
destroy: TCairoDestroyFunc): TCairoStatus{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pattern_get_type*(pattern: Pcairo_pattern_t): cairo_pattern_type_t{.
|
proc cairo_pattern_get_type*(pattern: PCairoPattern): TCairoPatternType{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pattern_add_color_stop_rgb*(pattern: Pcairo_pattern_t,
|
proc cairo_pattern_add_color_stop_rgb*(pattern: PCairoPattern,
|
||||||
offset, red, green, blue: float64){.
|
offset, red, green, blue: float64){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pattern_add_color_stop_rgba*(pattern: Pcairo_pattern_t, offset, red,
|
proc cairo_pattern_add_color_stop_rgba*(pattern: PCairoPattern, offset, red,
|
||||||
green, blue, alpha: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
green, blue, alpha: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pattern_set_matrix*(pattern: Pcairo_pattern_t,
|
proc cairo_pattern_set_matrix*(pattern: PCairoPattern,
|
||||||
matrix: Pcairo_matrix_t){.cdecl, importc,
|
matrix: PCairoMatrix){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pattern_get_matrix*(pattern: Pcairo_pattern_t,
|
proc cairo_pattern_get_matrix*(pattern: PCairoPattern,
|
||||||
matrix: Pcairo_matrix_t){.cdecl, importc,
|
matrix: PCairoMatrix){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pattern_set_extend*(pattern: Pcairo_pattern_t, extend: cairo_extend_t){.
|
proc cairo_pattern_set_extend*(pattern: PCairoPattern, extend: TCairoExtend){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pattern_get_extend*(pattern: Pcairo_pattern_t): cairo_extend_t{.
|
proc cairo_pattern_get_extend*(pattern: PCairoPattern): TCairoExtend{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pattern_set_filter*(pattern: Pcairo_pattern_t, filter: cairo_filter_t){.
|
proc cairo_pattern_set_filter*(pattern: PCairoPattern, filter: TCairoFilter){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pattern_get_filter*(pattern: Pcairo_pattern_t): cairo_filter_t{.
|
proc cairo_pattern_get_filter*(pattern: PCairoPattern): TCairoFilter{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pattern_get_rgba*(pattern: Pcairo_pattern_t,
|
proc cairo_pattern_get_rgba*(pattern: PCairoPattern,
|
||||||
red, green, blue, alpha: var float64): cairo_status_t{.
|
red, green, blue, alpha: var float64): TCairoStatus{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pattern_get_surface*(pattern: Pcairo_pattern_t,
|
proc cairo_pattern_get_surface*(pattern: PCairoPattern,
|
||||||
surface: PPcairo_surface_t): cairo_status_t{.
|
surface: PPCairoSurface): TCairoStatus{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pattern_get_color_stop_rgba*(pattern: Pcairo_pattern_t, index: int32,
|
proc cairo_pattern_get_color_stop_rgba*(pattern: PCairoPattern, index: int32,
|
||||||
offset, red, green, blue, alpha: var float64): cairo_status_t{.cdecl, importc,
|
offset, red, green, blue, alpha: var float64): TCairoStatus{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pattern_get_color_stop_count*(pattern: Pcairo_pattern_t,
|
proc cairo_pattern_get_color_stop_count*(pattern: PCairoPattern,
|
||||||
count: var int32): cairo_status_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
count: var int32): TCairoStatus{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pattern_get_linear_points*(pattern: Pcairo_pattern_t,
|
proc cairo_pattern_get_linear_points*(pattern: PCairoPattern,
|
||||||
x0, y0, x1, y1: var float64): cairo_status_t{.
|
x0, y0, x1, y1: var float64): TCairoStatus{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pattern_get_radial_circles*(pattern: Pcairo_pattern_t,
|
proc cairo_pattern_get_radial_circles*(pattern: PCairoPattern,
|
||||||
x0, y0, r0, x1, y1, r1: var float64): cairo_status_t{.
|
x0, y0, r0, x1, y1, r1: var float64): TCairoStatus{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
#* Matrix functions
|
#* Matrix functions
|
||||||
proc cairo_matrix_init*(matrix: Pcairo_matrix_t, xx, yx, xy, yy, x0, y0: float64){.
|
proc cairo_matrix_init*(matrix: PCairoMatrix, xx, yx, xy, yy, x0, y0: float64){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_matrix_init_identity*(matrix: Pcairo_matrix_t){.cdecl, importc,
|
proc cairo_matrix_init_identity*(matrix: PCairoMatrix){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_matrix_init_translate*(matrix: Pcairo_matrix_t, tx, ty: float64){.
|
proc cairo_matrix_init_translate*(matrix: PCairoMatrix, tx, ty: float64){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_matrix_init_scale*(matrix: Pcairo_matrix_t, sx, sy: float64){.cdecl, importc,
|
proc cairo_matrix_init_scale*(matrix: PCairoMatrix, sx, sy: float64){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_matrix_init_rotate*(matrix: Pcairo_matrix_t, radians: float64){.
|
proc cairo_matrix_init_rotate*(matrix: PCairoMatrix, radians: float64){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_matrix_translate*(matrix: Pcairo_matrix_t, tx, ty: float64){.cdecl, importc,
|
proc cairo_matrix_translate*(matrix: PCairoMatrix, tx, ty: float64){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_matrix_scale*(matrix: Pcairo_matrix_t, sx, sy: float64){.cdecl, importc,
|
proc cairo_matrix_scale*(matrix: PCairoMatrix, sx, sy: float64){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_matrix_rotate*(matrix: Pcairo_matrix_t, radians: float64){.cdecl, importc,
|
proc cairo_matrix_rotate*(matrix: PCairoMatrix, radians: float64){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_matrix_invert*(matrix: Pcairo_matrix_t): cairo_status_t{.cdecl, importc,
|
proc cairo_matrix_invert*(matrix: PCairoMatrix): TCairoStatus{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_matrix_multiply*(result, a, b: Pcairo_matrix_t){.cdecl, importc,
|
proc cairo_matrix_multiply*(result, a, b: PCairoMatrix){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_matrix_transform_distance*(matrix: Pcairo_matrix_t, dx, dy: var float64){.
|
proc cairo_matrix_transform_distance*(matrix: PCairoMatrix, dx, dy: var float64){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_matrix_transform_point*(matrix: Pcairo_matrix_t, x, y: var float64){.
|
proc cairo_matrix_transform_point*(matrix: PCairoMatrix, x, y: var float64){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
#* PDF functions
|
#* PDF functions
|
||||||
proc cairo_pdf_surface_create*(filename: cstring,
|
proc cairo_pdf_surface_create*(filename: cstring,
|
||||||
width_in_points, height_in_points: float64): Pcairo_surface_t{.
|
width_in_points, height_in_points: float64): PCairoSurface{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pdf_surface_create_for_stream*(write_func: cairo_write_func_t,
|
proc cairo_pdf_surface_create_for_stream*(write_func: TCairoWriteFunc,
|
||||||
closure: Pointer, width_in_points, height_in_points: float64): Pcairo_surface_t{.
|
closure: Pointer, width_in_points, height_in_points: float64): PCairoSurface{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_pdf_surface_set_size*(surface: Pcairo_surface_t,
|
proc cairo_pdf_surface_set_size*(surface: PCairoSurface,
|
||||||
width_in_points, height_in_points: float64){.
|
width_in_points, height_in_points: float64){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
#* PS functions
|
#* PS functions
|
||||||
proc cairo_ps_surface_create*(filename: cstring,
|
proc cairo_ps_surface_create*(filename: cstring,
|
||||||
width_in_points, height_in_points: float64): Pcairo_surface_t{.
|
width_in_points, height_in_points: float64): PCairoSurface{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_ps_surface_create_for_stream*(write_func: cairo_write_func_t,
|
proc cairo_ps_surface_create_for_stream*(write_func: TCairoWriteFunc,
|
||||||
closure: Pointer, width_in_points, height_in_points: float64): Pcairo_surface_t{.
|
closure: Pointer, width_in_points, height_in_points: float64): PCairoSurface{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_ps_surface_set_size*(surface: Pcairo_surface_t,
|
proc cairo_ps_surface_set_size*(surface: PCairoSurface,
|
||||||
width_in_points, height_in_points: float64){.
|
width_in_points, height_in_points: float64){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_ps_surface_dsc_comment*(surface: Pcairo_surface_t, comment: cstring){.
|
proc cairo_ps_surface_dsc_comment*(surface: PCairoSurface, comment: cstring){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_ps_surface_dsc_begin_setup*(surface: Pcairo_surface_t){.cdecl, importc,
|
proc cairo_ps_surface_dsc_begin_setup*(surface: PCairoSurface){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_ps_surface_dsc_begin_page_setup*(surface: Pcairo_surface_t){.cdecl, importc,
|
proc cairo_ps_surface_dsc_begin_page_setup*(surface: PCairoSurface){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
#* SVG functions
|
#* SVG functions
|
||||||
proc cairo_svg_surface_create*(filename: cstring,
|
proc cairo_svg_surface_create*(filename: cstring,
|
||||||
width_in_points, height_in_points: float64): Pcairo_surface_t{.
|
width_in_points, height_in_points: float64): PCairoSurface{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_svg_surface_create_for_stream*(write_func: cairo_write_func_t,
|
proc cairo_svg_surface_create_for_stream*(write_func: TCairoWriteFunc,
|
||||||
closure: Pointer, width_in_points, height_in_points: float64): Pcairo_surface_t{.
|
closure: Pointer, width_in_points, height_in_points: float64): PCairoSurface{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_svg_surface_restrict_to_version*(surface: Pcairo_surface_t,
|
proc cairo_svg_surface_restrict_to_version*(surface: PCairoSurface,
|
||||||
version: cairo_svg_version_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
version: TCairoSvgVersion){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
#todo: see how translate this
|
#todo: see how translate this
|
||||||
#procedure cairo_svg_get_versions(cairo_svg_version_t const **versions,
|
#procedure cairo_svg_get_versions(TCairoSvgVersion const **versions,
|
||||||
# int *num_versions);
|
# int *num_versions);
|
||||||
proc cairo_svg_version_to_string*(version: cairo_svg_version_t): cstring{.cdecl, importc,
|
proc cairo_svg_version_to_string*(version: TCairoSvgVersion): cstring{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
#* Functions to be used while debugging (not intended for use in production code)
|
#* Functions to be used while debugging (not intended for use in production code)
|
||||||
proc cairo_debug_reset_static_data*(){.cdecl, importc, dynlib: LIB_CAIRO.}
|
proc cairo_debug_reset_static_data*(){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
|
|
@ -693,6 +693,6 @@ proc cairo_debug_reset_static_data*(){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_version(major, minor, micro: var int32) =
|
proc cairo_version(major, minor, micro: var int32) =
|
||||||
var version: int32
|
var version: int32
|
||||||
version = cairo_version()
|
version = cairo_version()
|
||||||
major = version div 10000
|
major = version div 10000'i32
|
||||||
minor = (version mod (major * 10000)) div 100
|
minor = (version mod (major * 10000'i32)) div 100'i32
|
||||||
micro = (version mod ((major * 10000) + (minor * 100)))
|
micro = (version mod ((major * 10000'i32) + (minor * 100'i32)))
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
# updated to version 1.4 by Luiz Américo Pereira Câmara 2007
|
# updated to version 1.4 by Luiz Américo Pereira Câmara 2007
|
||||||
#
|
#
|
||||||
|
|
||||||
import Cairo, freetypeh
|
import cairo, freetypeh
|
||||||
|
|
||||||
#todo: properly define FcPattern:
|
#todo: properly define FcPattern:
|
||||||
#It will require translate FontConfig header
|
#It will require translate FontConfig header
|
||||||
|
|
@ -20,17 +20,17 @@ import Cairo, freetypeh
|
||||||
|
|
||||||
type
|
type
|
||||||
FcPattern* = Pointer
|
FcPattern* = Pointer
|
||||||
PFcPattern* = ref FcPattern
|
PFcPattern* = ptr FcPattern
|
||||||
|
|
||||||
proc cairo_ft_font_face_create_for_pattern*(pattern: PFcPattern): Pcairo_font_face_t{.
|
proc cairo_ft_font_face_create_for_pattern*(pattern: PFcPattern): PCairoFontFace{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_ft_font_options_substitute*(options: Pcairo_font_options_t,
|
proc cairo_ft_font_options_substitute*(options: PCairoFontOptions,
|
||||||
pattern: PFcPattern){.cdecl, importc,
|
pattern: PFcPattern){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_ft_font_face_create_for_ft_face*(face: TFT_Face,
|
proc cairo_ft_font_face_create_for_ft_face*(face: TFT_Face,
|
||||||
load_flags: int32): Pcairo_font_face_t {.cdecl, importc, dynlib: LIB_CAIRO.}
|
load_flags: int32): PCairoFontFace {.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_ft_scaled_font_lock_face*(
|
proc cairo_ft_scaled_font_lock_face*(
|
||||||
scaled_font: Pcairo_scaled_font_t): TFT_Face{.cdecl, importc, dynlib: LIB_CAIRO.}
|
scaled_font: PCairoScaledFont): TFT_Face{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_ft_scaled_font_unlock_face*(
|
proc cairo_ft_scaled_font_unlock_face*(
|
||||||
scaled_font: Pcairo_scaled_font_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
scaled_font: PCairoScaledFont){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,30 +7,30 @@
|
||||||
import
|
import
|
||||||
Cairo, windows
|
Cairo, windows
|
||||||
|
|
||||||
proc cairo_win32_surface_create*(hdc: HDC): Pcairo_surface_t{.cdecl, importc,
|
proc cairo_win32_surface_create*(hdc: HDC): PCairoSurface{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_win32_surface_create_with_ddb*(hdc: HDC, format: cairo_format_t,
|
proc cairo_win32_surface_create_with_ddb*(hdc: HDC, format: TCairoFormat,
|
||||||
width, height: int32): Pcairo_surface_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
width, height: int32): PCairoSurface{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_win32_surface_create_with_dib*(format: cairo_format_t,
|
proc cairo_win32_surface_create_with_dib*(format: TCairoFormat,
|
||||||
width, height: int32): Pcairo_surface_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
width, height: int32): PCairoSurface{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_win32_surface_get_dc*(surface: pcairo_surface_t): HDC{.cdecl, importc,
|
proc cairo_win32_surface_get_dc*(surface: PCairoSurface): HDC{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_win32_surface_get_image*(surface: pcairo_surface_t): Pcairo_surface_t{.
|
proc cairo_win32_surface_get_image*(surface: PCairoSurface): PCairoSurface{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_win32_font_face_create_for_logfontw*(logfont: pLOGFONTW): Pcairo_font_face_t{.
|
proc cairo_win32_font_face_create_for_logfontw*(logfont: pLOGFONTW): PCairoFontFace{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_win32_font_face_create_for_hfont*(font: HFONT): Pcairo_font_face_t{.
|
proc cairo_win32_font_face_create_for_hfont*(font: HFONT): PCairoFontFace{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_win32_scaled_font_select_font*(scaled_font: pcairo_scaled_font_t,
|
proc cairo_win32_scaled_font_select_font*(scaled_font: PCairoScaledFont,
|
||||||
hdc: HDC): cairo_status_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
hdc: HDC): TCairoStatus{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_win32_scaled_font_done_font*(scaled_font: pcairo_scaled_font_t){.
|
proc cairo_win32_scaled_font_done_font*(scaled_font: PCairoScaledFont){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_win32_scaled_font_get_metrics_factor*(
|
proc cairo_win32_scaled_font_get_metrics_factor*(
|
||||||
scaled_font: pcairo_scaled_font_t): float64{.cdecl, importc, dynlib: LIB_CAIRO.}
|
scaled_font: PCairoScaledFont): float64{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_win32_scaled_font_get_logical_to_device*(
|
proc cairo_win32_scaled_font_get_logical_to_device*(
|
||||||
scaled_font: pcairo_scaled_font_t, logical_to_device: pcairo_matrix_t){.
|
scaled_font: PCairoScaledFont, logical_to_device: PCairoMatrix){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_win32_scaled_font_get_device_to_logical*(
|
proc cairo_win32_scaled_font_get_device_to_logical*(
|
||||||
scaled_font: pcairo_scaled_font_t, device_to_logical: pcairo_matrix_t){.
|
scaled_font: PCairoScaledFont, device_to_logical: PCairoMatrix){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
# implementation
|
# implementation
|
||||||
|
|
|
||||||
|
|
@ -9,32 +9,32 @@ import
|
||||||
Cairo, x, xlib, xrender
|
Cairo, x, xlib, xrender
|
||||||
|
|
||||||
proc cairo_xlib_surface_create*(dpy: PDisplay, drawable: TDrawable,
|
proc cairo_xlib_surface_create*(dpy: PDisplay, drawable: TDrawable,
|
||||||
visual: PVisual, width, height: int32): Pcairo_surface_t{.
|
visual: PVisual, width, height: int32): PCairoSurface{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_xlib_surface_create_for_bitmap*(dpy: PDisplay, bitmap: TPixmap,
|
proc cairo_xlib_surface_create_for_bitmap*(dpy: PDisplay, bitmap: TPixmap,
|
||||||
screen: PScreen, width, height: int32): Pcairo_surface_t{.cdecl, importc,
|
screen: PScreen, width, height: int32): PCairoSurface{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_xlib_surface_create_with_xrender_format*(dpy: PDisplay,
|
proc cairo_xlib_surface_create_with_xrender_format*(dpy: PDisplay,
|
||||||
drawable: TDrawable, screen: PScreen, format: PXRenderPictFormat,
|
drawable: TDrawable, screen: PScreen, format: PXRenderPictFormat,
|
||||||
width, height: int32): Pcairo_surface_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
width, height: int32): PCairoSurface{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_xlib_surface_get_depth*(surface: Pcairo_surface_t): int32{.cdecl, importc,
|
proc cairo_xlib_surface_get_depth*(surface: PCairoSurface): int32{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_xlib_surface_get_display*(surface: Pcairo_surface_t): PDisplay{.
|
proc cairo_xlib_surface_get_display*(surface: PCairoSurface): PDisplay{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_xlib_surface_get_drawable*(surface: Pcairo_surface_t): TDrawable{.
|
proc cairo_xlib_surface_get_drawable*(surface: PCairoSurface): TDrawable{.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
proc cairo_xlib_surface_get_height*(surface: Pcairo_surface_t): int32{.cdecl, importc,
|
proc cairo_xlib_surface_get_height*(surface: PCairoSurface): int32{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_xlib_surface_get_screen*(surface: Pcairo_surface_t): PScreen{.cdecl, importc,
|
proc cairo_xlib_surface_get_screen*(surface: PCairoSurface): PScreen{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_xlib_surface_get_visual*(surface: Pcairo_surface_t): PVisual{.cdecl, importc,
|
proc cairo_xlib_surface_get_visual*(surface: PCairoSurface): PVisual{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_xlib_surface_get_width*(surface: Pcairo_surface_t): int32{.cdecl, importc,
|
proc cairo_xlib_surface_get_width*(surface: PCairoSurface): int32{.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_xlib_surface_set_size*(surface: Pcairo_surface_t,
|
proc cairo_xlib_surface_set_size*(surface: PCairoSurface,
|
||||||
width, height: int32){.cdecl, importc,
|
width, height: int32){.cdecl, importc,
|
||||||
dynlib: LIB_CAIRO.}
|
dynlib: LIB_CAIRO.}
|
||||||
proc cairo_xlib_surface_set_drawable*(surface: Pcairo_surface_t,
|
proc cairo_xlib_surface_set_drawable*(surface: PCairoSurface,
|
||||||
drawable: TDrawable, width, height: int32){.
|
drawable: TDrawable, width, height: int32){.
|
||||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||||
# implementation
|
# implementation
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ proc ChooseFileToOpen*(window: PWindow, root: string = ""): string =
|
||||||
GTK_STOCK_OPEN, GTK_RESPONSE_OK, nil))
|
GTK_STOCK_OPEN, GTK_RESPONSE_OK, nil))
|
||||||
if root.len > 0:
|
if root.len > 0:
|
||||||
discard gtk_file_chooser_set_current_folder(chooser, root)
|
discard gtk_file_chooser_set_current_folder(chooser, root)
|
||||||
if gtk_dialog_run(chooser) == GTK_RESPONSE_OK:
|
if gtk_dialog_run(chooser) == cint(GTK_RESPONSE_OK):
|
||||||
var x = gtk_file_chooser_get_filename(chooser)
|
var x = gtk_file_chooser_get_filename(chooser)
|
||||||
result = $x
|
result = $x
|
||||||
g_free(x)
|
g_free(x)
|
||||||
|
|
@ -99,7 +99,7 @@ proc ChooseFileToOpen*(window: PWindow, root: string = ""): string =
|
||||||
gtk_widget_destroy(chooser)
|
gtk_widget_destroy(chooser)
|
||||||
|
|
||||||
proc ChooseFilesToOpen*(window: PWindow, root: string = ""): seq[string] =
|
proc ChooseFilesToOpen*(window: PWindow, root: string = ""): seq[string] =
|
||||||
## Opens a dialog that requests filenames from the user. Returns []
|
## Opens a dialog that requests filenames from the user. Returns ``@[]``
|
||||||
## if the user closed the dialog without selecting a file. On Windows,
|
## if the user closed the dialog without selecting a file. On Windows,
|
||||||
## the native dialog is used, else the GTK dialog is used.
|
## the native dialog is used, else the GTK dialog is used.
|
||||||
when defined(Windows):
|
when defined(Windows):
|
||||||
|
|
@ -114,7 +114,7 @@ proc ChooseFilesToOpen*(window: PWindow, root: string = ""): seq[string] =
|
||||||
opf.lpstrFile = buf
|
opf.lpstrFile = buf
|
||||||
opf.nMaxFile = sizeof(buf)
|
opf.nMaxFile = sizeof(buf)
|
||||||
var res = GetOpenFileName(addr(opf))
|
var res = GetOpenFileName(addr(opf))
|
||||||
result = []
|
result = @[]
|
||||||
if res != 0:
|
if res != 0:
|
||||||
# parsing the result is horrible:
|
# parsing the result is horrible:
|
||||||
var
|
var
|
||||||
|
|
@ -145,8 +145,8 @@ proc ChooseFilesToOpen*(window: PWindow, root: string = ""): seq[string] =
|
||||||
if root.len > 0:
|
if root.len > 0:
|
||||||
discard gtk_file_chooser_set_current_folder(chooser, root)
|
discard gtk_file_chooser_set_current_folder(chooser, root)
|
||||||
gtk_file_chooser_set_select_multiple(chooser, true)
|
gtk_file_chooser_set_select_multiple(chooser, true)
|
||||||
result = []
|
result = @[]
|
||||||
if gtk_dialog_run(chooser) == GTK_RESPONSE_OK:
|
if gtk_dialog_run(chooser) == cint(GTK_RESPONSE_OK):
|
||||||
var L = gtk_file_chooser_get_filenames(chooser)
|
var L = gtk_file_chooser_get_filenames(chooser)
|
||||||
var it = L
|
var it = L
|
||||||
while it != nil:
|
while it != nil:
|
||||||
|
|
@ -187,7 +187,7 @@ proc ChooseFileToSave*(window: PWindow, root: string = ""): string =
|
||||||
if root.len > 0:
|
if root.len > 0:
|
||||||
discard gtk_file_chooser_set_current_folder(chooser, root)
|
discard gtk_file_chooser_set_current_folder(chooser, root)
|
||||||
gtk_file_chooser_set_do_overwrite_confirmation(chooser, true)
|
gtk_file_chooser_set_do_overwrite_confirmation(chooser, true)
|
||||||
if gtk_dialog_run(chooser) == GTK_RESPONSE_OK:
|
if gtk_dialog_run(chooser) == cint(GTK_RESPONSE_OK):
|
||||||
var x = gtk_file_chooser_get_filename(chooser)
|
var x = gtk_file_chooser_get_filename(chooser)
|
||||||
result = $x
|
result = $x
|
||||||
g_free(x)
|
g_free(x)
|
||||||
|
|
@ -224,7 +224,7 @@ proc ChooseDir*(window: PWindow, root: string = ""): string =
|
||||||
GTK_STOCK_OPEN, GTK_RESPONSE_OK, nil))
|
GTK_STOCK_OPEN, GTK_RESPONSE_OK, nil))
|
||||||
if root.len > 0:
|
if root.len > 0:
|
||||||
discard gtk_file_chooser_set_current_folder(chooser, root)
|
discard gtk_file_chooser_set_current_folder(chooser, root)
|
||||||
if gtk_dialog_run(chooser) == GTK_RESPONSE_OK:
|
if gtk_dialog_run(chooser) == cint(GTK_RESPONSE_OK):
|
||||||
var x = gtk_file_chooser_get_filename(chooser)
|
var x = gtk_file_chooser_get_filename(chooser)
|
||||||
result = $x
|
result = $x
|
||||||
g_free(x)
|
g_free(x)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import
|
||||||
glib2
|
glib2
|
||||||
|
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
{.define: atkwin.}
|
|
||||||
const
|
const
|
||||||
atklib = "libatk-1.0-0.dll"
|
atklib = "libatk-1.0-0.dll"
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import
|
||||||
glib2, gdk2pixbuf, pango
|
glib2, gdk2pixbuf, pango
|
||||||
|
|
||||||
when defined(win32):
|
when defined(win32):
|
||||||
{.define: GDK_WINDOWING_WIN32.}
|
|
||||||
const
|
const
|
||||||
gdklib = "libgdk-win32-2.0-0.dll"
|
gdklib = "libgdk-win32-2.0-0.dll"
|
||||||
GDK_HAVE_WCHAR_H = 1
|
GDK_HAVE_WCHAR_H = 1
|
||||||
|
|
@ -3183,14 +3182,14 @@ proc GDK_IS_WINDOW_CLASS*(klass: Pointer): bool
|
||||||
proc GDK_WINDOW_GET_CLASS*(obj: Pointer): PGdkWindowObjectClass
|
proc GDK_WINDOW_GET_CLASS*(obj: Pointer): PGdkWindowObjectClass
|
||||||
proc GDK_WINDOW_OBJECT*(anObject: Pointer): PGdkWindowObject
|
proc GDK_WINDOW_OBJECT*(anObject: Pointer): PGdkWindowObject
|
||||||
const
|
const
|
||||||
bm_TGdkWindowObject_guffaw_gravity* = 0x00000001
|
bm_TGdkWindowObject_guffaw_gravity* = 0x00000001'i16
|
||||||
bp_TGdkWindowObject_guffaw_gravity* = 0
|
bp_TGdkWindowObject_guffaw_gravity* = 0'i16
|
||||||
bm_TGdkWindowObject_input_only* = 0x00000002
|
bm_TGdkWindowObject_input_only* = 0x00000002'i16
|
||||||
bp_TGdkWindowObject_input_only* = 1
|
bp_TGdkWindowObject_input_only* = 1'i16
|
||||||
bm_TGdkWindowObject_modal_hint* = 0x00000004
|
bm_TGdkWindowObject_modal_hint* = 0x00000004'i16
|
||||||
bp_TGdkWindowObject_modal_hint* = 2
|
bp_TGdkWindowObject_modal_hint* = 2'i16
|
||||||
bm_TGdkWindowObject_destroyed* = 0x00000018
|
bm_TGdkWindowObject_destroyed* = 0x00000018'i16
|
||||||
bp_TGdkWindowObject_destroyed* = 3
|
bp_TGdkWindowObject_destroyed* = 3'i16
|
||||||
|
|
||||||
proc GdkWindowObject_guffaw_gravity*(a: var TGdkWindowObject): guint
|
proc GdkWindowObject_guffaw_gravity*(a: var TGdkWindowObject): guint
|
||||||
proc GdkWindowObject_set_guffaw_gravity*(a: var TGdkWindowObject,
|
proc GdkWindowObject_set_guffaw_gravity*(a: var TGdkWindowObject,
|
||||||
|
|
@ -3417,7 +3416,7 @@ proc gdk_init*(argc: Pgint, v: var PPgchar){.cdecl, dynlib: gdklib,
|
||||||
proc gdk_init_check*(argc: Pgint, v: var PPgchar): gboolean{.cdecl,
|
proc gdk_init_check*(argc: Pgint, v: var PPgchar): gboolean{.cdecl,
|
||||||
dynlib: gdklib, importc: "gdk_init_check".}
|
dynlib: gdklib, importc: "gdk_init_check".}
|
||||||
when not defined(GDK_DISABLE_DEPRECATED):
|
when not defined(GDK_DISABLE_DEPRECATED):
|
||||||
proc gdk_exit(error_code: gint){.cdecl, dynlib: gdklib, importc: "gdk_exit".}
|
proc gdk_exit*(error_code: gint){.cdecl, dynlib: gdklib, importc: "gdk_exit".}
|
||||||
proc gdk_set_locale*(): cstring{.cdecl, dynlib: gdklib, importc: "gdk_set_locale".}
|
proc gdk_set_locale*(): cstring{.cdecl, dynlib: gdklib, importc: "gdk_set_locale".}
|
||||||
proc gdk_get_program_class*(): cstring{.cdecl, dynlib: gdklib,
|
proc gdk_get_program_class*(): cstring{.cdecl, dynlib: gdklib,
|
||||||
importc: "gdk_get_program_class".}
|
importc: "gdk_get_program_class".}
|
||||||
|
|
@ -3428,23 +3427,23 @@ proc gdk_error_trap_push*(){.cdecl, dynlib: gdklib,
|
||||||
proc gdk_error_trap_pop*(): gint{.cdecl, dynlib: gdklib,
|
proc gdk_error_trap_pop*(): gint{.cdecl, dynlib: gdklib,
|
||||||
importc: "gdk_error_trap_pop".}
|
importc: "gdk_error_trap_pop".}
|
||||||
when not defined(GDK_DISABLE_DEPRECATED):
|
when not defined(GDK_DISABLE_DEPRECATED):
|
||||||
proc gdk_set_use_xshm(use_xshm: gboolean){.cdecl, dynlib: gdklib,
|
proc gdk_set_use_xshm*(use_xshm: gboolean){.cdecl, dynlib: gdklib,
|
||||||
importc: "gdk_set_use_xshm".}
|
importc: "gdk_set_use_xshm".}
|
||||||
proc gdk_get_use_xshm(): gboolean{.cdecl, dynlib: gdklib,
|
proc gdk_get_use_xshm*(): gboolean{.cdecl, dynlib: gdklib,
|
||||||
importc: "gdk_get_use_xshm".}
|
importc: "gdk_get_use_xshm".}
|
||||||
proc gdk_get_display*(): cstring{.cdecl, dynlib: gdklib,
|
proc gdk_get_display*(): cstring{.cdecl, dynlib: gdklib,
|
||||||
importc: "gdk_get_display".}
|
importc: "gdk_get_display".}
|
||||||
proc gdk_get_display_arg_name*(): cstring{.cdecl, dynlib: gdklib,
|
proc gdk_get_display_arg_name*(): cstring{.cdecl, dynlib: gdklib,
|
||||||
importc: "gdk_get_display_arg_name".}
|
importc: "gdk_get_display_arg_name".}
|
||||||
when not defined(GDK_DISABLE_DEPRECATED):
|
when not defined(GDK_DISABLE_DEPRECATED):
|
||||||
proc gdk_input_add_full(source: gint, condition: TGdkInputCondition,
|
proc gdk_input_add_full*(source: gint, condition: TGdkInputCondition,
|
||||||
`function`: TGdkInputFunction, data: gpointer,
|
`function`: TGdkInputFunction, data: gpointer,
|
||||||
destroy: TGdkDestroyNotify): gint{.cdecl,
|
destroy: TGdkDestroyNotify): gint{.cdecl,
|
||||||
dynlib: gdklib, importc: "gdk_input_add_full".}
|
dynlib: gdklib, importc: "gdk_input_add_full".}
|
||||||
proc gdk_input_add(source: gint, condition: TGdkInputCondition,
|
proc gdk_input_add*(source: gint, condition: TGdkInputCondition,
|
||||||
`function`: TGdkInputFunction, data: gpointer): gint{.
|
`function`: TGdkInputFunction, data: gpointer): gint{.
|
||||||
cdecl, dynlib: gdklib, importc: "gdk_input_add".}
|
cdecl, dynlib: gdklib, importc: "gdk_input_add".}
|
||||||
proc gdk_input_remove(tag: gint){.cdecl, dynlib: gdklib,
|
proc gdk_input_remove*(tag: gint){.cdecl, dynlib: gdklib,
|
||||||
importc: "gdk_input_remove".}
|
importc: "gdk_input_remove".}
|
||||||
proc gdk_pointer_grab*(window: PGdkWindow, owner_events: gboolean,
|
proc gdk_pointer_grab*(window: PGdkWindow, owner_events: gboolean,
|
||||||
event_mask: TGdkEventMask, confine_to: PGdkWindow,
|
event_mask: TGdkEventMask, confine_to: PGdkWindow,
|
||||||
|
|
@ -3454,24 +3453,24 @@ proc gdk_keyboard_grab*(window: PGdkWindow, owner_events: gboolean,
|
||||||
time: guint32): TGdkGrabStatus{.cdecl, dynlib: gdklib,
|
time: guint32): TGdkGrabStatus{.cdecl, dynlib: gdklib,
|
||||||
importc: "gdk_keyboard_grab".}
|
importc: "gdk_keyboard_grab".}
|
||||||
when not defined(GDK_MULTIHEAD_SAFE):
|
when not defined(GDK_MULTIHEAD_SAFE):
|
||||||
proc gdk_pointer_ungrab(time: guint32){.cdecl, dynlib: gdklib,
|
proc gdk_pointer_ungrab*(time: guint32){.cdecl, dynlib: gdklib,
|
||||||
importc: "gdk_pointer_ungrab".}
|
importc: "gdk_pointer_ungrab".}
|
||||||
proc gdk_keyboard_ungrab(time: guint32){.cdecl, dynlib: gdklib,
|
proc gdk_keyboard_ungrab*(time: guint32){.cdecl, dynlib: gdklib,
|
||||||
importc: "gdk_keyboard_ungrab".}
|
importc: "gdk_keyboard_ungrab".}
|
||||||
proc gdk_pointer_is_grabbed(): gboolean{.cdecl, dynlib: gdklib,
|
proc gdk_pointer_is_grabbed*(): gboolean{.cdecl, dynlib: gdklib,
|
||||||
importc: "gdk_pointer_is_grabbed".}
|
importc: "gdk_pointer_is_grabbed".}
|
||||||
proc gdk_screen_width(): gint{.cdecl, dynlib: gdklib,
|
proc gdk_screen_width*(): gint{.cdecl, dynlib: gdklib,
|
||||||
importc: "gdk_screen_width".}
|
importc: "gdk_screen_width".}
|
||||||
proc gdk_screen_height(): gint{.cdecl, dynlib: gdklib,
|
proc gdk_screen_height*(): gint{.cdecl, dynlib: gdklib,
|
||||||
importc: "gdk_screen_height".}
|
importc: "gdk_screen_height".}
|
||||||
proc gdk_screen_width_mm(): gint{.cdecl, dynlib: gdklib,
|
proc gdk_screen_width_mm*(): gint{.cdecl, dynlib: gdklib,
|
||||||
importc: "gdk_screen_width_mm".}
|
importc: "gdk_screen_width_mm".}
|
||||||
proc gdk_screen_height_mm(): gint{.cdecl, dynlib: gdklib,
|
proc gdk_screen_height_mm*(): gint{.cdecl, dynlib: gdklib,
|
||||||
importc: "gdk_screen_height_mm".}
|
importc: "gdk_screen_height_mm".}
|
||||||
proc gdk_beep(){.cdecl, dynlib: gdklib, importc: "gdk_beep".}
|
proc gdk_beep*(){.cdecl, dynlib: gdklib, importc: "gdk_beep".}
|
||||||
proc gdk_flush*(){.cdecl, dynlib: gdklib, importc: "gdk_flush".}
|
proc gdk_flush*(){.cdecl, dynlib: gdklib, importc: "gdk_flush".}
|
||||||
when not defined(GDK_MULTIHEAD_SAFE):
|
when not defined(GDK_MULTIHEAD_SAFE):
|
||||||
proc gdk_set_double_click_time(msec: guint){.cdecl, dynlib: gdklib,
|
proc gdk_set_double_click_time*(msec: guint){.cdecl, dynlib: gdklib,
|
||||||
importc: "gdk_set_double_click_time".}
|
importc: "gdk_set_double_click_time".}
|
||||||
proc gdk_rectangle_intersect*(src1: PGdkRectangle, src2: PGdkRectangle,
|
proc gdk_rectangle_intersect*(src1: PGdkRectangle, src2: PGdkRectangle,
|
||||||
dest: PGdkRectangle): gboolean{.cdecl,
|
dest: PGdkRectangle): gboolean{.cdecl,
|
||||||
|
|
@ -3487,9 +3486,9 @@ proc gdk_wcstombs*(src: PGdkWChar): cstring{.cdecl, dynlib: gdklib,
|
||||||
proc gdk_mbstowcs*(dest: PGdkWChar, src: cstring, dest_max: gint): gint{.cdecl,
|
proc gdk_mbstowcs*(dest: PGdkWChar, src: cstring, dest_max: gint): gint{.cdecl,
|
||||||
dynlib: gdklib, importc: "gdk_mbstowcs".}
|
dynlib: gdklib, importc: "gdk_mbstowcs".}
|
||||||
when not defined(GDK_MULTIHEAD_SAFE):
|
when not defined(GDK_MULTIHEAD_SAFE):
|
||||||
proc gdk_event_send_client_message(event: PGdkEvent, xid: guint32): gboolean{.
|
proc gdk_event_send_client_message*(event: PGdkEvent, xid: guint32): gboolean{.
|
||||||
cdecl, dynlib: gdklib, importc: "gdk_event_send_client_message".}
|
cdecl, dynlib: gdklib, importc: "gdk_event_send_client_message".}
|
||||||
proc gdk_event_send_clientmessage_toall(event: PGdkEvent){.cdecl,
|
proc gdk_event_send_clientmessage_toall*(event: PGdkEvent){.cdecl,
|
||||||
dynlib: gdklib, importc: "gdk_event_send_clientmessage_toall".}
|
dynlib: gdklib, importc: "gdk_event_send_clientmessage_toall".}
|
||||||
proc gdk_event_send_client_message_for_display*(display: PGdkDisplay,
|
proc gdk_event_send_client_message_for_display*(display: PGdkDisplay,
|
||||||
event: PGdkEvent, xid: guint32): gboolean{.cdecl, dynlib: gdklib,
|
event: PGdkEvent, xid: guint32): gboolean{.cdecl, dynlib: gdklib,
|
||||||
|
|
@ -3550,27 +3549,27 @@ proc GDK_DRAG_CONTEXT_GET_CLASS*(obj: Pointer): PGdkDragContextClass =
|
||||||
GDK_TYPE_DRAG_CONTEXT()))
|
GDK_TYPE_DRAG_CONTEXT()))
|
||||||
|
|
||||||
proc gdkregion_EXTENTCHECK*(r1, r2: PGdkRegionBox): bool =
|
proc gdkregion_EXTENTCHECK*(r1, r2: PGdkRegionBox): bool =
|
||||||
result = (int(r1.x2) > r2.x1) and (int(r1.x1) < r2.x2) and
|
result = ((r1.x2) > r2.x1) and ((r1.x1) < r2.x2) and
|
||||||
(int(r1.y2) > r2.y1) and (int(r1.y1) < r2.y2)
|
((r1.y2) > r2.y1) and ((r1.y1) < r2.y2)
|
||||||
|
|
||||||
proc gdkregion_EXTENTS*(r: PGdkRegionBox, idRect: PGdkRegion) =
|
proc gdkregion_EXTENTS*(r: PGdkRegionBox, idRect: PGdkRegion) =
|
||||||
if (int(r.x1) < idRect.extents.x1):
|
if ((r.x1) < idRect.extents.x1):
|
||||||
idRect.extents.x1 = r.x1
|
idRect.extents.x1 = r.x1
|
||||||
if int(r.y1) < idRect.extents.y1:
|
if (r.y1) < idRect.extents.y1:
|
||||||
idRect.extents.y1 = r.y1
|
idRect.extents.y1 = r.y1
|
||||||
if int(r.x2) > idRect.extents.x2:
|
if (r.x2) > idRect.extents.x2:
|
||||||
idRect.extents.x2 = r.x2
|
idRect.extents.x2 = r.x2
|
||||||
|
|
||||||
proc gdkregion_MEMCHECK*(reg: PGdkRegion, ARect, firstrect: var PGdkRegionBox): bool =
|
proc gdkregion_MEMCHECK*(reg: PGdkRegion, ARect, firstrect: var PGdkRegionBox): bool =
|
||||||
nil
|
assert(false) # to implement
|
||||||
|
|
||||||
proc gdkregion_CHECK_PREVIOUS*(Reg: PGdkRegion, R: PGdkRegionBox,
|
proc gdkregion_CHECK_PREVIOUS*(Reg: PGdkRegion, R: PGdkRegionBox,
|
||||||
Rx1, Ry1, Rx2, Ry2: gint): bool =
|
Rx1, Ry1, Rx2, Ry2: gint): bool =
|
||||||
nil
|
assert(false) # to implement
|
||||||
|
|
||||||
proc gdkregion_ADDRECT*(reg: PGdkRegion, r: PGdkRegionBox,
|
proc gdkregion_ADDRECT*(reg: PGdkRegion, r: PGdkRegionBox,
|
||||||
rx1, ry1, rx2, ry2: gint) =
|
rx1, ry1, rx2, ry2: gint) =
|
||||||
if ((int(rx1) < rx2) and (int(ry1) < ry2) and
|
if (((rx1) < rx2) and ((ry1) < ry2) and
|
||||||
gdkregion_CHECK_PREVIOUS(reg, r, rx1, ry1, rx2, ry2)):
|
gdkregion_CHECK_PREVIOUS(reg, r, rx1, ry1, rx2, ry2)):
|
||||||
r.x1 = rx1
|
r.x1 = rx1
|
||||||
r.y1 = ry1
|
r.y1 = ry1
|
||||||
|
|
@ -3579,7 +3578,7 @@ proc gdkregion_ADDRECT*(reg: PGdkRegion, r: PGdkRegionBox,
|
||||||
|
|
||||||
proc gdkregion_ADDRECTNOX*(reg: PGdkRegion, r: PGdkRegionBox,
|
proc gdkregion_ADDRECTNOX*(reg: PGdkRegion, r: PGdkRegionBox,
|
||||||
rx1, ry1, rx2, ry2: gint) =
|
rx1, ry1, rx2, ry2: gint) =
|
||||||
if ((int(rx1) < rx2) and (int(ry1) < ry2) and
|
if (((rx1) < rx2) and ((ry1) < ry2) and
|
||||||
gdkregion_CHECK_PREVIOUS(reg, r, rx1, ry1, rx2, ry2)):
|
gdkregion_CHECK_PREVIOUS(reg, r, rx1, ry1, rx2, ry2)):
|
||||||
r.x1 = rx1
|
r.x1 = rx1
|
||||||
r.y1 = ry1
|
r.y1 = ry1
|
||||||
|
|
@ -3588,14 +3587,14 @@ proc gdkregion_ADDRECTNOX*(reg: PGdkRegion, r: PGdkRegionBox,
|
||||||
inc(reg . numRects)
|
inc(reg . numRects)
|
||||||
|
|
||||||
proc gdkregion_EMPTY_REGION*(pReg: PGdkRegion): bool =
|
proc gdkregion_EMPTY_REGION*(pReg: PGdkRegion): bool =
|
||||||
result = pReg.numRects == 0
|
result = pReg.numRects == 0'i32
|
||||||
|
|
||||||
proc gdkregion_REGION_NOT_EMPTY*(pReg: PGdkRegion): bool =
|
proc gdkregion_REGION_NOT_EMPTY*(pReg: PGdkRegion): bool =
|
||||||
result = pReg.numRects != 0
|
result = pReg.numRects != 0'i32
|
||||||
|
|
||||||
proc gdkregion_INBOX*(r: TGdkRegionBox, x, y: gint): bool =
|
proc gdkregion_INBOX*(r: TGdkRegionBox, x, y: gint): bool =
|
||||||
result = (((int(r.x2) > x) and (int(r.x1) <= x)) and
|
result = ((((r.x2) > x) and ((r.x1) <= x)) and
|
||||||
(int(r.y2) > y)) and (int(r.y1) <= y)
|
((r.y2) > y)) and ((r.y1) <= y)
|
||||||
|
|
||||||
proc GDK_TYPE_DRAWABLE*(): GType =
|
proc GDK_TYPE_DRAWABLE*(): GType =
|
||||||
result = gdk_drawable_get_type()
|
result = gdk_drawable_get_type()
|
||||||
|
|
@ -3894,7 +3893,7 @@ proc GdkWindowObject_guffaw_gravity*(a: var TGdkWindowObject): guint =
|
||||||
proc GdkWindowObject_set_guffaw_gravity*(a: var TGdkWindowObject,
|
proc GdkWindowObject_set_guffaw_gravity*(a: var TGdkWindowObject,
|
||||||
`guffaw_gravity`: guint) =
|
`guffaw_gravity`: guint) =
|
||||||
a.flag0 = a.flag0 or
|
a.flag0 = a.flag0 or
|
||||||
((`guffaw_gravity` shl bp_TGdkWindowObject_guffaw_gravity) and
|
(int16(`guffaw_gravity` shl bp_TGdkWindowObject_guffaw_gravity) and
|
||||||
bm_TGdkWindowObject_guffaw_gravity)
|
bm_TGdkWindowObject_guffaw_gravity)
|
||||||
|
|
||||||
proc GdkWindowObject_input_only*(a: var TGdkWindowObject): guint =
|
proc GdkWindowObject_input_only*(a: var TGdkWindowObject): guint =
|
||||||
|
|
@ -3904,7 +3903,7 @@ proc GdkWindowObject_input_only*(a: var TGdkWindowObject): guint =
|
||||||
proc GdkWindowObject_set_input_only*(a: var TGdkWindowObject,
|
proc GdkWindowObject_set_input_only*(a: var TGdkWindowObject,
|
||||||
`input_only`: guint) =
|
`input_only`: guint) =
|
||||||
a.flag0 = a.flag0 or
|
a.flag0 = a.flag0 or
|
||||||
((`input_only` shl bp_TGdkWindowObject_input_only) and
|
(int16(`input_only` shl bp_TGdkWindowObject_input_only) and
|
||||||
bm_TGdkWindowObject_input_only)
|
bm_TGdkWindowObject_input_only)
|
||||||
|
|
||||||
proc GdkWindowObject_modal_hint*(a: var TGdkWindowObject): guint =
|
proc GdkWindowObject_modal_hint*(a: var TGdkWindowObject): guint =
|
||||||
|
|
@ -3914,7 +3913,7 @@ proc GdkWindowObject_modal_hint*(a: var TGdkWindowObject): guint =
|
||||||
proc GdkWindowObject_set_modal_hint*(a: var TGdkWindowObject,
|
proc GdkWindowObject_set_modal_hint*(a: var TGdkWindowObject,
|
||||||
`modal_hint`: guint) =
|
`modal_hint`: guint) =
|
||||||
a.flag0 = a.flag0 or
|
a.flag0 = a.flag0 or
|
||||||
((`modal_hint` shl bp_TGdkWindowObject_modal_hint) and
|
(int16(`modal_hint` shl bp_TGdkWindowObject_modal_hint) and
|
||||||
bm_TGdkWindowObject_modal_hint)
|
bm_TGdkWindowObject_modal_hint)
|
||||||
|
|
||||||
proc GdkWindowObject_destroyed*(a: var TGdkWindowObject): guint =
|
proc GdkWindowObject_destroyed*(a: var TGdkWindowObject): guint =
|
||||||
|
|
@ -3923,7 +3922,7 @@ proc GdkWindowObject_destroyed*(a: var TGdkWindowObject): guint =
|
||||||
|
|
||||||
proc GdkWindowObject_set_destroyed*(a: var TGdkWindowObject, `destroyed`: guint) =
|
proc GdkWindowObject_set_destroyed*(a: var TGdkWindowObject, `destroyed`: guint) =
|
||||||
a.flag0 = a.flag0 or
|
a.flag0 = a.flag0 or
|
||||||
((`destroyed` shl bp_TGdkWindowObject_destroyed) and
|
(int16(`destroyed` shl bp_TGdkWindowObject_destroyed) and
|
||||||
bm_TGdkWindowObject_destroyed)
|
bm_TGdkWindowObject_destroyed)
|
||||||
|
|
||||||
proc GDK_ROOT_PARENT*(): PGdkWindow =
|
proc GDK_ROOT_PARENT*(): PGdkWindow =
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import
|
||||||
glib2
|
glib2
|
||||||
|
|
||||||
when defined(win32):
|
when defined(win32):
|
||||||
{.define: gdkpixbufwin.}
|
|
||||||
const
|
const
|
||||||
gdkpixbuflib = "libgdk_pixbuf-2.0-0.dll"
|
gdkpixbuflib = "libgdk_pixbuf-2.0-0.dll"
|
||||||
elif defined(darwin):
|
elif defined(darwin):
|
||||||
|
|
@ -18,8 +17,7 @@ elif defined(darwin):
|
||||||
else:
|
else:
|
||||||
const
|
const
|
||||||
gdkpixbuflib = "libgdk_pixbuf-2.0.so"
|
gdkpixbuflib = "libgdk_pixbuf-2.0.so"
|
||||||
{.define: HasGTK2_4.}
|
|
||||||
{.define: HasGTK2_6.}
|
|
||||||
type
|
type
|
||||||
PGdkPixbuf* = pointer
|
PGdkPixbuf* = pointer
|
||||||
PGdkPixbufAnimation* = pointer
|
PGdkPixbufAnimation* = pointer
|
||||||
|
|
@ -55,9 +53,9 @@ proc gdk_pixbuf_error_quark*(): TGQuark{.cdecl, dynlib: gdkpixbuflib,
|
||||||
proc gdk_pixbuf_get_type*(): GType{.cdecl, dynlib: gdkpixbuflib,
|
proc gdk_pixbuf_get_type*(): GType{.cdecl, dynlib: gdkpixbuflib,
|
||||||
importc: "gdk_pixbuf_get_type".}
|
importc: "gdk_pixbuf_get_type".}
|
||||||
when not defined(GDK_PIXBUF_DISABLE_DEPRECATED):
|
when not defined(GDK_PIXBUF_DISABLE_DEPRECATED):
|
||||||
proc gdk_pixbuf_ref(pixbuf: PGdkPixbuf): PGdkPixbuf{.cdecl,
|
proc gdk_pixbuf_ref*(pixbuf: PGdkPixbuf): PGdkPixbuf{.cdecl,
|
||||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_ref".}
|
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_ref".}
|
||||||
proc gdk_pixbuf_unref(pixbuf: PGdkPixbuf){.cdecl, dynlib: gdkpixbuflib,
|
proc gdk_pixbuf_unref*(pixbuf: PGdkPixbuf){.cdecl, dynlib: gdkpixbuflib,
|
||||||
importc: "gdk_pixbuf_unref".}
|
importc: "gdk_pixbuf_unref".}
|
||||||
proc gdk_pixbuf_get_colorspace*(pixbuf: PGdkPixbuf): TGdkColorspace{.cdecl,
|
proc gdk_pixbuf_get_colorspace*(pixbuf: PGdkPixbuf): TGdkColorspace{.cdecl,
|
||||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_get_colorspace".}
|
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_get_colorspace".}
|
||||||
|
|
@ -96,12 +94,10 @@ proc gdk_pixbuf_new_from_xpm_data*(data: PPchar): PGdkPixbuf{.cdecl,
|
||||||
proc gdk_pixbuf_new_from_inline*(data_length: gint, a: var guint8,
|
proc gdk_pixbuf_new_from_inline*(data_length: gint, a: var guint8,
|
||||||
copy_pixels: gboolean, error: pointer): PGdkPixbuf{.
|
copy_pixels: gboolean, error: pointer): PGdkPixbuf{.
|
||||||
cdecl, dynlib: gdkpixbuflib, importc: "gdk_pixbuf_new_from_inline".}
|
cdecl, dynlib: gdkpixbuflib, importc: "gdk_pixbuf_new_from_inline".}
|
||||||
when defined(HasGTK2_4):
|
proc gdk_pixbuf_new_from_file_at_size*(filename: cstring, width, height: gint,
|
||||||
proc gdk_pixbuf_new_from_file_at_size(filename: cstring, width, height: gint,
|
|
||||||
error: pointer): PGdkPixbuf{.cdecl,
|
error: pointer): PGdkPixbuf{.cdecl,
|
||||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_new_from_file_at_size".}
|
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_new_from_file_at_size".}
|
||||||
when defined(HasGTK2_6):
|
proc gdk_pixbuf_new_from_file_at_scale*(filename: cstring, width, height: gint,
|
||||||
proc gdk_pixbuf_new_from_file_at_scale(filename: cstring, width, height: gint,
|
|
||||||
preserve_aspect_ratio: gboolean, error: pointer): PGdkPixbuf{.cdecl,
|
preserve_aspect_ratio: gboolean, error: pointer): PGdkPixbuf{.cdecl,
|
||||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_new_from_file_at_scale".}
|
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_new_from_file_at_scale".}
|
||||||
proc gdk_pixbuf_fill*(pixbuf: PGdkPixbuf, pixel: guint32){.cdecl,
|
proc gdk_pixbuf_fill*(pixbuf: PGdkPixbuf, pixel: guint32){.cdecl,
|
||||||
|
|
@ -158,9 +154,9 @@ proc gdk_pixbuf_animation_get_type*(): GType{.cdecl, dynlib: gdkpixbuflib,
|
||||||
proc gdk_pixbuf_animation_new_from_file*(filename: cstring, error: pointer): PGdkPixbufAnimation{.
|
proc gdk_pixbuf_animation_new_from_file*(filename: cstring, error: pointer): PGdkPixbufAnimation{.
|
||||||
cdecl, dynlib: gdkpixbuflib, importc: "gdk_pixbuf_animation_new_from_file".}
|
cdecl, dynlib: gdkpixbuflib, importc: "gdk_pixbuf_animation_new_from_file".}
|
||||||
when not defined(GDK_PIXBUF_DISABLE_DEPRECATED):
|
when not defined(GDK_PIXBUF_DISABLE_DEPRECATED):
|
||||||
proc gdk_pixbuf_animation_ref(animation: PGdkPixbufAnimation): PGdkPixbufAnimation{.
|
proc gdk_pixbuf_animation_ref*(animation: PGdkPixbufAnimation): PGdkPixbufAnimation{.
|
||||||
cdecl, dynlib: gdkpixbuflib, importc: "gdk_pixbuf_animation_ref".}
|
cdecl, dynlib: gdkpixbuflib, importc: "gdk_pixbuf_animation_ref".}
|
||||||
proc gdk_pixbuf_animation_unref(animation: PGdkPixbufAnimation){.cdecl,
|
proc gdk_pixbuf_animation_unref*(animation: PGdkPixbufAnimation){.cdecl,
|
||||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_animation_unref".}
|
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_animation_unref".}
|
||||||
proc gdk_pixbuf_animation_get_width*(animation: PGdkPixbufAnimation): int32{.
|
proc gdk_pixbuf_animation_get_width*(animation: PGdkPixbufAnimation): int32{.
|
||||||
cdecl, dynlib: gdkpixbuflib, importc: "gdk_pixbuf_animation_get_width".}
|
cdecl, dynlib: gdkpixbuflib, importc: "gdk_pixbuf_animation_get_width".}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
{.define: gtkwin.}
|
|
||||||
const
|
const
|
||||||
gliblib = "libglib-2.0-0.dll"
|
gliblib = "libglib-2.0-0.dll"
|
||||||
gthreadlib = "libgthread-2.0-0.dll"
|
|
||||||
gmodulelib = "libgmodule-2.0-0.dll"
|
gmodulelib = "libgmodule-2.0-0.dll"
|
||||||
gobjectlib = "libgobject-2.0-0.dll"
|
gobjectlib = "libgobject-2.0-0.dll"
|
||||||
else:
|
else:
|
||||||
const
|
const
|
||||||
gliblib = "libglib-2.0.so"
|
gliblib = "libglib-2.0.so"
|
||||||
gthreadlib = "libgthread-2.0.so"
|
|
||||||
gmodulelib = "libgmodule-2.0.so"
|
gmodulelib = "libgmodule-2.0.so"
|
||||||
gobjectlib = "libgobject-2.0.so"
|
gobjectlib = "libgobject-2.0.so"
|
||||||
|
|
||||||
|
# gthreadlib = "libgthread-2.0.so"
|
||||||
|
|
||||||
type
|
type
|
||||||
PGTypePlugin* = pointer
|
PGTypePlugin* = pointer
|
||||||
PGParamSpecPool* = pointer
|
PGParamSpecPool* = pointer
|
||||||
|
|
@ -19,29 +19,29 @@ type
|
||||||
PPPgchar* = ptr PPgchar
|
PPPgchar* = ptr PPgchar
|
||||||
PPgchar* = ptr cstring
|
PPgchar* = ptr cstring
|
||||||
gchar* = char
|
gchar* = char
|
||||||
Pgshort* = ptr gshort
|
|
||||||
gshort* = cshort
|
gshort* = cshort
|
||||||
Pglong* = ptr glong
|
|
||||||
glong* = clong
|
glong* = clong
|
||||||
Pgint* = ptr gint
|
|
||||||
PPgint* = ptr Pgint
|
|
||||||
gint* = cint
|
gint* = cint
|
||||||
Pgboolean* = ptr gboolean
|
|
||||||
gboolean* = bool
|
gboolean* = bool
|
||||||
Pguchar* = ptr guchar
|
|
||||||
PPguchar* = ptr Pguchar
|
|
||||||
guchar* = char
|
guchar* = char
|
||||||
Pgushort* = ptr gushort
|
|
||||||
gushort* = int16
|
gushort* = int16
|
||||||
Pgulong* = ptr gulong
|
|
||||||
gulong* = int
|
gulong* = int
|
||||||
guint* = cint
|
guint* = cint
|
||||||
Pguint* = ptr guint
|
|
||||||
gfloat* = cfloat
|
gfloat* = cfloat
|
||||||
Pgfloat* = ptr gfloat
|
|
||||||
gdouble* = cdouble
|
gdouble* = cdouble
|
||||||
Pgdouble* = ptr gdouble
|
|
||||||
gpointer* = pointer
|
gpointer* = pointer
|
||||||
|
Pgshort* = ptr gshort
|
||||||
|
Pglong* = ptr glong
|
||||||
|
Pgint* = ptr gint
|
||||||
|
PPgint* = ptr Pgint
|
||||||
|
Pgboolean* = ptr gboolean
|
||||||
|
Pguchar* = ptr guchar
|
||||||
|
PPguchar* = ptr Pguchar
|
||||||
|
Pgushort* = ptr gushort
|
||||||
|
Pgulong* = ptr gulong
|
||||||
|
Pguint* = ptr guint
|
||||||
|
Pgfloat* = ptr gfloat
|
||||||
|
Pgdouble* = ptr gdouble
|
||||||
pgpointer* = ptr gpointer
|
pgpointer* = ptr gpointer
|
||||||
gconstpointer* = pointer
|
gconstpointer* = pointer
|
||||||
PGCompareFunc* = ptr TGCompareFunc
|
PGCompareFunc* = ptr TGCompareFunc
|
||||||
|
|
@ -118,8 +118,8 @@ type
|
||||||
g_type*: GType
|
g_type*: GType
|
||||||
data*: array[0..1, gdouble]
|
data*: array[0..1, gdouble]
|
||||||
|
|
||||||
PPGData* = ptr PGData
|
|
||||||
PGData* = pointer
|
PGData* = pointer
|
||||||
|
PPGData* = ptr PGData
|
||||||
PGSList* = ptr TGSList
|
PGSList* = ptr TGSList
|
||||||
PPGSList* = ptr PGSList
|
PPGSList* = ptr PGSList
|
||||||
TGSList* {.final.} = object
|
TGSList* {.final.} = object
|
||||||
|
|
@ -132,8 +132,8 @@ type
|
||||||
next*: PGList
|
next*: PGList
|
||||||
prev*: PGList
|
prev*: PGList
|
||||||
|
|
||||||
PGParamFlags* = ptr TGParamFlags
|
|
||||||
TGParamFlags* = int32
|
TGParamFlags* = int32
|
||||||
|
PGParamFlags* = ptr TGParamFlags
|
||||||
PGParamSpec* = ptr TGParamSpec
|
PGParamSpec* = ptr TGParamSpec
|
||||||
PPGParamSpec* = ptr PGParamSpec
|
PPGParamSpec* = ptr PGParamSpec
|
||||||
TGParamSpec* {.final.} = object
|
TGParamSpec* {.final.} = object
|
||||||
|
|
@ -194,7 +194,7 @@ const
|
||||||
G_TYPE_PARAM* = GType(19 shl G_TYPE_FUNDAMENTAL_SHIFT)
|
G_TYPE_PARAM* = GType(19 shl G_TYPE_FUNDAMENTAL_SHIFT)
|
||||||
G_TYPE_OBJECT* = GType(20 shl G_TYPE_FUNDAMENTAL_SHIFT)
|
G_TYPE_OBJECT* = GType(20 shl G_TYPE_FUNDAMENTAL_SHIFT)
|
||||||
|
|
||||||
proc G_TYPE_MAKE_FUNDAMENTAL*(x: int32): GType
|
proc G_TYPE_MAKE_FUNDAMENTAL*(x: int): GType
|
||||||
const
|
const
|
||||||
G_TYPE_RESERVED_GLIB_FIRST* = 21
|
G_TYPE_RESERVED_GLIB_FIRST* = 21
|
||||||
G_TYPE_RESERVED_GLIB_LAST* = 31
|
G_TYPE_RESERVED_GLIB_LAST* = 31
|
||||||
|
|
@ -226,8 +226,8 @@ proc G_TYPE_FROM_INSTANCE*(instance: Pointer): GType
|
||||||
proc G_TYPE_FROM_CLASS*(g_class: Pointer): GType
|
proc G_TYPE_FROM_CLASS*(g_class: Pointer): GType
|
||||||
proc G_TYPE_FROM_INTERFACE*(g_iface: Pointer): GType
|
proc G_TYPE_FROM_INTERFACE*(g_iface: Pointer): GType
|
||||||
type
|
type
|
||||||
PGTypeDebugFlags* = ptr TGTypeDebugFlags
|
|
||||||
TGTypeDebugFlags* = int32
|
TGTypeDebugFlags* = int32
|
||||||
|
PGTypeDebugFlags* = ptr TGTypeDebugFlags
|
||||||
|
|
||||||
const
|
const
|
||||||
G_TYPE_DEBUG_NONE* = 0
|
G_TYPE_DEBUG_NONE* = 0
|
||||||
|
|
@ -296,8 +296,8 @@ const
|
||||||
G_TYPE_FLAG_DEEP_DERIVABLE* = 1 shl 3
|
G_TYPE_FLAG_DEEP_DERIVABLE* = 1 shl 3
|
||||||
|
|
||||||
type
|
type
|
||||||
PGTypeFlags* = ptr TGTypeFlags
|
|
||||||
TGTypeFlags* = int32
|
TGTypeFlags* = int32
|
||||||
|
PGTypeFlags* = ptr TGTypeFlags
|
||||||
|
|
||||||
const
|
const
|
||||||
G_TYPE_FLAG_ABSTRACT* = 1 shl 4
|
G_TYPE_FLAG_ABSTRACT* = 1 shl 4
|
||||||
|
|
@ -562,8 +562,8 @@ proc g_strdup_value_contents*(value: PGValue): cstring{.cdecl,
|
||||||
proc g_value_set_string_take_ownership*(value: PGValue, v_string: cstring){.
|
proc g_value_set_string_take_ownership*(value: PGValue, v_string: cstring){.
|
||||||
cdecl, dynlib: gobjectlib, importc: "g_value_set_string_take_ownership".}
|
cdecl, dynlib: gobjectlib, importc: "g_value_set_string_take_ownership".}
|
||||||
type
|
type
|
||||||
Pgchararray* = ptr Tgchararray
|
|
||||||
Tgchararray* = gchar
|
Tgchararray* = gchar
|
||||||
|
Pgchararray* = ptr Tgchararray
|
||||||
|
|
||||||
proc G_TYPE_IS_PARAM*(theType: GType): bool
|
proc G_TYPE_IS_PARAM*(theType: GType): bool
|
||||||
proc G_PARAM_SPEC*(pspec: Pointer): PGParamSpec
|
proc G_PARAM_SPEC*(pspec: Pointer): PGParamSpec
|
||||||
|
|
@ -692,26 +692,26 @@ proc G_CLOSURE_N_NOTIFIERS*(cl: PGClosure): int32
|
||||||
proc G_CCLOSURE_SWAP_DATA*(cclosure: PGClosure): int32
|
proc G_CCLOSURE_SWAP_DATA*(cclosure: PGClosure): int32
|
||||||
proc G_CALLBACK*(f: pointer): TGCallback
|
proc G_CALLBACK*(f: pointer): TGCallback
|
||||||
const
|
const
|
||||||
bm_TGClosure_ref_count* = 0x00007FFF
|
bm_TGClosure_ref_count* = 0x00007FFF'i32
|
||||||
bp_TGClosure_ref_count* = 0
|
bp_TGClosure_ref_count* = 0'i32
|
||||||
bm_TGClosure_meta_marshal* = 0x00008000
|
bm_TGClosure_meta_marshal* = 0x00008000'i32
|
||||||
bp_TGClosure_meta_marshal* = 15
|
bp_TGClosure_meta_marshal* = 15'i32
|
||||||
bm_TGClosure_n_guards* = 0x00010000
|
bm_TGClosure_n_guards* = 0x00010000'i32
|
||||||
bp_TGClosure_n_guards* = 16
|
bp_TGClosure_n_guards* = 16'i32
|
||||||
bm_TGClosure_n_fnotifiers* = 0x00060000
|
bm_TGClosure_n_fnotifiers* = 0x00060000'i32
|
||||||
bp_TGClosure_n_fnotifiers* = 17
|
bp_TGClosure_n_fnotifiers* = 17'i32
|
||||||
bm_TGClosure_n_inotifiers* = 0x07F80000
|
bm_TGClosure_n_inotifiers* = 0x07F80000'i32
|
||||||
bp_TGClosure_n_inotifiers* = 19
|
bp_TGClosure_n_inotifiers* = 19'i32
|
||||||
bm_TGClosure_in_inotify* = 0x08000000
|
bm_TGClosure_in_inotify* = 0x08000000'i32
|
||||||
bp_TGClosure_in_inotify* = 27
|
bp_TGClosure_in_inotify* = 27'i32
|
||||||
bm_TGClosure_floating* = 0x10000000
|
bm_TGClosure_floating* = 0x10000000'i32
|
||||||
bp_TGClosure_floating* = 28
|
bp_TGClosure_floating* = 28'i32
|
||||||
bm_TGClosure_derivative_flag* = 0x20000000
|
bm_TGClosure_derivative_flag* = 0x20000000'i32
|
||||||
bp_TGClosure_derivative_flag* = 29
|
bp_TGClosure_derivative_flag* = 29'i32
|
||||||
bm_TGClosure_in_marshal* = 0x40000000
|
bm_TGClosure_in_marshal* = 0x40000000'i32
|
||||||
bp_TGClosure_in_marshal* = 30
|
bp_TGClosure_in_marshal* = 30'i32
|
||||||
bm_TGClosure_is_invalid* = 0x80000000
|
bm_TGClosure_is_invalid* = 0x80000000'i32
|
||||||
bp_TGClosure_is_invalid* = 31
|
bp_TGClosure_is_invalid* = 31'i32
|
||||||
|
|
||||||
proc ref_count*(a: var TGClosure): guint
|
proc ref_count*(a: var TGClosure): guint
|
||||||
proc set_ref_count*(a: var TGClosure, ref_count: guint)
|
proc set_ref_count*(a: var TGClosure, ref_count: guint)
|
||||||
|
|
@ -2061,16 +2061,16 @@ type
|
||||||
TGHookFlagMask* = int
|
TGHookFlagMask* = int
|
||||||
|
|
||||||
const
|
const
|
||||||
G_HOOK_FLAG_ACTIVE* = 1 shl 0
|
G_HOOK_FLAG_ACTIVE* = 1'i32 shl 0'i32
|
||||||
G_HOOK_FLAG_IN_CALL* = 1 shl 1
|
G_HOOK_FLAG_IN_CALL* = 1'i32 shl 1'i32
|
||||||
G_HOOK_FLAG_MASK* = 0x0000000F
|
G_HOOK_FLAG_MASK* = 0x0000000F'i32
|
||||||
|
|
||||||
const
|
const
|
||||||
G_HOOK_FLAG_USER_SHIFT* = 4
|
G_HOOK_FLAG_USER_SHIFT* = 4'i32
|
||||||
bm_TGHookList_hook_size* = 0x0000FFFF
|
bm_TGHookList_hook_size* = 0x0000FFFF'i32
|
||||||
bp_TGHookList_hook_size* = 0
|
bp_TGHookList_hook_size* = 0'i32
|
||||||
bm_TGHookList_is_setup* = 0x00010000
|
bm_TGHookList_is_setup* = 0x00010000'i32
|
||||||
bp_TGHookList_is_setup* = 16
|
bp_TGHookList_is_setup* = 16'i32
|
||||||
|
|
||||||
proc TGHookList_hook_size*(a: var TGHookList): guint
|
proc TGHookList_hook_size*(a: var TGHookList): guint
|
||||||
proc TGHookList_set_hook_size*(a: var TGHookList, `hook_size`: guint)
|
proc TGHookList_set_hook_size*(a: var TGHookList, `hook_size`: guint)
|
||||||
|
|
@ -2502,18 +2502,18 @@ type
|
||||||
|
|
||||||
|
|
||||||
const
|
const
|
||||||
bm_TGIOChannel_use_buffer* = 0x00000001
|
bm_TGIOChannel_use_buffer* = 0x00000001'i16
|
||||||
bp_TGIOChannel_use_buffer* = 0
|
bp_TGIOChannel_use_buffer* = 0'i16
|
||||||
bm_TGIOChannel_do_encode* = 0x00000002
|
bm_TGIOChannel_do_encode* = 0x00000002'i16
|
||||||
bp_TGIOChannel_do_encode* = 1
|
bp_TGIOChannel_do_encode* = 1'i16
|
||||||
bm_TGIOChannel_close_on_unref* = 0x00000004
|
bm_TGIOChannel_close_on_unref* = 0x00000004'i16
|
||||||
bp_TGIOChannel_close_on_unref* = 2
|
bp_TGIOChannel_close_on_unref* = 2'i16
|
||||||
bm_TGIOChannel_is_readable* = 0x00000008
|
bm_TGIOChannel_is_readable* = 0x00000008'i16
|
||||||
bp_TGIOChannel_is_readable* = 3
|
bp_TGIOChannel_is_readable* = 3'i16
|
||||||
bm_TGIOChannel_is_writeable* = 0x00000010
|
bm_TGIOChannel_is_writeable* = 0x00000010'i16
|
||||||
bp_TGIOChannel_is_writeable* = 4
|
bp_TGIOChannel_is_writeable* = 4'i16
|
||||||
bm_TGIOChannel_is_seekable* = 0x00000020
|
bm_TGIOChannel_is_seekable* = 0x00000020'i16
|
||||||
bp_TGIOChannel_is_seekable* = 5
|
bp_TGIOChannel_is_seekable* = 5'i16
|
||||||
|
|
||||||
proc TGIOChannel_use_buffer*(a: var TGIOChannel): guint
|
proc TGIOChannel_use_buffer*(a: var TGIOChannel): guint
|
||||||
proc TGIOChannel_set_use_buffer*(a: var TGIOChannel, `use_buffer`: guint)
|
proc TGIOChannel_set_use_buffer*(a: var TGIOChannel, `use_buffer`: guint)
|
||||||
|
|
@ -3046,48 +3046,48 @@ const
|
||||||
G_CSET_DIGITS* = "0123456789"
|
G_CSET_DIGITS* = "0123456789"
|
||||||
|
|
||||||
const
|
const
|
||||||
bm_TGScannerConfig_case_sensitive* = 0x00000001
|
bm_TGScannerConfig_case_sensitive* = 0x00000001'i32
|
||||||
bp_TGScannerConfig_case_sensitive* = 0
|
bp_TGScannerConfig_case_sensitive* = 0'i32
|
||||||
bm_TGScannerConfig_skip_comment_multi* = 0x00000002
|
bm_TGScannerConfig_skip_comment_multi* = 0x00000002'i32
|
||||||
bp_TGScannerConfig_skip_comment_multi* = 1
|
bp_TGScannerConfig_skip_comment_multi* = 1'i32
|
||||||
bm_TGScannerConfig_skip_comment_single* = 0x00000004
|
bm_TGScannerConfig_skip_comment_single* = 0x00000004'i32
|
||||||
bp_TGScannerConfig_skip_comment_single* = 2
|
bp_TGScannerConfig_skip_comment_single* = 2'i32
|
||||||
bm_TGScannerConfig_scan_comment_multi* = 0x00000008
|
bm_TGScannerConfig_scan_comment_multi* = 0x00000008'i32
|
||||||
bp_TGScannerConfig_scan_comment_multi* = 3
|
bp_TGScannerConfig_scan_comment_multi* = 3'i32
|
||||||
bm_TGScannerConfig_scan_identifier* = 0x00000010
|
bm_TGScannerConfig_scan_identifier* = 0x00000010'i32
|
||||||
bp_TGScannerConfig_scan_identifier* = 4
|
bp_TGScannerConfig_scan_identifier* = 4'i32
|
||||||
bm_TGScannerConfig_scan_identifier_1char* = 0x00000020
|
bm_TGScannerConfig_scan_identifier_1char* = 0x00000020'i32
|
||||||
bp_TGScannerConfig_scan_identifier_1char* = 5
|
bp_TGScannerConfig_scan_identifier_1char* = 5'i32
|
||||||
bm_TGScannerConfig_scan_identifier_NULL* = 0x00000040
|
bm_TGScannerConfig_scan_identifier_NULL* = 0x00000040'i32
|
||||||
bp_TGScannerConfig_scan_identifier_NULL* = 6
|
bp_TGScannerConfig_scan_identifier_NULL* = 6'i32
|
||||||
bm_TGScannerConfig_scan_symbols* = 0x00000080
|
bm_TGScannerConfig_scan_symbols* = 0x00000080'i32
|
||||||
bp_TGScannerConfig_scan_symbols* = 7
|
bp_TGScannerConfig_scan_symbols* = 7'i32
|
||||||
bm_TGScannerConfig_scan_binary* = 0x00000100
|
bm_TGScannerConfig_scan_binary* = 0x00000100'i32
|
||||||
bp_TGScannerConfig_scan_binary* = 8
|
bp_TGScannerConfig_scan_binary* = 8'i32
|
||||||
bm_TGScannerConfig_scan_octal* = 0x00000200
|
bm_TGScannerConfig_scan_octal* = 0x00000200'i32
|
||||||
bp_TGScannerConfig_scan_octal* = 9
|
bp_TGScannerConfig_scan_octal* = 9'i32
|
||||||
bm_TGScannerConfig_scan_float* = 0x00000400
|
bm_TGScannerConfig_scan_float* = 0x00000400'i32
|
||||||
bp_TGScannerConfig_scan_float* = 10
|
bp_TGScannerConfig_scan_float* = 10'i32
|
||||||
bm_TGScannerConfig_scan_hex* = 0x00000800
|
bm_TGScannerConfig_scan_hex* = 0x00000800'i32
|
||||||
bp_TGScannerConfig_scan_hex* = 11
|
bp_TGScannerConfig_scan_hex* = 11'i32
|
||||||
bm_TGScannerConfig_scan_hex_dollar* = 0x00001000
|
bm_TGScannerConfig_scan_hex_dollar* = 0x00001000'i32
|
||||||
bp_TGScannerConfig_scan_hex_dollar* = 12
|
bp_TGScannerConfig_scan_hex_dollar* = 12'i32
|
||||||
bm_TGScannerConfig_scan_string_sq* = 0x00002000
|
bm_TGScannerConfig_scan_string_sq* = 0x00002000'i32
|
||||||
bp_TGScannerConfig_scan_string_sq* = 13
|
bp_TGScannerConfig_scan_string_sq* = 13'i32
|
||||||
bm_TGScannerConfig_scan_string_dq* = 0x00004000
|
bm_TGScannerConfig_scan_string_dq* = 0x00004000'i32
|
||||||
bp_TGScannerConfig_scan_string_dq* = 14
|
bp_TGScannerConfig_scan_string_dq* = 14'i32
|
||||||
bm_TGScannerConfig_numbers_2_int* = 0x00008000
|
bm_TGScannerConfig_numbers_2_int* = 0x00008000'i32
|
||||||
bp_TGScannerConfig_numbers_2_int* = 15
|
bp_TGScannerConfig_numbers_2_int* = 15'i32
|
||||||
bm_TGScannerConfig_int_2_float* = 0x00010000
|
bm_TGScannerConfig_int_2_float* = 0x00010000'i32
|
||||||
bp_TGScannerConfig_int_2_float* = 16
|
bp_TGScannerConfig_int_2_float* = 16'i32
|
||||||
bm_TGScannerConfig_identifier_2_string* = 0x00020000
|
bm_TGScannerConfig_identifier_2_string* = 0x00020000'i32
|
||||||
bp_TGScannerConfig_identifier_2_string* = 17
|
bp_TGScannerConfig_identifier_2_string* = 17'i32
|
||||||
bm_TGScannerConfig_char_2_token* = 0x00040000
|
bm_TGScannerConfig_char_2_token* = 0x00040000'i32
|
||||||
bp_TGScannerConfig_char_2_token* = 18
|
bp_TGScannerConfig_char_2_token* = 18'i32
|
||||||
bm_TGScannerConfig_symbol_2_token* = 0x00080000
|
bm_TGScannerConfig_symbol_2_token* = 0x00080000'i32
|
||||||
bp_TGScannerConfig_symbol_2_token* = 19
|
bp_TGScannerConfig_symbol_2_token* = 19'i32
|
||||||
bm_TGScannerConfig_scope_0_fallback* = 0x00100000
|
bm_TGScannerConfig_scope_0_fallback* = 0x00100000'i32
|
||||||
bp_TGScannerConfig_scope_0_fallback* = 20
|
bp_TGScannerConfig_scope_0_fallback* = 20'i32
|
||||||
|
|
||||||
proc TGScannerConfig_case_sensitive*(a: var TGScannerConfig): guint
|
proc TGScannerConfig_case_sensitive*(a: var TGScannerConfig): guint
|
||||||
proc TGScannerConfig_set_case_sensitive*(a: var TGScannerConfig,
|
proc TGScannerConfig_set_case_sensitive*(a: var TGScannerConfig,
|
||||||
|
|
@ -3439,19 +3439,21 @@ proc g_cclosure_marshal_BOOL__FLAGS*(closure: PGClosure, return_value: PGValue,
|
||||||
marshal_data: GPointer){.cdecl,
|
marshal_data: GPointer){.cdecl,
|
||||||
dynlib: gliblib, importc: "g_cclosure_marshal_BOOLEAN__FLAGS".}
|
dynlib: gliblib, importc: "g_cclosure_marshal_BOOLEAN__FLAGS".}
|
||||||
proc GUINT16_SWAP_LE_BE_CONSTANT*(val: guint16): guint16 =
|
proc GUINT16_SWAP_LE_BE_CONSTANT*(val: guint16): guint16 =
|
||||||
Result = ((val and 0x000000FF) shl 8) or ((val and 0x0000FF00) shr 8)
|
Result = ((val and 0x00FF'i16) shl 8'i16) or ((val and 0xFF00'i16) shr 8'i16)
|
||||||
|
|
||||||
proc GUINT32_SWAP_LE_BE_CONSTANT*(val: guint32): guint32 =
|
proc GUINT32_SWAP_LE_BE_CONSTANT*(val: guint32): guint32 =
|
||||||
Result = ((val and 0x000000FF) shl 24) or ((val and 0x0000FF00) shl 8) or
|
Result = ((val and 0x000000FF'i32) shl 24'i32) or ((val and 0x0000FF00'i32) shl 8'i32) or
|
||||||
((val and 0x00FF0000) shr 8) or ((val and 0xFF000000) shr 24)
|
((val and 0x00FF0000'i32) shr 8'i32) or ((val and 0xFF000000'i32) shr 24'i32)
|
||||||
|
|
||||||
proc GUINT_TO_POINTER*(i: guint): pointer =
|
proc GUINT_TO_POINTER*(i: guint): pointer =
|
||||||
Result = cast[Pointer](TAddress(i))
|
Result = cast[Pointer](TAddress(i))
|
||||||
|
|
||||||
type
|
|
||||||
PGArray = pointer
|
|
||||||
|
|
||||||
when false:
|
when false:
|
||||||
|
|
||||||
|
type
|
||||||
|
PGArray* = pointer
|
||||||
|
|
||||||
proc g_array_append_val*(a: PGArray, v: gpointer): PGArray =
|
proc g_array_append_val*(a: PGArray, v: gpointer): PGArray =
|
||||||
result = g_array_append_vals(a, addr(v), 1)
|
result = g_array_append_vals(a, addr(v), 1)
|
||||||
|
|
||||||
|
|
@ -3678,17 +3680,17 @@ proc G_HOOK_FLAGS*(hook: PGHook): guint =
|
||||||
result = hook.flags
|
result = hook.flags
|
||||||
|
|
||||||
proc G_HOOK_ACTIVE*(hook: PGHook): bool =
|
proc G_HOOK_ACTIVE*(hook: PGHook): bool =
|
||||||
result = (hook.flags and G_HOOK_FLAG_ACTIVE) != 0
|
result = (hook.flags and G_HOOK_FLAG_ACTIVE) != 0'i32
|
||||||
|
|
||||||
proc G_HOOK_IN_CALL*(hook: PGHook): bool =
|
proc G_HOOK_IN_CALL*(hook: PGHook): bool =
|
||||||
result = (hook.flags and G_HOOK_FLAG_IN_CALL) != 0
|
result = (hook.flags and G_HOOK_FLAG_IN_CALL) != 0'i32
|
||||||
|
|
||||||
proc G_HOOK_IS_VALID*(hook: PGHook): bool =
|
proc G_HOOK_IS_VALID*(hook: PGHook): bool =
|
||||||
result = (hook.hook_id != 0) and G_HOOK_ACTIVE(hook)
|
result = (hook.hook_id != 0) and G_HOOK_ACTIVE(hook)
|
||||||
|
|
||||||
proc G_HOOK_IS_UNLINKED*(hook: PGHook): bool =
|
proc G_HOOK_IS_UNLINKED*(hook: PGHook): bool =
|
||||||
result = (hook.next == nil) and (hook.prev == nil) and
|
result = (hook.next == nil) and (hook.prev == nil) and
|
||||||
(hook.hook_id == 0) and (hook.ref_count == 0)
|
(hook.hook_id == 0) and (hook.ref_count == 0'i32)
|
||||||
|
|
||||||
proc g_hook_append*(hook_list: PGHookList, hook: PGHook) =
|
proc g_hook_append*(hook_list: PGHookList, hook: PGHook) =
|
||||||
g_hook_insert_before(hook_list, nil, hook)
|
g_hook_insert_before(hook_list, nil, hook)
|
||||||
|
|
@ -3702,7 +3704,7 @@ proc TGIOChannel_use_buffer*(a: var TGIOChannel): guint =
|
||||||
|
|
||||||
proc TGIOChannel_set_use_buffer*(a: var TGIOChannel, `use_buffer`: guint) =
|
proc TGIOChannel_set_use_buffer*(a: var TGIOChannel, `use_buffer`: guint) =
|
||||||
a.flag0 = a.flag0 or
|
a.flag0 = a.flag0 or
|
||||||
((`use_buffer` shl bp_TGIOChannel_use_buffer) and
|
(int16(`use_buffer` shl bp_TGIOChannel_use_buffer) and
|
||||||
bm_TGIOChannel_use_buffer)
|
bm_TGIOChannel_use_buffer)
|
||||||
|
|
||||||
proc TGIOChannel_do_encode*(a: var TGIOChannel): guint =
|
proc TGIOChannel_do_encode*(a: var TGIOChannel): guint =
|
||||||
|
|
@ -3711,7 +3713,7 @@ proc TGIOChannel_do_encode*(a: var TGIOChannel): guint =
|
||||||
|
|
||||||
proc TGIOChannel_set_do_encode*(a: var TGIOChannel, `do_encode`: guint) =
|
proc TGIOChannel_set_do_encode*(a: var TGIOChannel, `do_encode`: guint) =
|
||||||
a.flag0 = a.flag0 or
|
a.flag0 = a.flag0 or
|
||||||
((`do_encode` shl bp_TGIOChannel_do_encode) and
|
(int16(`do_encode` shl bp_TGIOChannel_do_encode) and
|
||||||
bm_TGIOChannel_do_encode)
|
bm_TGIOChannel_do_encode)
|
||||||
|
|
||||||
proc TGIOChannel_close_on_unref*(a: var TGIOChannel): guint =
|
proc TGIOChannel_close_on_unref*(a: var TGIOChannel): guint =
|
||||||
|
|
@ -3720,7 +3722,7 @@ proc TGIOChannel_close_on_unref*(a: var TGIOChannel): guint =
|
||||||
|
|
||||||
proc TGIOChannel_set_close_on_unref*(a: var TGIOChannel, `close_on_unref`: guint) =
|
proc TGIOChannel_set_close_on_unref*(a: var TGIOChannel, `close_on_unref`: guint) =
|
||||||
a.flag0 = a.flag0 or
|
a.flag0 = a.flag0 or
|
||||||
((`close_on_unref` shl bp_TGIOChannel_close_on_unref) and
|
(int16(`close_on_unref` shl bp_TGIOChannel_close_on_unref) and
|
||||||
bm_TGIOChannel_close_on_unref)
|
bm_TGIOChannel_close_on_unref)
|
||||||
|
|
||||||
proc TGIOChannel_is_readable*(a: var TGIOChannel): guint =
|
proc TGIOChannel_is_readable*(a: var TGIOChannel): guint =
|
||||||
|
|
@ -3729,7 +3731,7 @@ proc TGIOChannel_is_readable*(a: var TGIOChannel): guint =
|
||||||
|
|
||||||
proc TGIOChannel_set_is_readable*(a: var TGIOChannel, `is_readable`: guint) =
|
proc TGIOChannel_set_is_readable*(a: var TGIOChannel, `is_readable`: guint) =
|
||||||
a.flag0 = a.flag0 or
|
a.flag0 = a.flag0 or
|
||||||
((`is_readable` shl bp_TGIOChannel_is_readable) and
|
(int16(`is_readable` shl bp_TGIOChannel_is_readable) and
|
||||||
bm_TGIOChannel_is_readable)
|
bm_TGIOChannel_is_readable)
|
||||||
|
|
||||||
proc TGIOChannel_is_writeable*(a: var TGIOChannel): guint =
|
proc TGIOChannel_is_writeable*(a: var TGIOChannel): guint =
|
||||||
|
|
@ -3738,7 +3740,7 @@ proc TGIOChannel_is_writeable*(a: var TGIOChannel): guint =
|
||||||
|
|
||||||
proc TGIOChannel_set_is_writeable*(a: var TGIOChannel, `is_writeable`: guint) =
|
proc TGIOChannel_set_is_writeable*(a: var TGIOChannel, `is_writeable`: guint) =
|
||||||
a.flag0 = a.flag0 or
|
a.flag0 = a.flag0 or
|
||||||
((`is_writeable` shl bp_TGIOChannel_is_writeable) and
|
(int16(`is_writeable` shl bp_TGIOChannel_is_writeable) and
|
||||||
bm_TGIOChannel_is_writeable)
|
bm_TGIOChannel_is_writeable)
|
||||||
|
|
||||||
proc TGIOChannel_is_seekable*(a: var TGIOChannel): guint =
|
proc TGIOChannel_is_seekable*(a: var TGIOChannel): guint =
|
||||||
|
|
@ -3747,7 +3749,7 @@ proc TGIOChannel_is_seekable*(a: var TGIOChannel): guint =
|
||||||
|
|
||||||
proc TGIOChannel_set_is_seekable*(a: var TGIOChannel, `is_seekable`: guint) =
|
proc TGIOChannel_set_is_seekable*(a: var TGIOChannel, `is_seekable`: guint) =
|
||||||
a.flag0 = a.flag0 or
|
a.flag0 = a.flag0 or
|
||||||
((`is_seekable` shl bp_TGIOChannel_is_seekable) and
|
(int16(`is_seekable` shl bp_TGIOChannel_is_seekable) and
|
||||||
bm_TGIOChannel_is_seekable)
|
bm_TGIOChannel_is_seekable)
|
||||||
|
|
||||||
proc g_utf8_next_char*(p: pguchar): pguchar =
|
proc g_utf8_next_char*(p: pguchar): pguchar =
|
||||||
|
|
@ -3816,10 +3818,10 @@ proc g_node_first_child*(node: PGNode): PGNode =
|
||||||
result = nil
|
result = nil
|
||||||
|
|
||||||
proc g_rand_boolean*(rand: PGRand): gboolean =
|
proc g_rand_boolean*(rand: PGRand): gboolean =
|
||||||
result = ((g_rand_int(rand)) and (1 shl 15)) != 0
|
result = (int(g_rand_int(rand)) and (1 shl 15)) != 0
|
||||||
|
|
||||||
proc g_random_boolean*(): gboolean =
|
proc g_random_boolean*(): gboolean =
|
||||||
result = (g_random_int() and (1 shl 15)) != 0
|
result = (int(g_random_int()) and (1 shl 15)) != 0
|
||||||
|
|
||||||
proc TGScannerConfig_case_sensitive*(a: var TGScannerConfig): guint =
|
proc TGScannerConfig_case_sensitive*(a: var TGScannerConfig): guint =
|
||||||
result = (a.flag0 and bm_TGScannerConfig_case_sensitive) shr
|
result = (a.flag0 and bm_TGScannerConfig_case_sensitive) shr
|
||||||
|
|
@ -4077,7 +4079,7 @@ when false:
|
||||||
proc g_strstrip*(str: cstring): cstring =
|
proc g_strstrip*(str: cstring): cstring =
|
||||||
result = g_strchomp(g_strchug(str))
|
result = g_strchomp(g_strchug(str))
|
||||||
|
|
||||||
proc G_TYPE_MAKE_FUNDAMENTAL*(x: int32): GType =
|
proc G_TYPE_MAKE_FUNDAMENTAL*(x: int): GType =
|
||||||
result = GType(x shl G_TYPE_FUNDAMENTAL_SHIFT)
|
result = GType(x shl G_TYPE_FUNDAMENTAL_SHIFT)
|
||||||
|
|
||||||
proc G_TYPE_IS_FUNDAMENTAL*(theType: GType): bool =
|
proc G_TYPE_IS_FUNDAMENTAL*(theType: GType): bool =
|
||||||
|
|
@ -4202,7 +4204,7 @@ proc G_CLOSURE_NEEDS_MARSHAL*(closure: Pointer): bool =
|
||||||
result = cast[PGClosure](closure).marshal == nil
|
result = cast[PGClosure](closure).marshal == nil
|
||||||
|
|
||||||
proc G_CLOSURE_N_NOTIFIERS*(cl: PGClosure): int32 =
|
proc G_CLOSURE_N_NOTIFIERS*(cl: PGClosure): int32 =
|
||||||
result = ((meta_marshal(cl) + ((n_guards(cl)) shl 1)) + (n_fnotifiers(cl))) +
|
result = ((meta_marshal(cl) + ((n_guards(cl)) shl 1'i32)) + (n_fnotifiers(cl))) +
|
||||||
(n_inotifiers(cl))
|
(n_inotifiers(cl))
|
||||||
|
|
||||||
proc G_CCLOSURE_SWAP_DATA*(cclosure: PGClosure): int32 =
|
proc G_CCLOSURE_SWAP_DATA*(cclosure: PGClosure): int32 =
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -2,7 +2,6 @@ import
|
||||||
glib2, gtk2
|
glib2, gtk2
|
||||||
|
|
||||||
when defined(win32):
|
when defined(win32):
|
||||||
{.define: gtkwin.}
|
|
||||||
const
|
const
|
||||||
LibGladeLib = "libglade-2.0-0.dll"
|
LibGladeLib = "libglade-2.0-0.dll"
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
import
|
import
|
||||||
glib2
|
glib2
|
||||||
|
|
||||||
{.define: PANGO_ENABLE_ENGINE.}
|
|
||||||
{.define: PANGO_ENABLE_BACKEND.}
|
|
||||||
when defined(win32):
|
when defined(win32):
|
||||||
{.define: pangowin.}
|
|
||||||
const
|
const
|
||||||
pangolib* = "libpango-1.0-0.dll"
|
pangolib* = "libpango-1.0-0.dll"
|
||||||
else:
|
else:
|
||||||
|
|
@ -381,26 +378,26 @@ proc pango_parse_markup*(markup_text: cstring, length: int32,
|
||||||
text: PPchar, accel_char: Pgunichar, error: pointer): gboolean{.
|
text: PPchar, accel_char: Pgunichar, error: pointer): gboolean{.
|
||||||
cdecl, dynlib: pangolib, importc: "pango_parse_markup".}
|
cdecl, dynlib: pangolib, importc: "pango_parse_markup".}
|
||||||
const
|
const
|
||||||
bm_TPangoLogAttr_is_line_break* = 0x00000001
|
bm_TPangoLogAttr_is_line_break* = 0x00000001'i16
|
||||||
bp_TPangoLogAttr_is_line_break* = 0
|
bp_TPangoLogAttr_is_line_break* = 0'i16
|
||||||
bm_TPangoLogAttr_is_mandatory_break* = 0x00000002
|
bm_TPangoLogAttr_is_mandatory_break* = 0x00000002'i16
|
||||||
bp_TPangoLogAttr_is_mandatory_break* = 1
|
bp_TPangoLogAttr_is_mandatory_break* = 1'i16
|
||||||
bm_TPangoLogAttr_is_char_break* = 0x00000004
|
bm_TPangoLogAttr_is_char_break* = 0x00000004'i16
|
||||||
bp_TPangoLogAttr_is_char_break* = 2
|
bp_TPangoLogAttr_is_char_break* = 2'i16
|
||||||
bm_TPangoLogAttr_is_white* = 0x00000008
|
bm_TPangoLogAttr_is_white* = 0x00000008'i16
|
||||||
bp_TPangoLogAttr_is_white* = 3
|
bp_TPangoLogAttr_is_white* = 3'i16
|
||||||
bm_TPangoLogAttr_is_cursor_position* = 0x00000010
|
bm_TPangoLogAttr_is_cursor_position* = 0x00000010'i16
|
||||||
bp_TPangoLogAttr_is_cursor_position* = 4
|
bp_TPangoLogAttr_is_cursor_position* = 4'i16
|
||||||
bm_TPangoLogAttr_is_word_start* = 0x00000020
|
bm_TPangoLogAttr_is_word_start* = 0x00000020'i16
|
||||||
bp_TPangoLogAttr_is_word_start* = 5
|
bp_TPangoLogAttr_is_word_start* = 5'i16
|
||||||
bm_TPangoLogAttr_is_word_end* = 0x00000040
|
bm_TPangoLogAttr_is_word_end* = 0x00000040'i16
|
||||||
bp_TPangoLogAttr_is_word_end* = 6
|
bp_TPangoLogAttr_is_word_end* = 6'i16
|
||||||
bm_TPangoLogAttr_is_sentence_boundary* = 0x00000080
|
bm_TPangoLogAttr_is_sentence_boundary* = 0x00000080'i16
|
||||||
bp_TPangoLogAttr_is_sentence_boundary* = 7
|
bp_TPangoLogAttr_is_sentence_boundary* = 7'i16
|
||||||
bm_TPangoLogAttr_is_sentence_start* = 0x00000100
|
bm_TPangoLogAttr_is_sentence_start* = 0x00000100'i16
|
||||||
bp_TPangoLogAttr_is_sentence_start* = 8
|
bp_TPangoLogAttr_is_sentence_start* = 8'i16
|
||||||
bm_TPangoLogAttr_is_sentence_end* = 0x00000200
|
bm_TPangoLogAttr_is_sentence_end* = 0x00000200'i16
|
||||||
bp_TPangoLogAttr_is_sentence_end* = 9
|
bp_TPangoLogAttr_is_sentence_end* = 9'i16
|
||||||
|
|
||||||
proc is_line_break*(a: var TPangoLogAttr): guint
|
proc is_line_break*(a: var TPangoLogAttr): guint
|
||||||
proc set_is_line_break*(a: var TPangoLogAttr, `is_line_break`: guint)
|
proc set_is_line_break*(a: var TPangoLogAttr, `is_line_break`: guint)
|
||||||
|
|
@ -687,8 +684,8 @@ proc pango_font_map_list_families*(fontmap: PPangoFontMap,
|
||||||
families: var openarray[ptr PPangoFontFamily]){.cdecl,
|
families: var openarray[ptr PPangoFontFamily]){.cdecl,
|
||||||
dynlib: pangolib, importc: "pango_font_map_list_families".}
|
dynlib: pangolib, importc: "pango_font_map_list_families".}
|
||||||
const
|
const
|
||||||
bm_TPangoGlyphVisAttr_is_cluster_start* = 0x00000001
|
bm_TPangoGlyphVisAttr_is_cluster_start* = 0x00000001'i16
|
||||||
bp_TPangoGlyphVisAttr_is_cluster_start* = 0
|
bp_TPangoGlyphVisAttr_is_cluster_start* = 0'i16
|
||||||
|
|
||||||
proc is_cluster_start*(a: var TPangoGlyphVisAttr): guint
|
proc is_cluster_start*(a: var TPangoGlyphVisAttr): guint
|
||||||
proc set_is_cluster_start*(a: var TPangoGlyphVisAttr, `is_cluster_start`: guint)
|
proc set_is_cluster_start*(a: var TPangoGlyphVisAttr, `is_cluster_start`: guint)
|
||||||
|
|
@ -931,7 +928,7 @@ proc PANGO_LBEARING*(rect: TPangoRectangle): int32 =
|
||||||
result = rect.x
|
result = rect.x
|
||||||
|
|
||||||
proc PANGO_RBEARING*(rect: TPangoRectangle): int32 =
|
proc PANGO_RBEARING*(rect: TPangoRectangle): int32 =
|
||||||
result = int(rect.x) + (rect.width)
|
result = (rect.x) + (rect.width)
|
||||||
|
|
||||||
proc PANGO_TYPE_LANGUAGE*(): GType =
|
proc PANGO_TYPE_LANGUAGE*(): GType =
|
||||||
result = pango_language_get_type()
|
result = pango_language_get_type()
|
||||||
|
|
@ -957,7 +954,7 @@ proc is_line_break*(a: var TPangoLogAttr): guint =
|
||||||
|
|
||||||
proc set_is_line_break*(a: var TPangoLogAttr, `is_line_break`: guint) =
|
proc set_is_line_break*(a: var TPangoLogAttr, `is_line_break`: guint) =
|
||||||
a.flag0 = a.flag0 or
|
a.flag0 = a.flag0 or
|
||||||
((`is_line_break` shl bp_TPangoLogAttr_is_line_break) and
|
(int16(`is_line_break` shl bp_TPangoLogAttr_is_line_break) and
|
||||||
bm_TPangoLogAttr_is_line_break)
|
bm_TPangoLogAttr_is_line_break)
|
||||||
|
|
||||||
proc is_mandatory_break*(a: var TPangoLogAttr): guint =
|
proc is_mandatory_break*(a: var TPangoLogAttr): guint =
|
||||||
|
|
@ -966,7 +963,7 @@ proc is_mandatory_break*(a: var TPangoLogAttr): guint =
|
||||||
|
|
||||||
proc set_is_mandatory_break*(a: var TPangoLogAttr, `is_mandatory_break`: guint) =
|
proc set_is_mandatory_break*(a: var TPangoLogAttr, `is_mandatory_break`: guint) =
|
||||||
a.flag0 = a.flag0 or
|
a.flag0 = a.flag0 or
|
||||||
((`is_mandatory_break` shl bp_TPangoLogAttr_is_mandatory_break) and
|
(int16(`is_mandatory_break` shl bp_TPangoLogAttr_is_mandatory_break) and
|
||||||
bm_TPangoLogAttr_is_mandatory_break)
|
bm_TPangoLogAttr_is_mandatory_break)
|
||||||
|
|
||||||
proc is_char_break*(a: var TPangoLogAttr): guint =
|
proc is_char_break*(a: var TPangoLogAttr): guint =
|
||||||
|
|
@ -975,7 +972,7 @@ proc is_char_break*(a: var TPangoLogAttr): guint =
|
||||||
|
|
||||||
proc set_is_char_break*(a: var TPangoLogAttr, `is_char_break`: guint) =
|
proc set_is_char_break*(a: var TPangoLogAttr, `is_char_break`: guint) =
|
||||||
a.flag0 = a.flag0 or
|
a.flag0 = a.flag0 or
|
||||||
((`is_char_break` shl bp_TPangoLogAttr_is_char_break) and
|
(int16(`is_char_break` shl bp_TPangoLogAttr_is_char_break) and
|
||||||
bm_TPangoLogAttr_is_char_break)
|
bm_TPangoLogAttr_is_char_break)
|
||||||
|
|
||||||
proc is_white*(a: var TPangoLogAttr): guint =
|
proc is_white*(a: var TPangoLogAttr): guint =
|
||||||
|
|
@ -984,7 +981,7 @@ proc is_white*(a: var TPangoLogAttr): guint =
|
||||||
|
|
||||||
proc set_is_white*(a: var TPangoLogAttr, `is_white`: guint) =
|
proc set_is_white*(a: var TPangoLogAttr, `is_white`: guint) =
|
||||||
a.flag0 = a.flag0 or
|
a.flag0 = a.flag0 or
|
||||||
((`is_white` shl bp_TPangoLogAttr_is_white) and
|
(int16(`is_white` shl bp_TPangoLogAttr_is_white) and
|
||||||
bm_TPangoLogAttr_is_white)
|
bm_TPangoLogAttr_is_white)
|
||||||
|
|
||||||
proc is_cursor_position*(a: var TPangoLogAttr): guint =
|
proc is_cursor_position*(a: var TPangoLogAttr): guint =
|
||||||
|
|
@ -993,7 +990,7 @@ proc is_cursor_position*(a: var TPangoLogAttr): guint =
|
||||||
|
|
||||||
proc set_is_cursor_position*(a: var TPangoLogAttr, `is_cursor_position`: guint) =
|
proc set_is_cursor_position*(a: var TPangoLogAttr, `is_cursor_position`: guint) =
|
||||||
a.flag0 = a.flag0 or
|
a.flag0 = a.flag0 or
|
||||||
((`is_cursor_position` shl bp_TPangoLogAttr_is_cursor_position) and
|
(int16(`is_cursor_position` shl bp_TPangoLogAttr_is_cursor_position) and
|
||||||
bm_TPangoLogAttr_is_cursor_position)
|
bm_TPangoLogAttr_is_cursor_position)
|
||||||
|
|
||||||
proc is_word_start*(a: var TPangoLogAttr): guint =
|
proc is_word_start*(a: var TPangoLogAttr): guint =
|
||||||
|
|
@ -1002,7 +999,7 @@ proc is_word_start*(a: var TPangoLogAttr): guint =
|
||||||
|
|
||||||
proc set_is_word_start*(a: var TPangoLogAttr, `is_word_start`: guint) =
|
proc set_is_word_start*(a: var TPangoLogAttr, `is_word_start`: guint) =
|
||||||
a.flag0 = a.flag0 or
|
a.flag0 = a.flag0 or
|
||||||
((`is_word_start` shl bp_TPangoLogAttr_is_word_start) and
|
(int16(`is_word_start` shl bp_TPangoLogAttr_is_word_start) and
|
||||||
bm_TPangoLogAttr_is_word_start)
|
bm_TPangoLogAttr_is_word_start)
|
||||||
|
|
||||||
proc is_word_end*(a: var TPangoLogAttr): guint =
|
proc is_word_end*(a: var TPangoLogAttr): guint =
|
||||||
|
|
@ -1011,7 +1008,7 @@ proc is_word_end*(a: var TPangoLogAttr): guint =
|
||||||
|
|
||||||
proc set_is_word_end*(a: var TPangoLogAttr, `is_word_end`: guint) =
|
proc set_is_word_end*(a: var TPangoLogAttr, `is_word_end`: guint) =
|
||||||
a.flag0 = a.flag0 or
|
a.flag0 = a.flag0 or
|
||||||
((`is_word_end` shl bp_TPangoLogAttr_is_word_end) and
|
(int16(`is_word_end` shl bp_TPangoLogAttr_is_word_end) and
|
||||||
bm_TPangoLogAttr_is_word_end)
|
bm_TPangoLogAttr_is_word_end)
|
||||||
|
|
||||||
proc is_sentence_boundary*(a: var TPangoLogAttr): guint =
|
proc is_sentence_boundary*(a: var TPangoLogAttr): guint =
|
||||||
|
|
@ -1021,7 +1018,7 @@ proc is_sentence_boundary*(a: var TPangoLogAttr): guint =
|
||||||
proc set_is_sentence_boundary*(a: var TPangoLogAttr,
|
proc set_is_sentence_boundary*(a: var TPangoLogAttr,
|
||||||
`is_sentence_boundary`: guint) =
|
`is_sentence_boundary`: guint) =
|
||||||
a.flag0 = a.flag0 or
|
a.flag0 = a.flag0 or
|
||||||
((`is_sentence_boundary` shl bp_TPangoLogAttr_is_sentence_boundary) and
|
(int16(`is_sentence_boundary` shl bp_TPangoLogAttr_is_sentence_boundary) and
|
||||||
bm_TPangoLogAttr_is_sentence_boundary)
|
bm_TPangoLogAttr_is_sentence_boundary)
|
||||||
|
|
||||||
proc is_sentence_start*(a: var TPangoLogAttr): guint =
|
proc is_sentence_start*(a: var TPangoLogAttr): guint =
|
||||||
|
|
@ -1030,7 +1027,7 @@ proc is_sentence_start*(a: var TPangoLogAttr): guint =
|
||||||
|
|
||||||
proc set_is_sentence_start*(a: var TPangoLogAttr, `is_sentence_start`: guint) =
|
proc set_is_sentence_start*(a: var TPangoLogAttr, `is_sentence_start`: guint) =
|
||||||
a.flag0 = a.flag0 or
|
a.flag0 = a.flag0 or
|
||||||
((`is_sentence_start` shl bp_TPangoLogAttr_is_sentence_start) and
|
(int16(`is_sentence_start` shl bp_TPangoLogAttr_is_sentence_start) and
|
||||||
bm_TPangoLogAttr_is_sentence_start)
|
bm_TPangoLogAttr_is_sentence_start)
|
||||||
|
|
||||||
proc is_sentence_end*(a: var TPangoLogAttr): guint =
|
proc is_sentence_end*(a: var TPangoLogAttr): guint =
|
||||||
|
|
@ -1039,7 +1036,7 @@ proc is_sentence_end*(a: var TPangoLogAttr): guint =
|
||||||
|
|
||||||
proc set_is_sentence_end*(a: var TPangoLogAttr, `is_sentence_end`: guint) =
|
proc set_is_sentence_end*(a: var TPangoLogAttr, `is_sentence_end`: guint) =
|
||||||
a.flag0 = a.flag0 or
|
a.flag0 = a.flag0 or
|
||||||
((`is_sentence_end` shl bp_TPangoLogAttr_is_sentence_end) and
|
(int16(`is_sentence_end` shl bp_TPangoLogAttr_is_sentence_end) and
|
||||||
bm_TPangoLogAttr_is_sentence_end)
|
bm_TPangoLogAttr_is_sentence_end)
|
||||||
|
|
||||||
proc PANGO_TYPE_CONTEXT*(): GType =
|
proc PANGO_TYPE_CONTEXT*(): GType =
|
||||||
|
|
@ -1181,7 +1178,7 @@ proc is_cluster_start*(a: var TPangoGlyphVisAttr): guint =
|
||||||
|
|
||||||
proc set_is_cluster_start*(a: var TPangoGlyphVisAttr, `is_cluster_start`: guint) =
|
proc set_is_cluster_start*(a: var TPangoGlyphVisAttr, `is_cluster_start`: guint) =
|
||||||
a.flag0 = a.flag0 or
|
a.flag0 = a.flag0 or
|
||||||
((`is_cluster_start` shl bp_TPangoGlyphVisAttr_is_cluster_start) and
|
(int16(`is_cluster_start` shl bp_TPangoGlyphVisAttr_is_cluster_start) and
|
||||||
bm_TPangoGlyphVisAttr_is_cluster_start)
|
bm_TPangoGlyphVisAttr_is_cluster_start)
|
||||||
|
|
||||||
proc PANGO_TYPE_GLYPH_STRING*(): GType =
|
proc PANGO_TYPE_GLYPH_STRING*(): GType =
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,9 @@ proc pango_scan_string*(pos: PPchar, OutStr: PGString): gboolean{.cdecl,
|
||||||
dynlib: pangolib, importc: "pango_scan_string".}
|
dynlib: pangolib, importc: "pango_scan_string".}
|
||||||
proc pango_scan_int*(pos: PPchar, OutInt: pint32): gboolean{.cdecl,
|
proc pango_scan_int*(pos: PPchar, OutInt: pint32): gboolean{.cdecl,
|
||||||
dynlib: pangolib, importc: "pango_scan_int".}
|
dynlib: pangolib, importc: "pango_scan_int".}
|
||||||
when defined(PANGO_ENABLE_BACKEND):
|
proc pango_config_key_get(key: cstring): cstring{.cdecl, dynlib: pangolib,
|
||||||
proc pango_config_key_get(key: cstring): cstring{.cdecl, dynlib: pangolib,
|
|
||||||
importc: "pango_config_key_get".}
|
importc: "pango_config_key_get".}
|
||||||
proc pango_lookup_aliases(fontname: cstring, families: PPPchar,
|
proc pango_lookup_aliases(fontname: cstring, families: PPPchar,
|
||||||
n_families: pint32){.cdecl, dynlib: pangolib,
|
n_families: pint32){.cdecl, dynlib: pangolib,
|
||||||
importc: "pango_lookup_aliases".}
|
importc: "pango_lookup_aliases".}
|
||||||
proc pango_parse_style*(str: cstring, style: PPangoStyle, warn: gboolean): gboolean{.
|
proc pango_parse_style*(str: cstring, style: PPangoStyle, warn: gboolean): gboolean{.
|
||||||
|
|
@ -32,10 +31,9 @@ proc pango_parse_weight*(str: cstring, weight: PPangoWeight, warn: gboolean): gb
|
||||||
cdecl, dynlib: pangolib, importc: "pango_parse_weight".}
|
cdecl, dynlib: pangolib, importc: "pango_parse_weight".}
|
||||||
proc pango_parse_stretch*(str: cstring, stretch: PPangoStretch, warn: gboolean): gboolean{.
|
proc pango_parse_stretch*(str: cstring, stretch: PPangoStretch, warn: gboolean): gboolean{.
|
||||||
cdecl, dynlib: pangolib, importc: "pango_parse_stretch".}
|
cdecl, dynlib: pangolib, importc: "pango_parse_stretch".}
|
||||||
when defined(PANGO_ENABLE_BACKEND):
|
proc pango_get_sysconf_subdirectory(): cstring{.cdecl, dynlib: pangolib,
|
||||||
proc pango_get_sysconf_subdirectory(): cstring{.cdecl, dynlib: pangolib,
|
|
||||||
importc: "pango_get_sysconf_subdirectory".}
|
importc: "pango_get_sysconf_subdirectory".}
|
||||||
proc pango_get_lib_subdirectory(): cstring{.cdecl, dynlib: pangolib,
|
proc pango_get_lib_subdirectory(): cstring{.cdecl, dynlib: pangolib,
|
||||||
importc: "pango_get_lib_subdirectory".}
|
importc: "pango_get_lib_subdirectory".}
|
||||||
proc pango_log2vis_get_embedding_levels*(str: Pgunichar, len: int32,
|
proc pango_log2vis_get_embedding_levels*(str: Pgunichar, len: int32,
|
||||||
pbase_dir: PPangoDirection, embedding_level_list: Pguint8): gboolean{.cdecl,
|
pbase_dir: PPangoDirection, embedding_level_list: Pguint8): gboolean{.cdecl,
|
||||||
|
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
# Lexer generator for Nimrod
|
|
||||||
# (c) 2008 Andreas Rumpf
|
|
||||||
|
|
||||||
# Stress testing for the macro feature
|
|
||||||
|
|
||||||
# the syntax that should be supported is:
|
|
||||||
|
|
||||||
# template numpostfix =
|
|
||||||
# '\'' & 'F'|'f'|'i'|'I' & "32"|"64"|"8"|"16"
|
|
||||||
# template edigits =
|
|
||||||
# 'e'|'E' & +digits
|
|
||||||
# tokens(
|
|
||||||
# tkIdent: +UniIdentStart & *UniIdentRest,
|
|
||||||
# tkHexNumber: '0' & ('x'|'X') & +hexDigits & ?( numpostfix ),
|
|
||||||
# tkOctNumber: '0' & ('c'|'C') & +octDigits & ?( numpostfix ),
|
|
||||||
# tkBinNumber: '0' & ('b'|'B') & +binDigits & ?( numpostfix ),
|
|
||||||
# tkIntNumber: +digits & ?( numpostfix ),
|
|
||||||
# tkFloatNumber: +digits & ('.' & +digits & ?(edigits) | edigits) & ?(numpostfix),
|
|
||||||
#
|
|
||||||
# )
|
|
||||||
# actions(
|
|
||||||
# tkIdent: lookup
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
|
||||||
# match inputstream
|
|
||||||
# of +('A'..'Z' | '_' | 'a'..'z') *('A'..'Z' | '_' | 'a'..'z' | '0'..'9') :
|
|
||||||
#
|
|
||||||
# x = inputstream[pos..length]
|
|
||||||
# of '0' 'x' +('0'..'9' | 'a'..'f' | '_' | 'A'..'F') :
|
|
||||||
# y = ...
|
|
||||||
|
|
||||||
const
|
|
||||||
AsciiLetter = {'A'..'Z', 'a'..'z'}
|
|
||||||
uniLetter = AsciiLetter + {'\128'..'\255'}
|
|
||||||
digits = {'0'..'9'}
|
|
||||||
hexDigits = {'0'..'9', 'a'..'f', 'A'..'F'}
|
|
||||||
octDigits = {'0'..'7'}
|
|
||||||
binDigits = {'0'..'1'}
|
|
||||||
AsciiIdentStart = AsciiLetter + {'_'}
|
|
||||||
AsciiIdentRest = AsciiIdentStart + Digits
|
|
||||||
UniIdentStart = UniLetter + {'_'}
|
|
||||||
UniIdentRest = UniIdentStart + Digits
|
|
||||||
|
|
||||||
# --> if match(s, +AsciiIdentStart & *AsciiIdentRest):
|
|
||||||
|
|
||||||
# Regular expressions in Nimrod itself!
|
|
||||||
# -------------------------------------
|
|
||||||
#
|
|
||||||
# 'a' -- matches the character a
|
|
||||||
# 'a'..'z' -- range operator '-'
|
|
||||||
# 'A' | 'B' -- alternative operator |
|
|
||||||
# * 'a' -- prefix * is needed
|
|
||||||
# + 'a' -- prefix + is needed
|
|
||||||
# ? 'a' -- prefix ? is needed
|
|
||||||
# *? prefix is needed
|
|
||||||
# +? prefix is needed
|
|
||||||
# letter -- character classes with real names!
|
|
||||||
# letters
|
|
||||||
# white
|
|
||||||
# whites
|
|
||||||
# any -- any character
|
|
||||||
# () -- are Nimrod syntax
|
|
||||||
# ! 'a'-'z'
|
|
||||||
#
|
|
||||||
# -- concatentation via proc call:
|
|
||||||
#
|
|
||||||
# re('A' 'Z' *word )
|
|
||||||
|
|
||||||
macro re(n: expr): expr =
|
|
||||||
|
|
||||||
result = newCall("magic_re", x)
|
|
||||||
|
|
@ -1,124 +0,0 @@
|
||||||
# new implementation of regular expressions
|
|
||||||
|
|
||||||
type
|
|
||||||
TRegexKind = enum
|
|
||||||
regNone,
|
|
||||||
regChar,
|
|
||||||
regSet,
|
|
||||||
regConc,
|
|
||||||
regAlt,
|
|
||||||
regStar,
|
|
||||||
regPlus,
|
|
||||||
regMN,
|
|
||||||
regNewline
|
|
||||||
|
|
||||||
TRegex = object of TObject
|
|
||||||
case kind: TRegexKind
|
|
||||||
of regChar: c: char
|
|
||||||
of regSet: s: ref set[char]
|
|
||||||
else: a, b: PRegEx
|
|
||||||
|
|
||||||
PRegEx* = ref TRegEx
|
|
||||||
|
|
||||||
TRegExFlag* = enum ## Flags concerning the semantics of regular expressions
|
|
||||||
reCaseInsensitive, ## case insensitive match
|
|
||||||
reStyleInsensitive ## style insensitive match
|
|
||||||
|
|
||||||
|
|
||||||
TRegExFlags* = set[TRegExFlag]
|
|
||||||
## Flags concerning the semantics of regular expressions
|
|
||||||
|
|
||||||
proc raiseRegex(msg: string) {.noreturn.} =
|
|
||||||
var e: ref Exception
|
|
||||||
new(e)
|
|
||||||
e.msg = msg
|
|
||||||
raise e
|
|
||||||
|
|
||||||
proc compileAux(i: int, s: string, r: PRegEx): int
|
|
||||||
|
|
||||||
proc compileBackslash(i: int, s: string, r: PRegEx): int =
|
|
||||||
var i = i
|
|
||||||
inc(i)
|
|
||||||
case s[i]
|
|
||||||
of 'A'..'Z':
|
|
||||||
of 'a'..'z':
|
|
||||||
of '0':
|
|
||||||
of '1'..'9':
|
|
||||||
|
|
||||||
else:
|
|
||||||
r.kind = regChar
|
|
||||||
r.c = s[i]
|
|
||||||
inc(i)
|
|
||||||
result = i
|
|
||||||
|
|
||||||
proc compileAtom(i: int, s: string, r: PRegEx): int =
|
|
||||||
var i = i
|
|
||||||
case s[i]
|
|
||||||
of '[':
|
|
||||||
inc(i)
|
|
||||||
var inverse = s[i] == '^'
|
|
||||||
if inverse: inc(i)
|
|
||||||
r.kind = regSet
|
|
||||||
new(r.s)
|
|
||||||
while true:
|
|
||||||
case s[i]
|
|
||||||
of '\\': i = compileBackslash(i, s, r)
|
|
||||||
of ']':
|
|
||||||
inc(i)
|
|
||||||
break
|
|
||||||
of '\0':
|
|
||||||
raiseRegex("']' expected")
|
|
||||||
elif s[i+1] == '-':
|
|
||||||
var x = s[i]
|
|
||||||
inc(i, 2)
|
|
||||||
var y = s[i]
|
|
||||||
inc(i)
|
|
||||||
r.s = r.s + {x..y}
|
|
||||||
else:
|
|
||||||
incl(r.s, s[i])
|
|
||||||
inc(i)
|
|
||||||
if inverse:
|
|
||||||
r.s = {'\0'..'\255'} - r.s
|
|
||||||
of '\\':
|
|
||||||
inc(i)
|
|
||||||
i = compileBackslash(i, s, r)
|
|
||||||
of '.':
|
|
||||||
r.kind = regAny
|
|
||||||
inc(i)
|
|
||||||
of '(':
|
|
||||||
inc(i)
|
|
||||||
i = compileAux(i, s, r)
|
|
||||||
if s[i] = ')': inc(i)
|
|
||||||
else: raiseRegex("')' expected")
|
|
||||||
of '\0': nil # do nothing
|
|
||||||
else:
|
|
||||||
r.kind = regChar
|
|
||||||
r.c = s[i]
|
|
||||||
inc(i)
|
|
||||||
result = i
|
|
||||||
|
|
||||||
proc compilePostfix(i: int, s: string, r: PRegEx): int =
|
|
||||||
var i = compileAtom(i, s, r)
|
|
||||||
var a: PRegEx
|
|
||||||
case s[i]
|
|
||||||
of '*':
|
|
||||||
of '+':
|
|
||||||
of '?':
|
|
||||||
else: nil
|
|
||||||
|
|
||||||
proc compileAux(i: int, s: string, r: PRegEx): int =
|
|
||||||
var i = i
|
|
||||||
i = compileAtom(i, s, r)
|
|
||||||
|
|
||||||
while s[i] != '\0':
|
|
||||||
|
|
||||||
result = i
|
|
||||||
|
|
||||||
proc compile*(regex: string, flags: TRegExFlags = {}): PRegEx =
|
|
||||||
## Compiles the string `regex` that represents a regular expression into
|
|
||||||
## an internal data structure that can be used for matching.
|
|
||||||
new(result)
|
|
||||||
var i = compileAux(0, regex, result)
|
|
||||||
if i < len(regex)-1:
|
|
||||||
# not all characters used for the regular expression?
|
|
||||||
raiseRegEx("invalid regular expression")
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
# This file was created by a complicated procedure which saved me a considerable
|
# This file was created by a complicated procedure which saved me a considerable
|
||||||
# amount of time: the pcre.h header was converted to modpcre.h by hand, so that
|
# amount of time: the pcre.h header was converted to modpcre.h by hand, so that
|
||||||
# h2pas could handle it. Then I used pas2mor to generate a Morpork binding.
|
# h2pas could handle it. Then I used pas2mor to generate a Nimrod binding.
|
||||||
# Unfortunately, I had to fix some things later on; thus don't do all this
|
# Unfortunately, I had to fix some things later on; thus don't do all this
|
||||||
# again! My manual changes will be lost!
|
# again! My manual changes will be lost!
|
||||||
|
|
||||||
|
|
@ -23,12 +23,62 @@
|
||||||
|
|
||||||
type
|
type
|
||||||
Pbyte = ptr byte
|
Pbyte = ptr byte
|
||||||
Pchar = CString
|
PPchar = ptr cstring
|
||||||
PPchar = ptr PChar
|
|
||||||
Pint = ptr cint
|
Pint = ptr cint
|
||||||
Ppcre* = ptr TPcre
|
Ppcre* = ptr TPcre
|
||||||
Ppcre_callout_block = ptr tpcre_callout_block
|
Ppcre_callout_block* = ptr tpcre_callout_block
|
||||||
Ppcre_extra = ptr Tpcre_extra
|
Ppcre_extra* = ptr Tpcre_extra
|
||||||
|
TPcre {.final, pure.} = object
|
||||||
|
|
||||||
|
# The structure for passing additional data to pcre_exec(). This is defined
|
||||||
|
# in such as way as to be extensible.
|
||||||
|
# Bits for which fields are set
|
||||||
|
# Opaque data from pcre_study()
|
||||||
|
# Maximum number of calls to match()
|
||||||
|
# Data passed back in callouts
|
||||||
|
# Const before type ignored
|
||||||
|
# Pointer to character tables
|
||||||
|
Tpcre_extra* {.final, pure.} = object
|
||||||
|
flags: cint
|
||||||
|
study_data: pointer
|
||||||
|
match_limit: cint
|
||||||
|
callout_data: pointer
|
||||||
|
tables: ptr byte
|
||||||
|
|
||||||
|
# The structure for passing out data via the pcre_callout_function. We use a
|
||||||
|
# structure so that new fields can be added on the end in future versions,
|
||||||
|
# without changing the API of the function, thereby allowing old clients to
|
||||||
|
# work without modification.
|
||||||
|
# Identifies version of block
|
||||||
|
# ------------------------ Version 0 -------------------------------
|
||||||
|
# Number compiled into pattern
|
||||||
|
# The offset vector
|
||||||
|
# Const before type ignored
|
||||||
|
# The subject being matched
|
||||||
|
# The length of the subject
|
||||||
|
# Offset to start of this match attempt
|
||||||
|
# Where we currently are in the subject
|
||||||
|
# Max current capture
|
||||||
|
# Most recently closed capture
|
||||||
|
# Data passed in with the call
|
||||||
|
# ------------------- Added for Version 1 --------------------------
|
||||||
|
# Offset to next item in the pattern
|
||||||
|
# Length of next item in the pattern
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
TPcre_callout_block* {.final, pure.} = object
|
||||||
|
version: cint
|
||||||
|
callout_number: cint
|
||||||
|
offset_vector: ptr cint
|
||||||
|
subject: ptr char
|
||||||
|
subject_length: cint
|
||||||
|
start_match: cint
|
||||||
|
current_position: cint
|
||||||
|
capture_top: cint
|
||||||
|
capture_last: cint
|
||||||
|
callout_data: pointer
|
||||||
|
pattern_position: cint
|
||||||
|
next_item_length: cint
|
||||||
|
|
||||||
|
|
||||||
#************************************************
|
#************************************************
|
||||||
#* Perl-Compatible Regular Expressions *
|
#* Perl-Compatible Regular Expressions *
|
||||||
|
|
@ -146,95 +196,39 @@ const
|
||||||
PCRE_EXTRA_MATCH_LIMIT* = 0x0002
|
PCRE_EXTRA_MATCH_LIMIT* = 0x0002
|
||||||
PCRE_EXTRA_CALLOUT_DATA* = 0x0004
|
PCRE_EXTRA_CALLOUT_DATA* = 0x0004
|
||||||
PCRE_EXTRA_TABLES* = 0x0008
|
PCRE_EXTRA_TABLES* = 0x0008
|
||||||
# Types
|
|
||||||
|
|
||||||
type
|
|
||||||
TPcre = record
|
|
||||||
#undefined structure
|
|
||||||
|
|
||||||
|
|
||||||
# The structure for passing additional data to pcre_exec(). This is defined
|
|
||||||
# in such as way as to be extensible. Always add new fields at the end,
|
|
||||||
# in order to remain compatible.
|
|
||||||
# Bits for which fields are set
|
|
||||||
# Opaque data from pcre_study()
|
|
||||||
# Maximum number of calls to match()
|
|
||||||
# Data passed back in callouts
|
|
||||||
# Const before type ignored
|
|
||||||
# Pointer to character tables
|
|
||||||
Tpcre_extra* {.final.} = object
|
|
||||||
flags: cuint
|
|
||||||
study_data: pointer
|
|
||||||
match_limit: cuint
|
|
||||||
callout_data: pointer
|
|
||||||
tables: ptr byte
|
|
||||||
|
|
||||||
# The structure for passing out data via the pcre_callout_function. We use a
|
|
||||||
# structure so that new fields can be added on the end in future versions,
|
|
||||||
# without changing the API of the function, thereby allowing old clients to
|
|
||||||
# work without modification.
|
|
||||||
# Identifies version of block
|
|
||||||
# ------------------------ Version 0 -------------------------------
|
|
||||||
# Number compiled into pattern
|
|
||||||
# The offset vector
|
|
||||||
# Const before type ignored
|
|
||||||
# The subject being matched
|
|
||||||
# The length of the subject
|
|
||||||
# Offset to start of this match attempt
|
|
||||||
# Where we currently are in the subject
|
|
||||||
# Max current capture
|
|
||||||
# Most recently closed capture
|
|
||||||
# Data passed in with the call
|
|
||||||
# ------------------- Added for Version 1 --------------------------
|
|
||||||
# Offset to next item in the pattern
|
|
||||||
# Length of next item in the pattern
|
|
||||||
# ------------------------------------------------------------------
|
|
||||||
TPcre_callout_block* {.final.} = object
|
|
||||||
version: cint
|
|
||||||
callout_number: cint
|
|
||||||
offset_vector: ptr cint
|
|
||||||
subject: ptr char
|
|
||||||
subject_length: cint
|
|
||||||
start_match: cint
|
|
||||||
current_position: cint
|
|
||||||
capture_top: cint
|
|
||||||
capture_last: cint
|
|
||||||
callout_data: pointer
|
|
||||||
pattern_position: cint
|
|
||||||
next_item_length: cint
|
|
||||||
|
|
||||||
# Exported PCRE functions
|
# Exported PCRE functions
|
||||||
|
|
||||||
proc pcre_compile*(para1: Pchar, para2: cint, para3: ptr Pchar,
|
proc pcre_compile*(para1: cstring, para2: cint, para3: ptr cstring,
|
||||||
para4: Pint, para5: Pbyte): Ppcre {.
|
para4: ptr int, para5: Pbyte): Ppcre {.
|
||||||
importc: "pcre_compile", noconv.}
|
importc: "pcre_compile", noconv.}
|
||||||
|
|
||||||
proc pcre_compile2*(para1: Pchar, para2: cint, para3: Pint, para4: PPchar,
|
proc pcre_compile2*(para1: cstring, para2: cint, para3: Pint, para4: PPchar,
|
||||||
para5: Pint, para6: Pbyte): Ppcre {.
|
para5: ptr int, para6: Pbyte): Ppcre {.
|
||||||
importc: "pcre_compile2", noconv.}
|
importc: "pcre_compile2", noconv.}
|
||||||
|
|
||||||
proc pcre_config*(para1: cint, para2: pointer): cint {.
|
proc pcre_config*(para1: cint, para2: pointer): cint {.
|
||||||
importc: "pcre_config", noconv.}
|
importc: "pcre_config", noconv.}
|
||||||
|
|
||||||
proc pcre_copy_named_substring*(para1: Ppcre, para2: Pchar, para3: Pint,
|
proc pcre_copy_named_substring*(para1: Ppcre, para2: cstring, para3: Pint,
|
||||||
para4: cint, para5: Pchar, para6: Pchar,
|
para4: cint, para5: cstring, para6: cstring,
|
||||||
para7: cint): cint {.
|
para7: cint): cint {.
|
||||||
importc: "pcre_copy_named_substring", noconv.}
|
importc: "pcre_copy_named_substring", noconv.}
|
||||||
|
|
||||||
proc pcre_copy_substring*(para1: Pchar, para2: Pint, para3: cint, para4: cint,
|
proc pcre_copy_substring*(para1: cstring, para2: Pint, para3: cint, para4: cint,
|
||||||
para5: Pchar, para6: cint): cint {.
|
para5: cstring, para6: cint): cint {.
|
||||||
importc: "pcre_copy_substring", noconv.}
|
importc: "pcre_copy_substring", noconv.}
|
||||||
|
|
||||||
proc pcre_dfa_exec*(para1: Ppcre, para2: Ppcre_extra, para3: Pchar,
|
proc pcre_dfa_exec*(para1: Ppcre, para2: Ppcre_extra, para3: cstring,
|
||||||
para4: cint, para5: cint, para6: cint, para7: Pint,
|
para4: cint, para5: cint, para6: cint, para7: Pint,
|
||||||
para8: cint, para9: Pint, para10: cint): cint {.
|
para8: cint, para9: Pint, para10: cint): cint {.
|
||||||
importc: "pcre_dfa_exec", noconv.}
|
importc: "pcre_dfa_exec", noconv.}
|
||||||
|
|
||||||
proc pcre_exec*(para1: Ppcre, para2: Ppcre_extra, para3: Pchar,
|
proc pcre_exec*(para1: Ppcre, para2: Ppcre_extra, para3: cstring,
|
||||||
para4: cint, para5: cint, para6: cint, para7: Pint,
|
para4: cint, para5: cint, para6: cint, para7: Pint,
|
||||||
para8: cint): cint {.importc: "pcre_exec", noconv.}
|
para8: cint): cint {.importc: "pcre_exec", noconv.}
|
||||||
|
|
||||||
proc pcre_free_substring*(para1: Pchar) {.
|
proc pcre_free_substring*(para1: cstring) {.
|
||||||
importc: "pcre_free_substring", noconv.}
|
importc: "pcre_free_substring", noconv.}
|
||||||
|
|
||||||
proc pcre_free_substring_list*(para1: PPchar) {.
|
proc pcre_free_substring_list*(para1: PPchar) {.
|
||||||
|
|
@ -243,18 +237,18 @@ proc pcre_free_substring_list*(para1: PPchar) {.
|
||||||
proc pcre_fullinfo*(para1: Ppcre, para2: Ppcre_extra, para3: cint,
|
proc pcre_fullinfo*(para1: Ppcre, para2: Ppcre_extra, para3: cint,
|
||||||
para4: pointer): cint {.importc: "pcre_fullinfo", noconv.}
|
para4: pointer): cint {.importc: "pcre_fullinfo", noconv.}
|
||||||
|
|
||||||
proc pcre_get_named_substring*(para1: Ppcre, para2: Pchar, para3: Pint,
|
proc pcre_get_named_substring*(para1: Ppcre, para2: cstring, para3: Pint,
|
||||||
para4: cint, para5: Pchar, para6: PPchar): cint {.
|
para4: cint, para5: cstring, para6: PPchar): cint {.
|
||||||
importc: "pcre_get_named_substring", noconv.}
|
importc: "pcre_get_named_substring", noconv.}
|
||||||
|
|
||||||
proc pcre_get_stringnumber*(para1: Ppcre, para2: Pchar): cint {.
|
proc pcre_get_stringnumber*(para1: Ppcre, para2: cstring): cint {.
|
||||||
importc: "pcre_get_stringnumber", noconv.}
|
importc: "pcre_get_stringnumber", noconv.}
|
||||||
|
|
||||||
proc pcre_get_substring*(para1: Pchar, para2: Pint, para3: cint,
|
proc pcre_get_substring*(para1: cstring, para2: Pint, para3: cint,
|
||||||
para4: cint, para5: PPchar): cint {.
|
para4: cint, para5: PPchar): cint {.
|
||||||
importc: "pcre_get_substring", noconv.}
|
importc: "pcre_get_substring", noconv.}
|
||||||
|
|
||||||
proc pcre_get_substring_list*(para1: Pchar, para2: Pint, para3: cint,
|
proc pcre_get_substring_list*(para1: cstring, para2: Pint, para3: cint,
|
||||||
para4: ptr PPchar): cint {.
|
para4: ptr PPchar): cint {.
|
||||||
importc: "pcre_get_substring_list", noconv.}
|
importc: "pcre_get_substring_list", noconv.}
|
||||||
|
|
||||||
|
|
@ -279,18 +273,19 @@ proc pcre_version*: CString {.importc: "pcre_version", noconv.}
|
||||||
#
|
#
|
||||||
|
|
||||||
# we use Nimrod's memory manager (but not GC!) for these functions:
|
# we use Nimrod's memory manager (but not GC!) for these functions:
|
||||||
|
type
|
||||||
|
TMalloc = proc (para1: int): pointer {.noconv.}
|
||||||
|
TFree = proc (para1: pointer) {.noconv.}
|
||||||
var
|
var
|
||||||
pcre_malloc {.importc: "pcre_malloc".}: proc (para1: int): pointer {.noconv.}
|
pcre_malloc {.importc: "pcre_malloc".}: TMalloc
|
||||||
pcre_free {.importc: "pcre_free".}: proc (para1: pointer) {.noconv.}
|
pcre_free {.importc: "pcre_free".}: TFree
|
||||||
pcre_stack_malloc {.importc: "pcre_stack_malloc".}:
|
pcre_stack_malloc {.importc: "pcre_stack_malloc".}: TMalloc
|
||||||
proc (para1: int): pointer {.noconv.}
|
pcre_stack_free {.importc: "pcre_stack_free".}: TFree
|
||||||
pcre_stack_free {.importc: "pcre_stack_free".}:
|
|
||||||
proc (para1: pointer) {.noconv.}
|
|
||||||
pcre_callout {.importc: "pcre_callout".}:
|
pcre_callout {.importc: "pcre_callout".}:
|
||||||
proc (para1: Ppcre_callout_block): cint {.noconv.}
|
proc (para1: Ppcre_callout_block): cint {.noconv.}
|
||||||
|
|
||||||
pcre_malloc = system.alloc
|
pcre_malloc = cast[TMalloc](system.alloc)
|
||||||
pcre_free = system.dealloc
|
pcre_free = cast[TFree](system.dealloc)
|
||||||
pcre_stack_malloc = system.alloc
|
pcre_stack_malloc = cast[TMalloc](system.alloc)
|
||||||
pcre_stack_free = system.dealloc
|
pcre_stack_free = cast[TFree](system.dealloc)
|
||||||
pcre_callout = nil
|
pcre_callout = nil
|
||||||
|
|
|
||||||
|
|
@ -33,27 +33,27 @@ const
|
||||||
## defines the maximum number of subpatterns that can be captured.
|
## defines the maximum number of subpatterns that can be captured.
|
||||||
## More subpatterns cannot be captured!
|
## More subpatterns cannot be captured!
|
||||||
|
|
||||||
proc match*(s, pattern: string, substrs: var openarray[string],
|
proc match*(s, pattern: string, matches: var openarray[string],
|
||||||
start: int = 0): bool
|
start: int = 0): bool
|
||||||
## returns ``true`` if ``s`` matches the ``pattern[start..]`` and
|
## returns ``true`` if ``s`` matches the ``pattern[start..]`` and
|
||||||
## the captured substrings in the array ``substrs``. If it does not
|
## the captured substrings in the array ``matches``. If it does not
|
||||||
## match, nothing is written into ``substrs`` and ``false`` is
|
## match, nothing is written into ``matches`` and ``false`` is
|
||||||
## returned.
|
## returned.
|
||||||
|
|
||||||
proc match*(s, pattern: string, start: int = 0): bool
|
proc match*(s, pattern: string, start: int = 0): bool
|
||||||
## returns ``true`` if ``s`` matches the ``pattern`` beginning from ``start``.
|
## returns ``true`` if ``s`` matches the ``pattern`` beginning from ``start``.
|
||||||
|
|
||||||
proc matchLen*(s, pattern: string, substrs: var openarray[string],
|
proc matchLen*(s, pattern: string, matches: var openarray[string],
|
||||||
start: int = 0): int
|
start: int = 0): int
|
||||||
## the same as ``match``, but it returns the length of the match,
|
## the same as ``match``, but it returns the length of the match,
|
||||||
## if there is no match, -1 is returned. Note that a match length
|
## if there is no match, -1 is returned. Note that a match length
|
||||||
## of zero can happen.
|
## of zero can happen.
|
||||||
|
|
||||||
proc find*(s, pattern: string, substrs: var openarray[string],
|
proc find*(s, pattern: string, matches: var openarray[string],
|
||||||
start: int = 0): bool
|
start: int = 0): bool
|
||||||
## returns ``true`` if ``pattern`` occurs in ``s`` and the captured
|
## returns ``true`` if ``pattern`` occurs in ``s`` and the captured
|
||||||
## substrings in the array ``substrs``. If it does not match, nothing
|
## substrings in the array ``matches``. If it does not match, nothing
|
||||||
## is written into ``substrs``.
|
## is written into ``matches``.
|
||||||
proc find*(s, pattern: string, start: int = 0): bool
|
proc find*(s, pattern: string, start: int = 0): bool
|
||||||
## returns ``true`` if ``pattern`` occurs in ``s``.
|
## returns ``true`` if ``pattern`` occurs in ``s``.
|
||||||
|
|
||||||
|
|
@ -61,7 +61,7 @@ proc find*(s, pattern: string, start: int = 0): bool
|
||||||
proc rawCompile(pattern: string, flags: cint): PPcre =
|
proc rawCompile(pattern: string, flags: cint): PPcre =
|
||||||
var
|
var
|
||||||
msg: CString
|
msg: CString
|
||||||
offset: cint
|
offset: int
|
||||||
com = pcreCompile(pattern, flags, addr(msg), addr(offset), nil)
|
com = pcreCompile(pattern, flags, addr(msg), addr(offset), nil)
|
||||||
if com == nil:
|
if com == nil:
|
||||||
var e: ref EInvalidRegEx
|
var e: ref EInvalidRegEx
|
||||||
|
|
@ -70,45 +70,46 @@ proc rawCompile(pattern: string, flags: cint): PPcre =
|
||||||
raise e
|
raise e
|
||||||
return com
|
return com
|
||||||
|
|
||||||
proc matchOrFind(s: string, pattern: PPcre, substrs: var openarray[string],
|
proc matchOrFind(s: string, pattern: PPcre, matches: var openarray[string],
|
||||||
start: cint): cint =
|
start: cint): cint =
|
||||||
var
|
var
|
||||||
rawMatches: array [0..maxSubpatterns * 3 - 1, cint]
|
rawMatches: array [0..maxSubpatterns * 3 - 1, cint]
|
||||||
res = int(pcreExec(pattern, nil, s, length(s), start, 0,
|
res = int(pcreExec(pattern, nil, s, len(s), start, 0,
|
||||||
cast[pint](addr(rawMatches)), maxSubpatterns * 3))
|
cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3))
|
||||||
dealloc(pattern)
|
dealloc(pattern)
|
||||||
if res < 0: return res
|
if res < 0: return res
|
||||||
for i in 0..res-1:
|
for i in 0..res-1:
|
||||||
var
|
var
|
||||||
a = rawMatches[i * 3]
|
a = rawMatches[i * 2]
|
||||||
b = rawMatches[i * 3 + 1]
|
b = rawMatches[i * 2 + 1]
|
||||||
if a >= 0: substrs[i] = copy(s, a, b)
|
if a >= 0'i32: matches[i] = copy(s, a, int(b)-1)
|
||||||
else: substrs[i] = ""
|
else: matches[i] = ""
|
||||||
return res
|
return res
|
||||||
|
|
||||||
proc matchOrFind(s: string, pattern: PPcre, start: cint): cint =
|
proc matchOrFind(s: string, pattern: PPcre, start: cint): cint =
|
||||||
var
|
var
|
||||||
rawMatches: array [0..maxSubpatterns * 3 - 1, cint]
|
rawMatches: array [0..maxSubpatterns * 3 - 1, cint]
|
||||||
res = pcreExec(pattern, nil, s, length(s), start, 0,
|
res = pcreExec(pattern, nil, s, len(s), start, 0,
|
||||||
cast[pint](addr(rawMatches)), maxSubpatterns * 3)
|
cast[ptr cint](addr(rawMatches)), maxSubpatterns * 3)
|
||||||
dealloc(pattern)
|
dealloc(pattern)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
proc match(s, pattern: string, substrs: var openarray[string],
|
proc match(s, pattern: string, matches: var openarray[string],
|
||||||
start: int = 0): bool =
|
start: int = 0): bool =
|
||||||
return matchOrFind(s, rawCompile(pattern, PCRE_ANCHORED),
|
return matchOrFind(s, rawCompile(pattern, PCRE_ANCHORED),
|
||||||
substrs, start) >= 0
|
matches, start) >= 0'i32
|
||||||
|
|
||||||
proc matchLen(s, pattern: string, substrs: var openarray[string],
|
proc matchLen(s, pattern: string, matches: var openarray[string],
|
||||||
start: int = 0): int =
|
start: int = 0): int =
|
||||||
return matchOrFind(s, rawCompile(pattern, PCRE_ANCHORED), substrs, start)
|
return matchOrFind(s, rawCompile(pattern, PCRE_ANCHORED), matches, start)
|
||||||
|
|
||||||
proc find(s, pattern: string, substrs: var openarray[string],
|
proc find(s, pattern: string, matches: var openarray[string],
|
||||||
start: int = 0): bool =
|
start: int = 0): bool =
|
||||||
return matchOrFind(s, rawCompile(pattern, 0), substrs, start) >= 0
|
return matchOrFind(s, rawCompile(pattern, PCRE_MULTILINE),
|
||||||
|
matches, start) >= 0'i32
|
||||||
|
|
||||||
proc match(s, pattern: string, start: int = 0): bool =
|
proc match(s, pattern: string, start: int = 0): bool =
|
||||||
return matchOrFind(s, rawCompile(pattern, PCRE_ANCHORED), start) >= 0
|
return matchOrFind(s, rawCompile(pattern, PCRE_ANCHORED), start) >= 0'i32
|
||||||
|
|
||||||
proc find(s, pattern: string, start: int = 0): bool =
|
proc find(s, pattern: string, start: int = 0): bool =
|
||||||
return matchOrFind(s, rawCompile(pattern, 0), start) >= 0
|
return matchOrFind(s, rawCompile(pattern, PCRE_MULTILINE), start) >= 0'i32
|
||||||
|
|
|
||||||
|
|
@ -17,4 +17,4 @@ proc population16(a: int): int {.inline.} =
|
||||||
return x
|
return x
|
||||||
|
|
||||||
proc countBits(n: int32): int =
|
proc countBits(n: int32): int =
|
||||||
result = population16(n and 0xffff) + population16(n shr 16)
|
result = population16(n and 0xffff'i32) + population16(n shr 16'i32)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
# Container library for Nimrod
|
# Container library for Nimrod
|
||||||
# Implemented with macros, because generics sucks in many ways
|
|
||||||
|
|
||||||
# Data structures for now:
|
# Data structures for now:
|
||||||
# TTable, TSet, TList
|
# TTable, TSet, TList
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,15 @@
|
||||||
#define USE_DL_PREFIX
|
|
||||||
|
|
||||||
|
#define USE_DL_PREFIX
|
||||||
|
#define ASSEMBLY_VERSION
|
||||||
|
|
||||||
|
/*
|
||||||
#define FOOTERS 1
|
#define FOOTERS 1
|
||||||
#define DEBUG 1
|
#define DEBUG 1
|
||||||
/*
|
|
||||||
#define ABORT_ON_ASSERT_FAILURE 0
|
#define ABORT_ON_ASSERT_FAILURE 0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define ABORT do { printf("abort was called\n"); abort(); } while (0)
|
#define ABORT do { /*printf("abort was called\n");*/ abort(); } while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This is a version (aka dlmalloc) of malloc/free/realloc written by
|
This is a version (aka dlmalloc) of malloc/free/realloc written by
|
||||||
|
|
@ -2210,7 +2213,7 @@ static size_t traverse_and_check(mstate m);
|
||||||
#define treebin_at(M,i) (&((M)->treebins[i]))
|
#define treebin_at(M,i) (&((M)->treebins[i]))
|
||||||
|
|
||||||
/* assign tree index for size S to variable I */
|
/* assign tree index for size S to variable I */
|
||||||
#if defined(__GNUC__) && defined(i386)
|
#if defined(__GNUC__) && defined(i386) && defined(ASSEMBLY_VERSION)
|
||||||
#define compute_tree_index(S, I)\
|
#define compute_tree_index(S, I)\
|
||||||
{\
|
{\
|
||||||
size_t X = S >> TREEBIN_SHIFT;\
|
size_t X = S >> TREEBIN_SHIFT;\
|
||||||
|
|
@ -2275,7 +2278,7 @@ static size_t traverse_and_check(mstate m);
|
||||||
|
|
||||||
/* index corresponding to given bit */
|
/* index corresponding to given bit */
|
||||||
|
|
||||||
#if defined(__GNUC__) && defined(i386)
|
#if defined(__GNUC__) && defined(i386) && defined(ASSEMBLY_VERSION)
|
||||||
#define compute_bit2idx(X, I)\
|
#define compute_bit2idx(X, I)\
|
||||||
{\
|
{\
|
||||||
unsigned int J;\
|
unsigned int J;\
|
||||||
|
|
|
||||||
|
|
@ -7,25 +7,14 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# This file implements the ability to call native procs from libraries.
|
# This file implements the ability to call native procs from libraries.
|
||||||
# It is not possible to do this in a platform independant way, unfortunately.
|
# It is not possible to do this in a platform independant way, unfortunately.
|
||||||
# However, the interface has been designed to take platform differences into
|
# However, the interface has been designed to take platform differences into
|
||||||
# account and been ported to all major platforms.
|
# account and been ported to all major platforms.
|
||||||
#
|
|
||||||
# interface
|
|
||||||
|
|
||||||
type
|
type
|
||||||
EInvalidLibrary = object of EOS
|
EInvalidLibrary = object of EOS
|
||||||
|
|
||||||
when defined(windows) or defined(dos):
|
|
||||||
{.define: USE_DLL.}
|
|
||||||
elif defined(posix):
|
|
||||||
{.define: USE_DLOPEN.}
|
|
||||||
elif defined(mac):
|
|
||||||
{.define: USE_DYLD.}
|
|
||||||
|
|
||||||
type
|
type
|
||||||
TLibHandle = pointer # private type
|
TLibHandle = pointer # private type
|
||||||
TProcAddr = pointer # libary loading and loading of procs:
|
TProcAddr = pointer # libary loading and loading of procs:
|
||||||
|
|
@ -37,15 +26,13 @@ proc nimLoadLibrary(path: string): TLibHandle {.compilerproc.}
|
||||||
proc nimUnloadLibrary(lib: TLibHandle) {.compilerproc.}
|
proc nimUnloadLibrary(lib: TLibHandle) {.compilerproc.}
|
||||||
proc nimGetProcAddr(lib: TLibHandle, name: cstring): TProcAddr {.compilerproc.}
|
proc nimGetProcAddr(lib: TLibHandle, name: cstring): TProcAddr {.compilerproc.}
|
||||||
|
|
||||||
#implementation
|
|
||||||
|
|
||||||
# this code was inspired from Lua's source code:
|
# this code was inspired from Lua's source code:
|
||||||
# Lua - An Extensible Extension Language
|
# Lua - An Extensible Extension Language
|
||||||
# Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil
|
# Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil
|
||||||
# http://www.lua.org
|
# http://www.lua.org
|
||||||
# mailto:info@lua.org
|
# mailto:info@lua.org
|
||||||
|
|
||||||
when defined(USE_DLOPEN):
|
when defined(posix):
|
||||||
#
|
#
|
||||||
# =========================================================================
|
# =========================================================================
|
||||||
# This is an implementation based on the dlfcn interface.
|
# This is an implementation based on the dlfcn interface.
|
||||||
|
|
@ -76,7 +63,7 @@ when defined(USE_DLOPEN):
|
||||||
proc nimGetProcAddr(lib: TLibHandle, name: cstring): TProcAddr =
|
proc nimGetProcAddr(lib: TLibHandle, name: cstring): TProcAddr =
|
||||||
result = dlsym(lib, name)
|
result = dlsym(lib, name)
|
||||||
|
|
||||||
elif defined(USE_DLL):
|
elif defined(windows) or defined(dos):
|
||||||
#
|
#
|
||||||
# =======================================================================
|
# =======================================================================
|
||||||
# Native Windows Implementation
|
# Native Windows Implementation
|
||||||
|
|
@ -102,7 +89,7 @@ elif defined(USE_DLL):
|
||||||
proc nimGetProcAddr(lib: TLibHandle, name: cstring): TProcAddr =
|
proc nimGetProcAddr(lib: TLibHandle, name: cstring): TProcAddr =
|
||||||
result = GetProcAddress(cast[THINSTANCE](lib), name)
|
result = GetProcAddress(cast[THINSTANCE](lib), name)
|
||||||
|
|
||||||
elif defined(USE_DYLD):
|
elif defined(mac):
|
||||||
#
|
#
|
||||||
# =======================================================================
|
# =======================================================================
|
||||||
# Native Mac OS X / Darwin Implementation
|
# Native Mac OS X / Darwin Implementation
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ proc GC_fullCollect() = nil
|
||||||
proc GC_setStrategy(strategy: TGC_Strategy) = nil
|
proc GC_setStrategy(strategy: TGC_Strategy) = nil
|
||||||
proc GC_enableMarkAndSweep() = nil
|
proc GC_enableMarkAndSweep() = nil
|
||||||
proc GC_disableMarkAndSweep() = nil
|
proc GC_disableMarkAndSweep() = nil
|
||||||
|
proc GC_getStatistics(): string = return ""
|
||||||
|
|
||||||
proc getOccupiedMem(): int = return -1
|
proc getOccupiedMem(): int = return -1
|
||||||
proc getFreeMem(): int = return -1
|
proc getFreeMem(): int = return -1
|
||||||
|
|
|
||||||
|
|
@ -171,8 +171,7 @@ var
|
||||||
|
|
||||||
proc signalHandler(sig: cint) {.exportc: "signalHandler", noconv.} =
|
proc signalHandler(sig: cint) {.exportc: "signalHandler", noconv.} =
|
||||||
# print stack trace and quit
|
# print stack trace and quit
|
||||||
var
|
var s = sig
|
||||||
s = int(sig)
|
|
||||||
GC_disable()
|
GC_disable()
|
||||||
setLen(buf, 0)
|
setLen(buf, 0)
|
||||||
rawWriteStackTrace(buf)
|
rawWriteStackTrace(buf)
|
||||||
|
|
@ -199,7 +198,8 @@ proc registerSignalHandler() =
|
||||||
c_signal(SIGILL, signalHandler)
|
c_signal(SIGILL, signalHandler)
|
||||||
c_signal(SIGBUS, signalHandler)
|
c_signal(SIGBUS, signalHandler)
|
||||||
|
|
||||||
registerSignalHandler() # call it in initialization section
|
when not defined(noSignalHandler):
|
||||||
|
registerSignalHandler() # call it in initialization section
|
||||||
# for easier debugging of the GC, this memory is only allocated after the
|
# for easier debugging of the GC, this memory is only allocated after the
|
||||||
# signal handlers have been registered
|
# signal handlers have been registered
|
||||||
new(gAssertionFailed)
|
new(gAssertionFailed)
|
||||||
|
|
@ -256,3 +256,12 @@ proc chckObj(obj, subclass: PNimType) {.compilerproc.} =
|
||||||
proc chckObjAsgn(a, b: PNimType) {.compilerproc, inline.} =
|
proc chckObjAsgn(a, b: PNimType) {.compilerproc, inline.} =
|
||||||
if a != b:
|
if a != b:
|
||||||
raise newException(EInvalidObjectAssignment, "invalid object assignment")
|
raise newException(EInvalidObjectAssignment, "invalid object assignment")
|
||||||
|
|
||||||
|
proc isObj(obj, subclass: PNimType): bool {.compilerproc.} =
|
||||||
|
# checks if obj is of type subclass:
|
||||||
|
var x = obj
|
||||||
|
if x == subclass: return true # optimized fast path
|
||||||
|
while x != subclass:
|
||||||
|
if x == nil: return false
|
||||||
|
x = x.base
|
||||||
|
return true
|
||||||
|
|
|
||||||
1086
lib/gc.nim
1086
lib/gc.nim
File diff suppressed because it is too large
Load diff
|
|
@ -104,8 +104,7 @@ const
|
||||||
growthFactor = 2 # must be power of two
|
growthFactor = 2 # must be power of two
|
||||||
|
|
||||||
proc init*[TKey, TValue](t: var TTable[TKey, TValue], capacity: natural = 32) =
|
proc init*[TKey, TValue](t: var TTable[TKey, TValue], capacity: natural = 32) =
|
||||||
t.d = [] # XXX
|
newSeq(t.d, capacity)
|
||||||
setLen(t.d, capacity)
|
|
||||||
|
|
||||||
proc len*[TKey, TValue](t: TTable[TKey, TValue]): natural = return t.counter
|
proc len*[TKey, TValue](t: TTable[TKey, TValue]): natural = return t.counter
|
||||||
|
|
||||||
|
|
@ -136,8 +135,8 @@ proc TableRawInsert[TKey, TValue](data: var seq[TPair[TKey, TValue]],
|
||||||
data[h].val = val
|
data[h].val = val
|
||||||
|
|
||||||
proc TableEnlarge[TKey, TValue](t: var TTable[TKey, TValue]) =
|
proc TableEnlarge[TKey, TValue](t: var TTable[TKey, TValue]) =
|
||||||
var n: seq[TPair[TKey,TValue]] = []
|
var n: seq[TPair[TKey,TValue]]
|
||||||
setLen(n, len(t.d) * growthFactor) # XXX
|
newSeq(n, len(t.d) * growthFactor)
|
||||||
for i in 0..high(t.d):
|
for i in 0..high(t.d):
|
||||||
if not isNil(t.d[i].key):
|
if not isNil(t.d[i].key):
|
||||||
TableRawInsert(n, t.d[i].key, t.d[i].val)
|
TableRawInsert(n, t.d[i].key, t.d[i].val)
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ type # This should be he same as ast.TTypeKind
|
||||||
tyNone, # 0
|
tyNone, # 0
|
||||||
tyBool, # 1
|
tyBool, # 1
|
||||||
tyChar, # 2
|
tyChar, # 2
|
||||||
tyEmptySet, # 3
|
tyEmpty, # 3
|
||||||
tyArrayConstr, # 4
|
tyArrayConstr, # 4
|
||||||
tyNil, # 5
|
tyNil, # 5
|
||||||
tyGeneric, # 6
|
tyGeneric, # 6
|
||||||
|
|
@ -49,9 +49,13 @@ type # This should be he same as ast.TTypeKind
|
||||||
len: int
|
len: int
|
||||||
sons: ptr array [0..0x7fff, ptr TNimNode]
|
sons: ptr array [0..0x7fff, ptr TNimNode]
|
||||||
|
|
||||||
|
TNimTypeFlag = enum
|
||||||
|
ntfNoRefs = 0, # type contains no tyRef, tySequence, tyString
|
||||||
|
ntfAcyclic = 1 # type cannot form a cycle
|
||||||
TNimType {.compilerproc, final.} = object
|
TNimType {.compilerproc, final.} = object
|
||||||
size: int
|
size: int
|
||||||
kind: TNimKind
|
kind: TNimKind
|
||||||
|
flags: set[TNimTypeFlag]
|
||||||
base: ptr TNimType
|
base: ptr TNimType
|
||||||
node: ptr TNimNode # valid for tyRecord, tyObject, tyTuple, tyEnum
|
node: ptr TNimNode # valid for tyRecord, tyObject, tyTuple, tyEnum
|
||||||
finalizer: pointer # the finalizer for the type
|
finalizer: pointer # the finalizer for the type
|
||||||
|
|
|
||||||
|
|
@ -8,42 +8,39 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
## This module implements a base object of a lexer with efficient buffer
|
## This module implements a base object of a lexer with efficient buffer
|
||||||
## handling. In fact I believe that this is the most efficient method of
|
## handling. Only at line endings checks are necessary if the buffer
|
||||||
## buffer handling that exists! Only at line endings checks are necessary
|
## needs refilling.
|
||||||
## if the buffer needs refilling.
|
|
||||||
|
|
||||||
import
|
import
|
||||||
strutils
|
strutils, streams
|
||||||
|
|
||||||
const
|
const
|
||||||
EndOfFile* = '\0' ## end of file marker
|
EndOfFile* = '\0' ## end of file marker
|
||||||
# A little picture makes everything clear :-)
|
|
||||||
# buf:
|
|
||||||
# "Example Text\n ha!" bufLen = 17
|
|
||||||
# ^pos = 0 ^ sentinel = 12
|
|
||||||
#
|
|
||||||
NewLines* = {'\c', '\L'}
|
NewLines* = {'\c', '\L'}
|
||||||
|
|
||||||
|
# Buffer handling:
|
||||||
|
# buf:
|
||||||
|
# "Example Text\n ha!" bufLen = 17
|
||||||
|
# ^pos = 0 ^ sentinel = 12
|
||||||
|
#
|
||||||
|
|
||||||
type
|
type
|
||||||
TBaseLexer* = object of TObject ## the base lexer. Inherit your lexer from
|
TBaseLexer* = object of TObject ## the base lexer. Inherit your lexer from
|
||||||
## this object.
|
## this object.
|
||||||
bufpos*: int ## the current position within the buffer
|
bufpos*: int ## the current position within the buffer
|
||||||
buf*: cstring ## the buffer itself
|
buf*: cstring ## the buffer itself
|
||||||
bufLen*: int ## length of buffer in characters
|
bufLen*: int ## length of buffer in characters
|
||||||
f*: tfile ## the file that is read
|
input: PStream ## the input stream
|
||||||
LineNumber*: int ## the current line number
|
LineNumber*: int ## the current line number
|
||||||
sentinel: int
|
sentinel: int
|
||||||
lineStart: int # index of last line start in buffer
|
lineStart: int # index of last line start in buffer
|
||||||
fileOpened: bool
|
fileOpened: bool
|
||||||
|
|
||||||
proc initBaseLexer*(L: var TBaseLexer, filename: string, bufLen: int = 8192): bool
|
proc open*(L: var TBaseLexer, input: PStream, bufLen: int = 8192)
|
||||||
## inits the TBaseLexer object with a file to scan
|
## inits the TBaseLexer with a stream to read from
|
||||||
|
|
||||||
proc initBaseLexerFromBuffer*(L: var TBaseLexer, buffer: string)
|
proc close*(L: var TBaseLexer)
|
||||||
## inits the TBaseLexer with a buffer to scan
|
## closes the base lexer. This closes `L`'s associated stream too.
|
||||||
|
|
||||||
proc deinitBaseLexer*(L: var TBaseLexer)
|
|
||||||
## deinitializes the base lexer. This needs to be called to close the file.
|
|
||||||
|
|
||||||
proc getCurrentLine*(L: TBaseLexer, marker: bool = true): string
|
proc getCurrentLine*(L: TBaseLexer, marker: bool = true): string
|
||||||
## retrieves the current line.
|
## retrieves the current line.
|
||||||
|
|
@ -65,9 +62,9 @@ proc HandleLF*(L: var TBaseLexer, pos: int): int
|
||||||
const
|
const
|
||||||
chrSize = sizeof(char)
|
chrSize = sizeof(char)
|
||||||
|
|
||||||
proc deinitBaseLexer(L: var TBaseLexer) =
|
proc close(L: var TBaseLexer) =
|
||||||
dealloc(L.buf)
|
dealloc(L.buf)
|
||||||
if L.fileOpened: closeFile(L.f)
|
L.input.close(L.input)
|
||||||
|
|
||||||
proc FillBuffer(L: var TBaseLexer) =
|
proc FillBuffer(L: var TBaseLexer) =
|
||||||
var
|
var
|
||||||
|
|
@ -82,8 +79,8 @@ proc FillBuffer(L: var TBaseLexer) =
|
||||||
assert(toCopy >= 0)
|
assert(toCopy >= 0)
|
||||||
if toCopy > 0:
|
if toCopy > 0:
|
||||||
MoveMem(L.buf, addr(L.buf[L.sentinel + 1]), toCopy * chrSize) # "moveMem" handles overlapping regions
|
MoveMem(L.buf, addr(L.buf[L.sentinel + 1]), toCopy * chrSize) # "moveMem" handles overlapping regions
|
||||||
charsRead = ReadBuffer(L.f, addr(L.buf[toCopy]), (L.sentinel + 1) * chrSize) div
|
charsRead = L.input.readData(L.input, addr(L.buf[toCopy]),
|
||||||
chrSize
|
(L.sentinel + 1) * chrSize) div chrSize
|
||||||
s = toCopy + charsRead
|
s = toCopy + charsRead
|
||||||
if charsRead < L.sentinel + 1:
|
if charsRead < L.sentinel + 1:
|
||||||
L.buf[s] = EndOfFile # set end marker
|
L.buf[s] = EndOfFile # set end marker
|
||||||
|
|
@ -105,8 +102,8 @@ proc FillBuffer(L: var TBaseLexer) =
|
||||||
L.bufLen = L.BufLen * 2
|
L.bufLen = L.BufLen * 2
|
||||||
L.buf = cast[cstring](realloc(L.buf, L.bufLen * chrSize))
|
L.buf = cast[cstring](realloc(L.buf, L.bufLen * chrSize))
|
||||||
assert(L.bufLen - oldBuflen == oldBufLen)
|
assert(L.bufLen - oldBuflen == oldBufLen)
|
||||||
charsRead = ReadBuffer(L.f, addr(L.buf[oldBufLen]), oldBufLen * chrSize) div
|
charsRead = L.input.ReadData(L.input, addr(L.buf[oldBufLen]),
|
||||||
chrSize
|
oldBufLen * chrSize) div chrSize
|
||||||
if charsRead < oldBufLen:
|
if charsRead < oldBufLen:
|
||||||
L.buf[oldBufLen + charsRead] = EndOfFile
|
L.buf[oldBufLen + charsRead] = EndOfFile
|
||||||
L.sentinel = oldBufLen + charsRead
|
L.sentinel = oldBufLen + charsRead
|
||||||
|
|
@ -140,35 +137,19 @@ proc skip_UTF_8_BOM(L: var TBaseLexer) =
|
||||||
inc(L.bufpos, 3)
|
inc(L.bufpos, 3)
|
||||||
inc(L.lineStart, 3)
|
inc(L.lineStart, 3)
|
||||||
|
|
||||||
proc initBaseLexer(L: var TBaseLexer, filename: string, bufLen: int = 8192): bool =
|
proc open(L: var TBaseLexer, input: PStream, bufLen: int = 8192) =
|
||||||
assert(bufLen > 0)
|
assert(bufLen > 0)
|
||||||
|
assert(input != nil)
|
||||||
|
L.input = input
|
||||||
L.bufpos = 0
|
L.bufpos = 0
|
||||||
L.bufLen = bufLen
|
L.bufLen = bufLen
|
||||||
L.buf = cast[cstring](alloc(bufLen * chrSize))
|
L.buf = cast[cstring](alloc(bufLen * chrSize))
|
||||||
L.sentinel = bufLen - 1
|
L.sentinel = bufLen - 1
|
||||||
L.lineStart = 0
|
L.lineStart = 0
|
||||||
L.linenumber = 1 # lines start at 1
|
L.linenumber = 1 # lines start at 1
|
||||||
L.fileOpened = openFile(L.f, filename)
|
|
||||||
result = L.fileOpened
|
|
||||||
if result:
|
|
||||||
fillBuffer(L)
|
fillBuffer(L)
|
||||||
skip_UTF_8_BOM(L)
|
skip_UTF_8_BOM(L)
|
||||||
|
|
||||||
proc initBaseLexerFromBuffer(L: var TBaseLexer, buffer: string) =
|
|
||||||
L.bufpos = 0
|
|
||||||
L.bufLen = len(buffer) + 1
|
|
||||||
L.buf = cast[cstring](alloc(L.bufLen * chrSize))
|
|
||||||
L.sentinel = L.bufLen - 1
|
|
||||||
L.lineStart = 0
|
|
||||||
L.linenumber = 1 # lines start at 1
|
|
||||||
L.fileOpened = false
|
|
||||||
if L.bufLen > 0:
|
|
||||||
copyMem(L.buf, cast[pointer](buffer), L.bufLen)
|
|
||||||
L.buf[L.bufLen - 1] = EndOfFile
|
|
||||||
else:
|
|
||||||
L.buf[0] = EndOfFile
|
|
||||||
skip_UTF_8_BOM(L)
|
|
||||||
|
|
||||||
proc getColNumber(L: TBaseLexer, pos: int): int =
|
proc getColNumber(L: TBaseLexer, pos: int): int =
|
||||||
result = pos - L.lineStart
|
result = pos - L.lineStart
|
||||||
assert(result >= 0)
|
assert(result >= 0)
|
||||||
|
|
|
||||||
|
|
@ -12,27 +12,43 @@
|
||||||
## Abstract syntax trees should be modified in macros.
|
## Abstract syntax trees should be modified in macros.
|
||||||
|
|
||||||
#[[[cog
|
#[[[cog
|
||||||
#def toEnum(name, elems, prefix):
|
#def toEnum(name, elems):
|
||||||
# body = ""
|
# body = ""
|
||||||
# counter = 0
|
# counter = 0
|
||||||
# for e in elems:
|
# for e in elems:
|
||||||
# if counter % 4 == 0: p = "\n "
|
# if counter % 4 == 0: p = "\n "
|
||||||
# else: p = ""
|
# else: p = ""
|
||||||
# body += p + prefix + e[2:] + ', '
|
# body = body + p + 'n' + e + ', '
|
||||||
# counter += 1
|
# counter = counter + 1
|
||||||
#
|
#
|
||||||
# return " TNimrod%s* = enum%s\n TNim%ss* = set[TNimrod%s]\n" \
|
# return (" TNimrod%s* = enum%s\n TNim%ss* = set[TNimrod%s]\n" %
|
||||||
# % (name, body.rstrip(", "), name, name)
|
# (name, body[:-2], name, name))
|
||||||
#
|
#
|
||||||
#enums = eval(file("data/ast.yml").read())
|
#enums = eval(open("data/ast.yml").read())
|
||||||
#cog.out("type\n")
|
#cog.out("type\n")
|
||||||
#i = 0
|
#for key, val in enums.items():
|
||||||
#for key, val in enums.iteritems():
|
# if key[-4:] == "Flag": continue
|
||||||
# if key.endswith("Flag"): continue
|
# cog.out(toEnum(key, val))
|
||||||
# cog.out(toEnum(key, val, ["nnk", "nty", "nsk"][i]))
|
|
||||||
# i += 1
|
|
||||||
#]]]
|
#]]]
|
||||||
type
|
type
|
||||||
|
TNimrodTypeKind* = enum
|
||||||
|
ntyNone, ntyBool, ntyChar, ntyEmpty,
|
||||||
|
ntyArrayConstr, ntyNil, ntyGeneric, ntyGenericInst,
|
||||||
|
ntyGenericParam, ntyEnum, ntyAnyEnum, ntyArray,
|
||||||
|
ntyObject, ntyTuple, ntySet, ntyRange,
|
||||||
|
ntyPtr, ntyRef, ntyVar, ntySequence,
|
||||||
|
ntyProc, ntyPointer, ntyOpenArray, ntyString,
|
||||||
|
ntyCString, ntyForward, ntyInt, ntyInt8,
|
||||||
|
ntyInt16, ntyInt32, ntyInt64, ntyFloat,
|
||||||
|
ntyFloat32, ntyFloat64, ntyFloat128
|
||||||
|
TNimTypeKinds* = set[TNimrodTypeKind]
|
||||||
|
TNimrodSymKind* = enum
|
||||||
|
nskUnknownSym, nskConditional, nskDynLib, nskParam,
|
||||||
|
nskTypeParam, nskTemp, nskType, nskConst,
|
||||||
|
nskVar, nskProc, nskIterator, nskConverter,
|
||||||
|
nskMacro, nskTemplate, nskField, nskEnumField,
|
||||||
|
nskForVar, nskModule, nskLabel, nskStub
|
||||||
|
TNimSymKinds* = set[TNimrodSymKind]
|
||||||
TNimrodNodeKind* = enum
|
TNimrodNodeKind* = enum
|
||||||
nnkNone, nnkEmpty, nnkIdent, nnkSym,
|
nnkNone, nnkEmpty, nnkIdent, nnkSym,
|
||||||
nnkType, nnkCharLit, nnkIntLit, nnkInt8Lit,
|
nnkType, nnkCharLit, nnkIntLit, nnkInt8Lit,
|
||||||
|
|
@ -61,29 +77,12 @@ type
|
||||||
nnkBreakStmt, nnkContinueStmt, nnkBlockStmt, nnkDiscardStmt,
|
nnkBreakStmt, nnkContinueStmt, nnkBlockStmt, nnkDiscardStmt,
|
||||||
nnkStmtList, nnkImportStmt, nnkFromStmt, nnkImportAs,
|
nnkStmtList, nnkImportStmt, nnkFromStmt, nnkImportAs,
|
||||||
nnkIncludeStmt, nnkAccessStmt, nnkCommentStmt, nnkStmtListExpr,
|
nnkIncludeStmt, nnkAccessStmt, nnkCommentStmt, nnkStmtListExpr,
|
||||||
nnkBlockExpr, nnkVm, nnkTypeOfExpr, nnkObjectTy,
|
nnkBlockExpr, nnkStmtListType, nnkBlockType, nnkVm,
|
||||||
nnkTupleTy, nnkRecList, nnkRecCase, nnkRecWhen,
|
nnkTypeOfExpr, nnkObjectTy, nnkTupleTy, nnkRecList,
|
||||||
nnkRefTy, nnkPtrTy, nnkVarTy, nnkProcTy,
|
nnkRecCase, nnkRecWhen, nnkRefTy, nnkPtrTy,
|
||||||
nnkEnumTy, nnkEnumFieldDef, nnkReturnToken
|
nnkVarTy, nnkProcTy, nnkEnumTy, nnkEnumFieldDef,
|
||||||
|
nnkReturnToken
|
||||||
TNimNodeKinds* = set[TNimrodNodeKind]
|
TNimNodeKinds* = set[TNimrodNodeKind]
|
||||||
TNimrodTypeKind* = enum
|
|
||||||
ntyNone, ntyBool, ntyChar, ntyEmptySet,
|
|
||||||
ntyArrayConstr, ntyNil, ntyGeneric, ntyGenericInst,
|
|
||||||
ntyGenericParam, ntyEnum, ntyAnyEnum, ntyArray,
|
|
||||||
ntyObject, ntyTuple, ntySet, ntyRange,
|
|
||||||
ntyPtr, ntyRef, ntyVar, ntySequence,
|
|
||||||
ntyProc, ntyPointer, ntyOpenArray, ntyString,
|
|
||||||
ntyCString, ntyForward, ntyInt, ntyInt8,
|
|
||||||
ntyInt16, ntyInt32, ntyInt64, ntyFloat,
|
|
||||||
ntyFloat32, ntyFloat64, ntyFloat128
|
|
||||||
TNimTypeKinds* = set[TNimrodTypeKind]
|
|
||||||
TNimrodSymKind* = enum
|
|
||||||
nskUnknownSym, nskConditional, nskDynLib, nskParam,
|
|
||||||
nskTypeParam, nskTemp, nskType, nskConst,
|
|
||||||
nskVar, nskProc, nskIterator, nskConverter,
|
|
||||||
nskMacro, nskTemplate, nskField, nskEnumField,
|
|
||||||
nskForVar, nskModule, nskLabel
|
|
||||||
TNimSymKinds* = set[TNimrodSymKind]
|
|
||||||
#[[[end]]]
|
#[[[end]]]
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
@ -142,33 +141,33 @@ proc error*(msg: string) {.magic: "NError".}
|
||||||
proc warning*(msg: string) {.magic: "NWarning".}
|
proc warning*(msg: string) {.magic: "NWarning".}
|
||||||
proc hint*(msg: string) {.magic: "NHint".}
|
proc hint*(msg: string) {.magic: "NHint".}
|
||||||
|
|
||||||
proc newStrLitNode*(s: string): PNimrodNode {.nodecl.} =
|
proc newStrLitNode*(s: string): PNimrodNode {.compileTime.} =
|
||||||
result = newNimNode(nnkStrLit)
|
result = newNimNode(nnkStrLit)
|
||||||
result.strVal = s
|
result.strVal = s
|
||||||
|
|
||||||
proc newIntLitNode*(i: biggestInt): PNimrodNode {.nodecl.} =
|
proc newIntLitNode*(i: biggestInt): PNimrodNode {.compileTime.} =
|
||||||
result = newNimNode(nnkIntLit)
|
result = newNimNode(nnkIntLit)
|
||||||
result.intVal = i
|
result.intVal = i
|
||||||
|
|
||||||
proc newIntLitNode*(f: biggestFloat): PNimrodNode {.nodecl.} =
|
proc newIntLitNode*(f: biggestFloat): PNimrodNode {.compileTime.} =
|
||||||
result = newNimNode(nnkFloatLit)
|
result = newNimNode(nnkFloatLit)
|
||||||
result.floatVal = f
|
result.floatVal = f
|
||||||
|
|
||||||
proc newIdentNode*(i: TNimrodIdent): PNimrodNode {.nodecl.} =
|
proc newIdentNode*(i: TNimrodIdent): PNimrodNode {.compileTime.} =
|
||||||
result = newNimNode(nnkIdent)
|
result = newNimNode(nnkIdent)
|
||||||
result.ident = i
|
result.ident = i
|
||||||
|
|
||||||
proc toStrLit*(n: PNimrodNode): PNimrodNode {.nodecl.} =
|
proc toStrLit*(n: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||||
return newStrLitNode(repr(n))
|
return newStrLitNode(repr(n))
|
||||||
|
|
||||||
proc expectKind*(n: PNimrodNode, k: TNimrodNodeKind) {.nodecl.} =
|
proc expectKind*(n: PNimrodNode, k: TNimrodNodeKind) {.compileTime.} =
|
||||||
if n.kind != k: error("macro expects a node of kind: " & repr(k))
|
if n.kind != k: error("macro expects a node of kind: " & repr(k))
|
||||||
|
|
||||||
proc expectMinLen*(n: PNimrodNode, min: int) {.nodecl.} =
|
proc expectMinLen*(n: PNimrodNode, min: int) {.compileTime.} =
|
||||||
if n.len < min: error("macro expects a node with " & $min & " children")
|
if n.len < min: error("macro expects a node with " & $min & " children")
|
||||||
|
|
||||||
proc newCall*(theProc: TNimrodIdent,
|
proc newCall*(theProc: TNimrodIdent,
|
||||||
args: openArray[PNimrodNode]): PNimrodNode {.nodecl.} =
|
args: openArray[PNimrodNode]): PNimrodNode {.compileTime.} =
|
||||||
## produces a new call node. `theProc` is the proc that is called with
|
## produces a new call node. `theProc` is the proc that is called with
|
||||||
## the arguments ``args[0..]``.
|
## the arguments ``args[0..]``.
|
||||||
result = newNimNode(nnkCall)
|
result = newNimNode(nnkCall)
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,10 @@
|
||||||
when defined(Posix):
|
when defined(Posix):
|
||||||
{.passl: "-lm".}
|
{.passl: "-lm".}
|
||||||
|
|
||||||
|
const
|
||||||
|
PI* = 3.1415926535897932384626433 ## the circle constant PI (Ludolph's number)
|
||||||
|
E* = 2.71828182845904523536028747 ## Euler's number
|
||||||
|
|
||||||
type
|
type
|
||||||
TFloatClass* = enum ## describes the class a floating point value belongs to.
|
TFloatClass* = enum ## describes the class a floating point value belongs to.
|
||||||
## This is the type that is returned by `classify`.
|
## This is the type that is returned by `classify`.
|
||||||
|
|
@ -35,7 +39,7 @@ proc classify*(x: float): TFloatClass =
|
||||||
|
|
||||||
# ECMAScript and most C compilers have no classify:
|
# ECMAScript and most C compilers have no classify:
|
||||||
if x == 0.0:
|
if x == 0.0:
|
||||||
if 1.0/x == 1.0/0.0:
|
if 1.0/x == Inf:
|
||||||
return fcZero
|
return fcZero
|
||||||
else:
|
else:
|
||||||
return fcNegZero
|
return fcNegZero
|
||||||
|
|
@ -129,7 +133,7 @@ when not defined(ECMAScript):
|
||||||
proc rand(): cint {.importc: "rand", nodecl.}
|
proc rand(): cint {.importc: "rand", nodecl.}
|
||||||
|
|
||||||
proc randomize() = srand(gettime(nil))
|
proc randomize() = srand(gettime(nil))
|
||||||
proc random(max: int): int = return rand() mod max
|
proc random(max: int): int = return int(rand()) mod max
|
||||||
|
|
||||||
else:
|
else:
|
||||||
proc mathrandom(): float {.importc: "Math.random", nodecl.}
|
proc mathrandom(): float {.importc: "Math.random", nodecl.}
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,7 @@ else:
|
||||||
# the fact that the OS is likely to give us pages with contingous numbers.
|
# the fact that the OS is likely to give us pages with contingous numbers.
|
||||||
# A page contains either small fixed size objects of the same size or
|
# A page contains either small fixed size objects of the same size or
|
||||||
# variable length objects. An object's size is always aligned at 16 byte
|
# variable length objects. An object's size is always aligned at 16 byte
|
||||||
# boundry. Huge objects are dealt with the TLSF algorithm.
|
# boundary. Huge objects are dealt with the TLSF algorithm.
|
||||||
# The design supports iterating over any object in a fast way.
|
# The design supports iterating over any object in a fast way.
|
||||||
|
|
||||||
# A bitset contains any page that starts an allocated page. The page may be
|
# A bitset contains any page that starts an allocated page. The page may be
|
||||||
|
|
@ -230,6 +230,7 @@ type
|
||||||
zct: TCellArray
|
zct: TCellArray
|
||||||
stackCells: TCellArray
|
stackCells: TCellArray
|
||||||
smallBlocks: array [PageSize div MemAlign, ptr TPageDesc]
|
smallBlocks: array [PageSize div MemAlign, ptr TPageDesc]
|
||||||
|
freeLists: array [PageSize div MemAlign, ptr TFreeList]
|
||||||
pages: TPageManager
|
pages: TPageManager
|
||||||
usedPages: TPageList
|
usedPages: TPageList
|
||||||
freePages: TPageList
|
freePages: TPageList
|
||||||
|
|
@ -237,6 +238,11 @@ type
|
||||||
# small blocks:
|
# small blocks:
|
||||||
proc allocSmall(var h: TGcHeap, size: int): pointer =
|
proc allocSmall(var h: TGcHeap, size: int): pointer =
|
||||||
var s = align(size)
|
var s = align(size)
|
||||||
|
var f = h.freeLists[s]
|
||||||
|
if f != nil:
|
||||||
|
f.prev = f.next # remove from list
|
||||||
|
f.next.prev = f.prev
|
||||||
|
return f
|
||||||
var p = h.smallBlocks[s]
|
var p = h.smallBlocks[s]
|
||||||
if p == nil or p.free == nil:
|
if p == nil or p.free == nil:
|
||||||
p = newSmallBlock(s, p)
|
p = newSmallBlock(s, p)
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@
|
||||||
#ifndef NIMBASE_H
|
#ifndef NIMBASE_H
|
||||||
#define NIMBASE_H
|
#define NIMBASE_H
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
/* calling convention mess ----------------------------------------------- */
|
/* calling convention mess ----------------------------------------------- */
|
||||||
#if defined(__GNUC__) || defined(__LCC__) || defined(__POCC__) \
|
#if defined(__GNUC__) || defined(__LCC__) || defined(__POCC__) \
|
||||||
|| defined(__TINYC__)
|
|| defined(__TINYC__)
|
||||||
|
|
@ -37,12 +39,16 @@
|
||||||
|
|
||||||
#if defined(__POCC__)
|
#if defined(__POCC__)
|
||||||
# define NIM_CONST /* PCC is really picky with const modifiers */
|
# define NIM_CONST /* PCC is really picky with const modifiers */
|
||||||
|
# undef _MSC_VER /* Yeah, right PCC defines _MSC_VER even if it is
|
||||||
|
not that compatible. Well done. */
|
||||||
#elif defined(__cplusplus)
|
#elif defined(__cplusplus)
|
||||||
# define NIM_CONST /* C++ is picky with const modifiers */
|
# define NIM_CONST /* C++ is picky with const modifiers */
|
||||||
#else
|
#else
|
||||||
# define NIM_CONST const
|
# define NIM_CONST const
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define NIM_THREADVAR __thread
|
||||||
|
|
||||||
/* --------------- how int64 constants should be declared: ----------- */
|
/* --------------- how int64 constants should be declared: ----------- */
|
||||||
#if defined(__GNUC__) || defined(__LCC__) || \
|
#if defined(__GNUC__) || defined(__LCC__) || \
|
||||||
defined(__POCC__) || defined(__DMC__)
|
defined(__POCC__) || defined(__DMC__)
|
||||||
|
|
@ -51,6 +57,14 @@
|
||||||
# define IL64(x) x
|
# define IL64(x) x
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* ---------------- casting without correct aliasing rules ----------- */
|
||||||
|
|
||||||
|
#if defined(__GNUCC__)
|
||||||
|
# define NIM_CAST(type, ptr) (((union{type __x__;}*)(ptr))->__x__)
|
||||||
|
#else
|
||||||
|
# define NIM_CAST(type, ptr) ((type)(ptr))
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------- */
|
||||||
|
|
||||||
#if defined(WIN32) || defined(_WIN32) /* only Windows has this mess... */
|
#if defined(WIN32) || defined(_WIN32) /* only Windows has this mess... */
|
||||||
|
|
@ -94,6 +108,16 @@
|
||||||
#define N_CLOSURE_PTR(rettype, name) rettype (*name)
|
#define N_CLOSURE_PTR(rettype, name) rettype (*name)
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__GNUC__) || defined(__ICC__)
|
||||||
|
# define N_NOINLINE(rettype, name) rettype __attribute__((noinline)) name
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
# define N_NOINLINE(rettype, name) __declspec(noinline) rettype name
|
||||||
|
#else
|
||||||
|
# define N_NOINLINE(rettype, name) rettype name
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define N_NOINLINE_PTR(rettype, name) rettype (*name)
|
||||||
|
|
||||||
#if defined(__BORLANDC__) || defined(__WATCOMC__) || \
|
#if defined(__BORLANDC__) || defined(__WATCOMC__) || \
|
||||||
defined(__POCC__) || defined(_MSC_VER)
|
defined(__POCC__) || defined(_MSC_VER)
|
||||||
/* these compilers have a fastcall so use it: */
|
/* these compilers have a fastcall so use it: */
|
||||||
|
|
@ -164,13 +188,10 @@
|
||||||
# define _ISOC99_SOURCE 1
|
# define _ISOC99_SOURCE 1
|
||||||
# define __USE_ISOC9X 1
|
# define __USE_ISOC9X 1
|
||||||
# define __USE_ISOC99 1
|
# define __USE_ISOC99 1
|
||||||
# include <math.h>
|
|
||||||
|
|
||||||
#elif (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) \
|
#elif (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) \
|
||||||
&& !defined(__BORLANDC__) && !defined(__POCC__)
|
&& !defined(__BORLANDC__) && !defined(__POCC__)
|
||||||
|
|
||||||
# include <math.h>
|
|
||||||
|
|
||||||
/* Win32 doesn't seem to have these functions.
|
/* Win32 doesn't seem to have these functions.
|
||||||
** Therefore implement inline versions of these functions here.
|
** Therefore implement inline versions of these functions here.
|
||||||
*/
|
*/
|
||||||
|
|
@ -194,8 +215,6 @@ static N_INLINE(long int, lrintf)(float flt) {
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
# include <math.h>
|
|
||||||
|
|
||||||
# ifndef lrint
|
# ifndef lrint
|
||||||
# define lrint(dbl) ((long int)(dbl))
|
# define lrint(dbl) ((long int)(dbl))
|
||||||
# endif
|
# endif
|
||||||
|
|
@ -214,11 +233,6 @@ static N_INLINE(long int, lrintf)(float flt) {
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
|
||||||
#ifndef NAN
|
|
||||||
static unsigned long nimNaN[2]={0xffffffff, 0x7fffffff};
|
|
||||||
# define NAN (*(double*) nimNaN)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#ifndef INF
|
#ifndef INF
|
||||||
static unsigned long nimInf[2]={0xffffffff, 0x7fffffff};
|
static unsigned long nimInf[2]={0xffffffff, 0x7fffffff};
|
||||||
|
|
@ -241,8 +255,7 @@ __TINYC__
|
||||||
# define HAVE_STDINT_H
|
# define HAVE_STDINT_H
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__LCC__) || defined(__GNUC__) || defined(__DMC__) \
|
#if defined(__LCC__) || defined(__DMC__) || defined(__POCC__)
|
||||||
|| defined(__POCC__)
|
|
||||||
# define HAVE_STDINT_H
|
# define HAVE_STDINT_H
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -328,14 +341,16 @@ static N_INLINE(NI32, float32ToInt32)(float val) {
|
||||||
return float64ToInt32((double)val);
|
return float64ToInt32((double)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define float64ToInt64(x) ((NI64) (x))
|
||||||
|
|
||||||
#define zeroMem(a, size) memset(a, 0, size)
|
#define zeroMem(a, size) memset(a, 0, size)
|
||||||
#define equalMem(a, b, size) (memcmp(a, b, size) == 0)
|
#define equalMem(a, b, size) (memcmp(a, b, size) == 0)
|
||||||
|
|
||||||
#define STRING_LITERAL(name, str, length) \
|
#define STRING_LITERAL(name, str, length) \
|
||||||
static const struct { \
|
static const struct { \
|
||||||
NI len, space; \
|
TGenericSeq Sup; \
|
||||||
NIM_CHAR data[length + 1]; \
|
NIM_CHAR data[length + 1]; \
|
||||||
} name = {length, length, str}
|
} name = {{length, length}, str}
|
||||||
|
|
||||||
typedef struct TStringDesc* string;
|
typedef struct TStringDesc* string;
|
||||||
|
|
||||||
|
|
@ -352,6 +367,13 @@ typedef struct TStringDesc* string;
|
||||||
#define GenericSeqSize sizeof(TGenericSeq)
|
#define GenericSeqSize sizeof(TGenericSeq)
|
||||||
#define paramCount() cmdCount
|
#define paramCount() cmdCount
|
||||||
|
|
||||||
|
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__i386__)
|
||||||
|
# ifndef NAN
|
||||||
|
static unsigned long nimNaN[2]={0xffffffff, 0x7fffffff};
|
||||||
|
# define NAN (*(double*) nimNaN)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef NAN
|
#ifndef NAN
|
||||||
# define NAN (0.0 / 0.0)
|
# define NAN (0.0 / 0.0)
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -399,6 +421,7 @@ struct NimException {
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
typedef struct TStringDesc {
|
typedef struct TStringDesc {
|
||||||
NI len;
|
NI len;
|
||||||
NI space;
|
NI space;
|
||||||
|
|
@ -410,5 +433,6 @@ typedef struct {
|
||||||
} TGenericSeq;
|
} TGenericSeq;
|
||||||
|
|
||||||
typedef TGenericSeq* PGenericSeq;
|
typedef TGenericSeq* PGenericSeq;
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
648
lib/os.nim
648
lib/os.nim
|
|
@ -7,14 +7,12 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
## Basic operating system facilities like retrieving environment variables,
|
## This module contains basic operating system facilities like
|
||||||
## reading command line arguments, working with directories, running shell
|
## retrieving environment variables, reading command line arguments,
|
||||||
## commands, etc. This module is -- like any other basic library --
|
## working with directories, running shell commands, etc.
|
||||||
## platform independant. However, the ECMAScript target is not supported,
|
## This module is -- like any other basic library -- platform independant.
|
||||||
## as there is no way to perform these operations in ECMAScript portably
|
|
||||||
## or at all.
|
|
||||||
|
|
||||||
{.push debugger:off.}
|
{.push debugger: off.}
|
||||||
|
|
||||||
import
|
import
|
||||||
strutils, times
|
strutils, times
|
||||||
|
|
@ -28,8 +26,9 @@ template newException(exceptn, message: expr): expr =
|
||||||
e.msg = message
|
e.msg = message
|
||||||
e
|
e
|
||||||
|
|
||||||
when defined(windows) or defined(OS2) or defined(DOS):
|
const
|
||||||
{.define: doslike.} # DOS-like filesystem
|
doslike = defined(windows) or defined(OS2) or defined(DOS)
|
||||||
|
# DOS-like filesystem
|
||||||
|
|
||||||
when defined(Nimdoc): # only for proper documentation:
|
when defined(Nimdoc): # only for proper documentation:
|
||||||
const
|
const
|
||||||
|
|
@ -69,6 +68,14 @@ when defined(Nimdoc): # only for proper documentation:
|
||||||
## True if the file system is case sensitive, false otherwise. Used by
|
## True if the file system is case sensitive, false otherwise. Used by
|
||||||
## `cmpPaths` to compare filenames properly.
|
## `cmpPaths` to compare filenames properly.
|
||||||
|
|
||||||
|
ExeExt* = ""
|
||||||
|
## The file extension of native executables. For example:
|
||||||
|
## "" on UNIX, "exe" on Windows.
|
||||||
|
|
||||||
|
ScriptExt* = ""
|
||||||
|
## The file extension of a script file. For example: "" on UNIX,
|
||||||
|
## "bat" on Windows.
|
||||||
|
|
||||||
elif defined(macos):
|
elif defined(macos):
|
||||||
const
|
const
|
||||||
curdir* = ':'
|
curdir* = ':'
|
||||||
|
|
@ -77,6 +84,8 @@ elif defined(macos):
|
||||||
altsep* = dirsep
|
altsep* = dirsep
|
||||||
pathsep* = ','
|
pathsep* = ','
|
||||||
FileSystemCaseSensitive* = false
|
FileSystemCaseSensitive* = false
|
||||||
|
ExeExt* = ""
|
||||||
|
ScriptExt* = ""
|
||||||
|
|
||||||
# MacOS paths
|
# MacOS paths
|
||||||
# ===========
|
# ===========
|
||||||
|
|
@ -96,7 +105,7 @@ elif defined(macos):
|
||||||
# waterproof. In case of equal names the first volume found will do.
|
# waterproof. In case of equal names the first volume found will do.
|
||||||
# Two colons "::" are the relative path to the parent. Three is to the
|
# Two colons "::" are the relative path to the parent. Three is to the
|
||||||
# grandparent etc.
|
# grandparent etc.
|
||||||
elif defined(doslike):
|
elif doslike:
|
||||||
const
|
const
|
||||||
curdir* = '.'
|
curdir* = '.'
|
||||||
pardir* = ".."
|
pardir* = ".."
|
||||||
|
|
@ -104,6 +113,8 @@ elif defined(doslike):
|
||||||
altsep* = '/'
|
altsep* = '/'
|
||||||
pathSep* = ';' # seperator between paths
|
pathSep* = ';' # seperator between paths
|
||||||
FileSystemCaseSensitive* = false
|
FileSystemCaseSensitive* = false
|
||||||
|
ExeExt* = "exe"
|
||||||
|
ScriptExt* = "bat"
|
||||||
elif defined(PalmOS) or defined(MorphOS):
|
elif defined(PalmOS) or defined(MorphOS):
|
||||||
const
|
const
|
||||||
dirsep* = '/'
|
dirsep* = '/'
|
||||||
|
|
@ -111,6 +122,8 @@ elif defined(PalmOS) or defined(MorphOS):
|
||||||
PathSep* = ';'
|
PathSep* = ';'
|
||||||
pardir* = ".."
|
pardir* = ".."
|
||||||
FileSystemCaseSensitive* = false
|
FileSystemCaseSensitive* = false
|
||||||
|
ExeExt* = ""
|
||||||
|
ScriptExt* = ""
|
||||||
elif defined(RISCOS):
|
elif defined(RISCOS):
|
||||||
const
|
const
|
||||||
dirsep* = '.'
|
dirsep* = '.'
|
||||||
|
|
@ -118,6 +131,8 @@ elif defined(RISCOS):
|
||||||
pardir* = ".." # is this correct?
|
pardir* = ".." # is this correct?
|
||||||
pathSep* = ','
|
pathSep* = ','
|
||||||
FileSystemCaseSensitive* = true
|
FileSystemCaseSensitive* = true
|
||||||
|
ExeExt* = ""
|
||||||
|
ScriptExt* = ""
|
||||||
else: # UNIX-like operating system
|
else: # UNIX-like operating system
|
||||||
const
|
const
|
||||||
curdir* = '.'
|
curdir* = '.'
|
||||||
|
|
@ -126,6 +141,8 @@ else: # UNIX-like operating system
|
||||||
altsep* = dirsep
|
altsep* = dirsep
|
||||||
pathSep* = ':'
|
pathSep* = ':'
|
||||||
FileSystemCaseSensitive* = true
|
FileSystemCaseSensitive* = true
|
||||||
|
ExeExt* = ""
|
||||||
|
ScriptExt* = ""
|
||||||
|
|
||||||
const
|
const
|
||||||
ExtSep* = '.'
|
ExtSep* = '.'
|
||||||
|
|
@ -133,26 +150,26 @@ const
|
||||||
## for example, the '.' in ``os.nim``.
|
## for example, the '.' in ``os.nim``.
|
||||||
|
|
||||||
proc getApplicationDir*(): string {.noSideEffect.}
|
proc getApplicationDir*(): string {.noSideEffect.}
|
||||||
## Gets the directory of the application's executable.
|
## Returns the directory of the application's executable.
|
||||||
|
|
||||||
proc getApplicationFilename*(): string {.noSideEffect.}
|
proc getApplicationFilename*(): string {.noSideEffect.}
|
||||||
## Gets the filename of the application's executable.
|
## Returns the filename of the application's executable.
|
||||||
|
|
||||||
proc getCurrentDir*(): string {.noSideEffect.}
|
proc getCurrentDir*(): string {.noSideEffect.}
|
||||||
## Gets the current working directory.
|
## Returns the current working directory.
|
||||||
|
|
||||||
proc setCurrentDir*(newDir: string) {.inline.}
|
proc setCurrentDir*(newDir: string) {.inline.}
|
||||||
## Sets the current working directory; `EOS` is raised if
|
## Sets the current working directory; `EOS` is raised if
|
||||||
## `newDir` cannot been set.
|
## `newDir` cannot been set.
|
||||||
|
|
||||||
proc getHomeDir*(): string {.noSideEffect.}
|
proc getHomeDir*(): string {.noSideEffect.}
|
||||||
## Gets the home directory of the current user.
|
## Returns the home directory of the current user.
|
||||||
|
|
||||||
proc getConfigDir*(): string {.noSideEffect.}
|
proc getConfigDir*(): string {.noSideEffect.}
|
||||||
## Gets the config directory of the current user for applications.
|
## Returns the config directory of the current user for applications.
|
||||||
|
|
||||||
proc expandFilename*(filename: string): string
|
proc expandFilename*(filename: string): string
|
||||||
## Returns the full path of `filename`, "" on error.
|
## Returns the full path of `filename`, raises EOS in case of an error.
|
||||||
|
|
||||||
proc ExistsFile*(filename: string): bool
|
proc ExistsFile*(filename: string): bool
|
||||||
## Returns true if the file exists, false otherwise.
|
## Returns true if the file exists, false otherwise.
|
||||||
|
|
@ -216,13 +233,26 @@ proc SplitFilename*(filename: string, name, extension: var string) {.
|
||||||
## It the file has no extension, extention is the empty string.
|
## It the file has no extension, extention is the empty string.
|
||||||
|
|
||||||
proc extractDir*(path: string): string {.noSideEffect.}
|
proc extractDir*(path: string): string {.noSideEffect.}
|
||||||
## Extracts the directory of a given path. This is the `head`
|
## Extracts the directory of a given path. This is almost the
|
||||||
## result of `splitPath`.
|
## same as the `head` result of `splitPath`, except that
|
||||||
|
## ``extractDir("/usr/lib/") == "/usr/lib/"``.
|
||||||
|
|
||||||
proc extractFilename*(path: string): string {.noSideEffect.}
|
proc extractFilename*(path: string): string {.noSideEffect.}
|
||||||
## Extracts the filename of a given `path`. This the the `tail`
|
## Extracts the filename of a given `path`. This is almost the
|
||||||
## result of `splitPath`.
|
## same as the `tail` result of `splitPath`, except that
|
||||||
# XXX: this is not true: /usr/lib/ --> filename should be empty!
|
## ``extractFilename("/usr/lib/") == ""``.
|
||||||
|
|
||||||
|
proc extractFileExt*(filename: string): string {.noSideEffect.} =
|
||||||
|
## Extracts the file extension of a given `filename`. This is the
|
||||||
|
## same as the `extension` result of `splitFilename`.
|
||||||
|
var dummy: string
|
||||||
|
splitFilename(filename, dummy, result)
|
||||||
|
|
||||||
|
proc extractFileTrunk*(filename: string): string {.noSideEffect.} =
|
||||||
|
## Extracts the file name of a given `filename`. This removes any
|
||||||
|
## directory information and the file extension.
|
||||||
|
var dummy: string
|
||||||
|
splitFilename(extractFilename(filename), result, dummy)
|
||||||
|
|
||||||
proc cmpPaths*(pathA, pathB: string): int {.noSideEffect.}
|
proc cmpPaths*(pathA, pathB: string): int {.noSideEffect.}
|
||||||
## Compares two paths.
|
## Compares two paths.
|
||||||
|
|
@ -251,28 +281,23 @@ proc ChangeFileExt*(filename, ext: string): string {.noSideEffect.}
|
||||||
## filesystems may use a different character. (Although I know
|
## filesystems may use a different character. (Although I know
|
||||||
## of none such beast.)
|
## of none such beast.)
|
||||||
|
|
||||||
# procs dealing with processes:
|
|
||||||
proc executeProcess*(command: string): int
|
|
||||||
## Executes a process.
|
|
||||||
##
|
|
||||||
## Command has the form 'program args' where args are the command
|
|
||||||
## line arguments given to program. The proc returns the error code
|
|
||||||
## of the process when it has finished. The proc does not return
|
|
||||||
## until the process has finished.
|
|
||||||
|
|
||||||
proc executeShellCommand*(command: string): int
|
proc executeShellCommand*(command: string): int
|
||||||
## Executes a shell command.
|
## Executes a shell command.
|
||||||
##
|
##
|
||||||
## The syntax of the command is unspecified and depends on the used
|
## Command has the form 'program args' where args are the command
|
||||||
## shell. The proc returns the error code of the shell when it has finished.
|
## line arguments given to program. The proc returns the error code
|
||||||
|
## of the shell when it has finished. The proc does not return until
|
||||||
|
## the process has finished. To execute a program without having a
|
||||||
|
## shell involved, use the `executeProcess` proc of the `osproc`
|
||||||
|
## module.
|
||||||
|
|
||||||
# procs operating on a high level for files:
|
# procs operating on a high level for files:
|
||||||
proc copyFile*(dest, source: string)
|
proc copyFile*(dest, source: string)
|
||||||
## Copies a file from `dest` to `source`. If this fails,
|
## Copies a file from `source` to `dest`. If this fails,
|
||||||
## `EOS` is raised.
|
## `EOS` is raised.
|
||||||
|
|
||||||
proc moveFile*(dest, source: string)
|
proc moveFile*(dest, source: string)
|
||||||
## Moves a file from `dest` to `source`. If this fails, `EOS` is raised.
|
## Moves a file from `source` to `dest`. If this fails, `EOS` is raised.
|
||||||
|
|
||||||
proc removeFile*(file: string)
|
proc removeFile*(file: string)
|
||||||
## Removes the `file`. If this fails, `EOS` is raised.
|
## Removes the `file`. If this fails, `EOS` is raised.
|
||||||
|
|
@ -294,10 +319,10 @@ proc existsDir*(dir: string): bool
|
||||||
## is returned.
|
## is returned.
|
||||||
|
|
||||||
proc getLastModificationTime*(file: string): TTime
|
proc getLastModificationTime*(file: string): TTime
|
||||||
## Gets the time of the `file`'s last modification.
|
## Returns the time of the `file`'s last modification.
|
||||||
|
|
||||||
proc fileNewer*(a, b: string): bool
|
proc fileNewer*(a, b: string): bool
|
||||||
## returns true if the file `a` is newer than file `b`, i.e. if `a`'s
|
## Returns true if the file `a` is newer than file `b`, i.e. if `a`'s
|
||||||
## modification time is later than `b`'s.
|
## modification time is later than `b`'s.
|
||||||
|
|
||||||
# procs dealing with environment variables:
|
# procs dealing with environment variables:
|
||||||
|
|
@ -306,7 +331,7 @@ proc putEnv*(key, val: string)
|
||||||
## If an error occurs, `EInvalidEnvVar` is raised.
|
## If an error occurs, `EInvalidEnvVar` is raised.
|
||||||
|
|
||||||
proc getEnv*(key: string): string
|
proc getEnv*(key: string): string
|
||||||
## Gets the value of the environment variable named `key`.
|
## Returns the value of the environment variable named `key`.
|
||||||
##
|
##
|
||||||
## If the variable does not exist, "" is returned. To distinguish
|
## If the variable does not exist, "" is returned. To distinguish
|
||||||
## whether a variable exists or it's value is just "", call
|
## whether a variable exists or it's value is just "", call
|
||||||
|
|
@ -328,6 +353,43 @@ proc paramStr*(i: int): string
|
||||||
## `i` should be in the range `1..paramCount()`, else
|
## `i` should be in the range `1..paramCount()`, else
|
||||||
## the `EOutOfIndex` exception is raised.
|
## the `EOutOfIndex` exception is raised.
|
||||||
|
|
||||||
|
when defined(windows):
|
||||||
|
proc GetLastError(): int32 {.importc, stdcall, dynlib: "kernel32".}
|
||||||
|
proc FormatMessageA(dwFlags: int32, lpSource: pointer,
|
||||||
|
dwMessageId, dwLanguageId: int32,
|
||||||
|
lpBuffer: pointer, nSize: int32,
|
||||||
|
Arguments: pointer): int32 {.
|
||||||
|
importc, stdcall, dynlib: "kernel32".}
|
||||||
|
proc LocalFree(p: pointer) {.importc, stdcall, dynlib: "kernel32".}
|
||||||
|
|
||||||
|
var errno {.importc, header: "<errno.h>".}: cint ## error variable
|
||||||
|
proc strerror(errnum: cint): cstring {.importc, header: "<string.h>".}
|
||||||
|
|
||||||
|
proc OSError*(msg: string = "") {.noinline.} =
|
||||||
|
## 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.
|
||||||
|
if len(msg) == 0:
|
||||||
|
when defined(Windows):
|
||||||
|
var err = GetLastError()
|
||||||
|
if err != 0'i32:
|
||||||
|
# sigh, why is this is so difficult?
|
||||||
|
var msgbuf: cstring
|
||||||
|
if FormatMessageA(0x00000100 or 0x00001000 or 0x00000200,
|
||||||
|
nil, err, 0, addr(msgbuf), 0, nil) != 0'i32:
|
||||||
|
var m = $msgbuf
|
||||||
|
if msgbuf != nil:
|
||||||
|
LocalFree(msgbuf)
|
||||||
|
raise newException(EOS, m)
|
||||||
|
if errno != 0'i32:
|
||||||
|
raise newException(EOS, $strerror(errno))
|
||||||
|
else:
|
||||||
|
raise newException(EOS, "unknown OS error")
|
||||||
|
else:
|
||||||
|
raise newException(EOS, msg)
|
||||||
|
|
||||||
# implementation
|
# implementation
|
||||||
|
|
||||||
proc UnixToNativePath(path: string): string =
|
proc UnixToNativePath(path: string): string =
|
||||||
|
|
@ -337,7 +399,7 @@ proc UnixToNativePath(path: string): string =
|
||||||
var start: int
|
var start: int
|
||||||
if path[0] == '/':
|
if path[0] == '/':
|
||||||
# an absolute path
|
# an absolute path
|
||||||
when defined(doslike):
|
when doslike:
|
||||||
result = r"C:\"
|
result = r"C:\"
|
||||||
elif defined(macos):
|
elif defined(macos):
|
||||||
result = "" # must not start with ':'
|
result = "" # must not start with ':'
|
||||||
|
|
@ -368,7 +430,7 @@ proc UnixToNativePath(path: string): string =
|
||||||
add result, dirSep
|
add result, dirSep
|
||||||
inc(i)
|
inc(i)
|
||||||
else:
|
else:
|
||||||
add result, $path[i]
|
add result, path[i]
|
||||||
inc(i)
|
inc(i)
|
||||||
|
|
||||||
# interface to C library:
|
# interface to C library:
|
||||||
|
|
@ -377,7 +439,8 @@ const
|
||||||
cunder = if defined(pcc): "_" else: ""
|
cunder = if defined(pcc): "_" else: ""
|
||||||
|
|
||||||
type
|
type
|
||||||
TStat {.importc: "struct " & cunder & "stat", final.} = object
|
TStat {.importc: "struct " & cunder & "stat",
|
||||||
|
header: "<sys/stat.h>", pure.} = object
|
||||||
st_dev: int16
|
st_dev: int16
|
||||||
st_ino: int16
|
st_ino: int16
|
||||||
st_mode: int16
|
st_mode: int16
|
||||||
|
|
@ -390,60 +453,56 @@ type
|
||||||
st_mtime: TTime
|
st_mtime: TTime
|
||||||
st_ctime: TTime
|
st_ctime: TTime
|
||||||
|
|
||||||
var
|
|
||||||
errno {.importc: "errno", header: "<errno.h>".}: cint
|
when defined(unix):
|
||||||
|
var
|
||||||
EEXIST {.importc: "EEXIST", header: "<errno.h>".}: cint
|
EEXIST {.importc: "EEXIST", header: "<errno.h>".}: cint
|
||||||
|
|
||||||
when defined(unix):
|
|
||||||
const dirHeader = "<sys/stat.h>"
|
|
||||||
elif defined(windows):
|
|
||||||
const dirHeader = "<direct.h>"
|
|
||||||
else:
|
|
||||||
{.error: "os library not ported to your OS. Please help!".}
|
|
||||||
|
|
||||||
|
|
||||||
proc chdir(path: CString): cint {.
|
|
||||||
importc: cunder & "chdir", header: dirHeader.}
|
|
||||||
|
|
||||||
when defined(unix):
|
|
||||||
proc mkdir(dir: CString, theAccess: cint): cint {.
|
proc mkdir(dir: CString, theAccess: cint): cint {.
|
||||||
importc: "mkdir", header: dirHeader.}
|
importc: "mkdir", header: "<sys/stat.h>".}
|
||||||
proc realpath(name, resolved: CString): CString {.
|
proc realpath(name, resolved: CString): CString {.
|
||||||
importc: "realpath", header: "<stdlib.h>".}
|
importc: "realpath", header: "<stdlib.h>".}
|
||||||
proc getcwd(buf: CString, buflen: cint): CString {.
|
proc getcwd(buf: CString, buflen: cint): CString {.
|
||||||
importc: "getcwd", header: "<unistd.h>".}
|
importc: "getcwd", header: "<unistd.h>".}
|
||||||
elif defined(windows):
|
proc chdir(path: CString): cint {.
|
||||||
proc mkdir(dir: CString): cint {.
|
importc: "chdir", header: "<unistd.h>".}
|
||||||
importc: "mkdir", header: dirHeader.}
|
proc rmdir(dir: CString): cint {.
|
||||||
proc fullpath(buffer, file: CString, size: int): CString {.
|
importc: "rmdir", header: "<unistd.h>".}
|
||||||
importc: "_fullpath", header: "<stdlib.h>".}
|
|
||||||
proc getcwd(buf: CString, buflen: cint): CString {.
|
|
||||||
importc: cunder & "getcwd", header: "<direct.h>".}
|
|
||||||
|
|
||||||
proc CreateDirectory(pathName: cstring, security: Pointer): cint {.
|
# is in <stdlib.h>:
|
||||||
importc: "CreateDirectory", header: "<windows.h>".}
|
proc cputenv(env: CString): cint {.importc: "putenv", noDecl.}
|
||||||
proc GetLastError(): cint {.importc, header: "<windows.h>".}
|
|
||||||
|
elif defined(windows):
|
||||||
|
proc GetCurrentDirectoryA(nBufferLength: int32, lpBuffer: cstring): int32 {.
|
||||||
|
importc, dynlib: "kernel32", stdcall.}
|
||||||
|
proc SetCurrentDirectoryA(lpPathName: cstring): int32 {.
|
||||||
|
importc, dynlib: "kernel32", stdcall.}
|
||||||
|
proc CreateDirectoryA(pathName: cstring, security: Pointer): int32 {.
|
||||||
|
importc: "CreateDirectoryA", dynlib: "kernel32", stdcall.}
|
||||||
|
proc RemoveDirectoryA(lpPathName: cstring): int32 {.
|
||||||
|
importc, dynlib: "kernel32", stdcall.}
|
||||||
|
proc SetEnvironmentVariableA(lpName, lpValue: cstring): int32 {.
|
||||||
|
stdcall, dynlib: "kernel32", importc.}
|
||||||
else:
|
else:
|
||||||
{.error: "os library not ported to your OS. Please help!".}
|
{.error: "os library not ported to your OS. Please help!".}
|
||||||
|
|
||||||
|
|
||||||
proc rmdir(dir: CString): cint {.
|
|
||||||
importc: cunder & "rmdir", header: "<time.h>".}
|
|
||||||
# rmdir is of course in ``dirHeader``, but we check here to include
|
|
||||||
# time.h which is needed for stat(). stat() needs time.h and
|
|
||||||
# sys/stat.h; we workaround a C library issue here.
|
|
||||||
|
|
||||||
proc free(c: cstring) {.importc: "free", nodecl.}
|
when defined(unix):
|
||||||
|
proc free(c: cstring) {.importc: "free", nodecl.}
|
||||||
# some C procs return a buffer that has to be freed with free(),
|
# some C procs return a buffer that has to be freed with free(),
|
||||||
# so we define it here
|
# so we define it here
|
||||||
proc strlen(str: CString): int {.importc: "strlen", nodecl.}
|
proc strlen(str: CString): int {.importc: "strlen", nodecl.}
|
||||||
|
|
||||||
proc stat(f: CString, res: var TStat): cint {.
|
proc stat(f: CString, res: var TStat): cint {.
|
||||||
importc: cunder & "stat", header: "<sys/stat.h>".}
|
importc: cunder & "stat", header: "<time.h>".}
|
||||||
|
# stat is of course in ``<sys/stat.h>``, but I include
|
||||||
|
# time.h which is needed for stat() too. stat() needs both time.h and
|
||||||
|
# sys/stat.h.
|
||||||
|
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
proc getModuleFilename(handle: int32, buf: CString, size: int32): int32 {.
|
proc GetModuleFileNameA(handle: int32, buf: CString, size: int32): int32 {.
|
||||||
importc: "GetModuleFileName", header: "<windows.h>".}
|
importc, dynlib: "kernel32", stdcall.}
|
||||||
|
|
||||||
proc getLastModificationTime(file: string): TTime =
|
proc getLastModificationTime(file: string): TTime =
|
||||||
var
|
var
|
||||||
|
|
@ -452,11 +511,12 @@ proc getLastModificationTime(file: string): TTime =
|
||||||
return res.st_mtime
|
return res.st_mtime
|
||||||
|
|
||||||
proc setCurrentDir(newDir: string) =
|
proc setCurrentDir(newDir: string) =
|
||||||
if chdir(newDir) != 0:
|
when defined(Windows):
|
||||||
raise newException(EOS, "cannot change the working directory to '$1'" %
|
if SetCurrentDirectoryA(newDir) == 0'i32: OSError()
|
||||||
newDir)
|
else:
|
||||||
|
if chdir(newDir) != 0'i32: OSError()
|
||||||
|
|
||||||
when defined(linux) or defined(solaris) or defined(bsd):
|
when defined(linux) or defined(solaris) or defined(bsd) or defined(aix):
|
||||||
proc readlink(link, buf: cstring, size: int): int {.
|
proc readlink(link, buf: cstring, size: int): int {.
|
||||||
header: "<unistd.h>", cdecl.}
|
header: "<unistd.h>", cdecl.}
|
||||||
|
|
||||||
|
|
@ -487,14 +547,14 @@ proc getApplicationFilename(): string =
|
||||||
# /proc/<pid>/file
|
# /proc/<pid>/file
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
result = newString(256)
|
result = newString(256)
|
||||||
var len = getModuleFileName(0, result, 256)
|
var len = getModuleFileNameA(0, result, 256)
|
||||||
setlen(result, int(len))
|
setlen(result, int(len))
|
||||||
elif defined(linux):
|
elif defined(linux) or defined(aix):
|
||||||
result = getApplAux("/proc/self/exe")
|
result = getApplAux("/proc/self/exe")
|
||||||
elif defined(solaris):
|
elif defined(solaris):
|
||||||
result = getApplAux("/proc/" & $getpid() & "/path/a.out")
|
result = getApplAux("/proc/" & $getpid() & "/path/a.out")
|
||||||
elif defined(bsd):
|
elif defined(bsd):
|
||||||
result = getApplAux("/proc/" & $getpid() & "file")
|
result = getApplAux("/proc/" & $getpid() & "/file")
|
||||||
elif defined(macosx):
|
elif defined(macosx):
|
||||||
var size: int32
|
var size: int32
|
||||||
getExecPath1(nil, size)
|
getExecPath1(nil, size)
|
||||||
|
|
@ -513,20 +573,22 @@ proc getApplicationFilename(): string =
|
||||||
var x = joinPath(p, result)
|
var x = joinPath(p, result)
|
||||||
if ExistsFile(x): return x
|
if ExistsFile(x): return x
|
||||||
|
|
||||||
{.push warnings: off.}
|
|
||||||
proc getApplicationDir(): string =
|
proc getApplicationDir(): string =
|
||||||
var tail: string
|
var tail: string
|
||||||
splitPath(getApplicationFilename(), result, tail)
|
splitPath(getApplicationFilename(), result, tail)
|
||||||
{.pop.}
|
|
||||||
|
|
||||||
proc getCurrentDir(): string =
|
proc getCurrentDir(): string =
|
||||||
const
|
const bufsize = 512 # should be enough
|
||||||
bufsize = 512 # should be enough
|
|
||||||
result = newString(bufsize)
|
result = newString(bufsize)
|
||||||
|
when defined(windows):
|
||||||
|
var L = GetCurrentDirectoryA(bufsize, result)
|
||||||
|
if L == 0'i32: OSError()
|
||||||
|
setLen(result, L)
|
||||||
|
else:
|
||||||
if getcwd(result, bufsize) != nil:
|
if getcwd(result, bufsize) != nil:
|
||||||
setlen(result, strlen(result))
|
setlen(result, strlen(result))
|
||||||
else:
|
else:
|
||||||
raise newException(EOS, "getcwd failed")
|
OSError()
|
||||||
|
|
||||||
proc JoinPath(head, tail: string): string =
|
proc JoinPath(head, tail: string): string =
|
||||||
if len(head) == 0:
|
if len(head) == 0:
|
||||||
|
|
@ -617,46 +679,65 @@ proc AppendFileExt(filename, ext: string): string =
|
||||||
proc csystem(cmd: CString): cint {.importc: "system", noDecl.}
|
proc csystem(cmd: CString): cint {.importc: "system", noDecl.}
|
||||||
# is in <stdlib.h>!
|
# is in <stdlib.h>!
|
||||||
|
|
||||||
when defined(wcc):
|
|
||||||
# everywhere it is in <stdlib.h>, except for Watcom C ...
|
|
||||||
proc cputenv(env: CString): cint {.importc: "putenv", header: "<process.h>".}
|
|
||||||
|
|
||||||
else: # is in <stdlib.h>
|
|
||||||
proc cputenv(env: CString): cint {.importc: cunder & "putenv", noDecl.}
|
|
||||||
|
|
||||||
proc cgetenv(env: CString): CString {.importc: "getenv", noDecl.}
|
proc cgetenv(env: CString): CString {.importc: "getenv", noDecl.}
|
||||||
|
|
||||||
#long _findfirst(char *, struct _finddata_t *);
|
|
||||||
#int _findnext(long, struct _finddata_t *);
|
|
||||||
#int _findclose(long);
|
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
|
const
|
||||||
|
FILE_ATTRIBUTE_DIRECTORY = 16
|
||||||
|
MAX_PATH = 260
|
||||||
type
|
type
|
||||||
TFindData {.importc: "struct _finddata_t", final.} = object
|
HANDLE = int
|
||||||
attrib {.importc: "attrib".}: cint
|
FILETIME {.pure.} = object
|
||||||
time_create {.importc: "time_create".}: cint
|
dwLowDateTime: int32
|
||||||
time_access {.importc: "time_access".}: cint
|
dwHighDateTime: int32
|
||||||
time_write {.importc: "time_write".}: cint
|
TWIN32_FIND_DATA {.pure.} = object
|
||||||
size {.importc: "size".}: cint
|
dwFileAttributes: int32
|
||||||
name {.importc: "name".}: array[0..259, char]
|
ftCreationTime: FILETIME
|
||||||
|
ftLastAccessTime: FILETIME
|
||||||
|
ftLastWriteTime: FILETIME
|
||||||
|
nFileSizeHigh: int32
|
||||||
|
nFileSizeLow: int32
|
||||||
|
dwReserved0: int32
|
||||||
|
dwReserved1: int32
|
||||||
|
cFileName: array[0..(MAX_PATH) - 1, char]
|
||||||
|
cAlternateFileName: array[0..13, char]
|
||||||
|
proc FindFirstFileA(lpFileName: cstring,
|
||||||
|
lpFindFileData: var TWIN32_FIND_DATA): HANDLE {.
|
||||||
|
stdcall, dynlib: "kernel32", importc: "FindFirstFileA".}
|
||||||
|
proc FindNextFileA(hFindFile: HANDLE,
|
||||||
|
lpFindFileData: var TWIN32_FIND_DATA): int32 {.
|
||||||
|
stdcall, dynlib: "kernel32", importc: "FindNextFileA".}
|
||||||
|
proc FindClose(hFindFile: HANDLE) {.stdcall, dynlib: "kernel32",
|
||||||
|
importc: "FindClose".}
|
||||||
|
|
||||||
|
proc GetFullPathNameA(lpFileName: cstring, nBufferLength: int32,
|
||||||
|
lpBuffer: cstring, lpFilePart: var cstring): int32 {.
|
||||||
|
stdcall, dynlib: "kernel32", importc.}
|
||||||
|
proc GetFileAttributesA(lpFileName: cstring): int32 {.
|
||||||
|
stdcall, dynlib: "kernel32", importc.}
|
||||||
|
|
||||||
proc findfirst(pathname: CString, f: ptr TFindData): cint {.
|
|
||||||
importc: "_findfirst", header: "<io.h>".}
|
|
||||||
proc findnext(handle: cint, f: ptr TFindData): cint {.
|
|
||||||
importc: "_findnext", header: "<io.h>".}
|
|
||||||
proc findclose(handle: cint) {.importc: "_findclose", header: "<io.h>".}
|
|
||||||
else:
|
else:
|
||||||
type
|
type
|
||||||
TFindData {.importc: "glob_t", final.} = object
|
TDIR {.importc: "DIR", header: "<dirent.h>", pure.} = object
|
||||||
|
TDirent {.importc: "struct dirent", header: "<dirent.h>", pure.} = object
|
||||||
|
d_name: array [0..255, char]
|
||||||
|
|
||||||
|
proc opendir(dir: cstring): ptr TDIR {.importc, header: "<dirent.h>".}
|
||||||
|
proc closedir(dir: ptr TDIR) {.importc, header: "<dirent.h>".}
|
||||||
|
proc readdir(dir: ptr TDIR): ptr TDirent {.importc, header: "<dirent.h>".}
|
||||||
|
|
||||||
|
type
|
||||||
|
TGlob {.importc: "glob_t", header: "<glob.h>", final, pure.} = object
|
||||||
gl_pathc: int # count of paths matched by pattern
|
gl_pathc: int # count of paths matched by pattern
|
||||||
gl_pathv: ptr array[0..1000_000, CString] # list of matched path names
|
gl_pathv: cstringArray # list of matched path names
|
||||||
gl_offs: int # slots to reserve at beginning of gl_pathv
|
gl_offs: int # slots to reserve at beginning of gl_pathv
|
||||||
PFindData = ptr TFindData
|
PGlob = ptr TGlob
|
||||||
|
|
||||||
proc glob(pattern: cstring, flags: cint, errfunc: pointer,
|
proc glob(pattern: cstring, flags: cint, errfunc: pointer,
|
||||||
pglob: PFindData): cint {.
|
pglob: PGlob): cint {.
|
||||||
importc: "glob", header: "<glob.h>".}
|
importc: "glob", header: "<glob.h>".}
|
||||||
|
|
||||||
proc globfree(pglob: PFindData) {.
|
proc globfree(pglob: PGlob) {.
|
||||||
importc: "globfree", header: "<glob.h>".}
|
importc: "globfree", header: "<glob.h>".}
|
||||||
|
|
||||||
proc sameFile*(path1, path2: string): bool =
|
proc sameFile*(path1, path2: string): bool =
|
||||||
|
|
@ -665,132 +746,149 @@ proc sameFile*(path1, path2: string): bool =
|
||||||
## Raises an exception if an os.stat() call on either pathname fails.
|
## Raises an exception if an os.stat() call on either pathname fails.
|
||||||
when defined(Windows):
|
when defined(Windows):
|
||||||
var
|
var
|
||||||
a, b: TFindData
|
a, b: TWin32FindData
|
||||||
var resA = findfirst(path1, addr(a))
|
var resA = findfirstFileA(path1, a)
|
||||||
var resB = findfirst(path2, addr(b))
|
var resB = findfirstFileA(path2, b)
|
||||||
if resA != -1 and resB != -1:
|
if resA != -1 and resB != -1:
|
||||||
result = $a.name == $b.name
|
result = $a.cFileName == $b.cFileName
|
||||||
else:
|
else:
|
||||||
# work around some ``findfirst`` bugs
|
# work around some ``findfirstFileA`` bugs
|
||||||
result = cmpPaths(path1, path2) == 0
|
result = cmpPaths(path1, path2) == 0
|
||||||
if resA != -1: findclose(resA)
|
if resA != -1: findclose(resA)
|
||||||
if resB != -1: findclose(resB)
|
if resB != -1: findclose(resB)
|
||||||
else:
|
else:
|
||||||
var
|
var
|
||||||
a, b: TStat
|
a, b: TStat
|
||||||
if stat(path1, a) < 0 or stat(path2, b) < 0:
|
if stat(path1, a) < 0'i32 or stat(path2, b) < 0'i32:
|
||||||
result = cmpPaths(path1, path2) == 0 # be consistent with Windows
|
result = cmpPaths(path1, path2) == 0 # be consistent with Windows
|
||||||
else:
|
else:
|
||||||
result = int(a.st_dev) == b.st_dev and int(a.st_ino) == b.st_ino
|
result = a.st_dev == b.st_dev and a.st_ino == b.st_ino
|
||||||
|
|
||||||
|
proc sameFileContent*(path1, path2: string): bool =
|
||||||
|
## Returns True if both pathname arguments refer to files with identical
|
||||||
|
## content. Content is compared byte for byte.
|
||||||
|
const
|
||||||
|
bufSize = 8192 # 8K buffer
|
||||||
|
var
|
||||||
|
a, b: TFile
|
||||||
|
if not openFile(a, path1): return false
|
||||||
|
if not openFile(b, path2):
|
||||||
|
closeFile(a)
|
||||||
|
return false
|
||||||
|
var bufA = alloc(bufsize)
|
||||||
|
var bufB = alloc(bufsize)
|
||||||
|
while True:
|
||||||
|
var readA = readBuffer(a, bufA, bufsize)
|
||||||
|
var readB = readBuffer(b, bufB, bufsize)
|
||||||
|
if readA != readB:
|
||||||
|
result = false
|
||||||
|
break
|
||||||
|
if readA == 0:
|
||||||
|
result = true
|
||||||
|
break
|
||||||
|
result = equalMem(bufA, bufB, readA)
|
||||||
|
if not result: break
|
||||||
|
if readA != bufSize: break # end of file
|
||||||
|
dealloc(bufA)
|
||||||
|
dealloc(bufB)
|
||||||
|
closeFile(a)
|
||||||
|
closeFile(b)
|
||||||
|
|
||||||
|
# Ansi C has these:
|
||||||
proc cremove(filename: CString): cint {.importc: "remove", noDecl.}
|
proc cremove(filename: CString): cint {.importc: "remove", noDecl.}
|
||||||
proc crename(oldname, newname: CString): cint {.importc: "rename", noDecl.}
|
proc crename(oldname, newname: CString): cint {.importc: "rename", noDecl.}
|
||||||
|
|
||||||
when defined(Windows):
|
when defined(Windows):
|
||||||
proc cCopyFile(lpExistingFileName, lpNewFileName: CString,
|
proc CopyFileA(lpExistingFileName, lpNewFileName: CString,
|
||||||
bFailIfExists: cint): cint {.
|
bFailIfExists: cint): cint {.
|
||||||
importc: "CopyFile", header: "<windows.h>".}
|
importc, stdcall, dynlib: "kernel32".}
|
||||||
# cMoveFile(lpExistingFileName, lpNewFileName: CString): int
|
proc copyFile(dest, source: string) =
|
||||||
# {.importc: "MoveFile", noDecl, header: "<winbase.h>".}
|
if CopyFileA(source, dest, 0'i32) == 0'i32: OSError()
|
||||||
# cRemoveFile(filename: CString, cmo: int)
|
|
||||||
# {.importc: "DeleteFile", noDecl, header: "<winbase.h>".}
|
|
||||||
else:
|
else:
|
||||||
# generic version of cCopyFile which works for any platform:
|
# generic version of copyFile which works for any platform:
|
||||||
proc cCopyFile(lpExistingFileName, lpNewFileName: CString,
|
proc copyFile(dest, source: string) =
|
||||||
bFailIfExists: cint): cint =
|
|
||||||
const
|
const
|
||||||
bufSize = 8192 # 8K buffer
|
bufSize = 8192 # 8K buffer
|
||||||
var
|
var
|
||||||
dest, src: TFile
|
d, s: TFile
|
||||||
if not openFile(src, $lpExistingFilename): return -1
|
if not openFile(s, source): OSError()
|
||||||
if not openFile(dest, $lpNewFilename, fmWrite):
|
if not openFile(d, dest, fmWrite):
|
||||||
closeFile(src)
|
closeFile(s)
|
||||||
return -1
|
OSError()
|
||||||
var
|
var
|
||||||
buf: Pointer = alloc(bufsize)
|
buf: Pointer = alloc(bufsize)
|
||||||
bytesread, byteswritten: int
|
bytesread, byteswritten: int
|
||||||
while True:
|
while True:
|
||||||
bytesread = readBuffer(src, buf, bufsize)
|
bytesread = readBuffer(s, buf, bufsize)
|
||||||
byteswritten = writeBuffer(dest, buf, bytesread)
|
byteswritten = writeBuffer(d, buf, bytesread)
|
||||||
if bytesread != bufSize: break
|
if bytesread != bufSize: break
|
||||||
if byteswritten == bytesread: result = 0
|
if bytesread != bytesWritten: OSError()
|
||||||
else: result = -1
|
|
||||||
dealloc(buf)
|
dealloc(buf)
|
||||||
closeFile(src)
|
closeFile(s)
|
||||||
closeFile(dest)
|
closeFile(d)
|
||||||
|
|
||||||
|
|
||||||
proc moveFile(dest, source: string) =
|
proc moveFile(dest, source: string) =
|
||||||
if crename(source, dest) != 0:
|
if crename(source, dest) != 0'i32: OSError()
|
||||||
raise newException(EOS, "cannot move file from '$1' to '$2'" %
|
|
||||||
[source, dest])
|
|
||||||
|
|
||||||
proc copyFile(dest, source: string) =
|
|
||||||
if cCopyFile(source, dest, 0) != 0:
|
|
||||||
raise newException(EOS, "cannot copy file from '$1' to '$2'" %
|
|
||||||
[source, dest])
|
|
||||||
|
|
||||||
proc removeFile(file: string) =
|
proc removeFile(file: string) =
|
||||||
if cremove(file) != 0:
|
if cremove(file) != 0'i32: OSError()
|
||||||
raise newException(EOS, "cannot remove file '$1'" % file)
|
|
||||||
|
|
||||||
proc removeDir(dir: string) =
|
proc removeDir(dir: string) =
|
||||||
if rmdir(dir) != 0:
|
when defined(windows):
|
||||||
raise newException(EOS, "cannot remove directory '$1'" % dir)
|
if RemoveDirectoryA(dir) == 0'i32: OSError()
|
||||||
|
else:
|
||||||
|
if rmdir(dir) != 0'i32: OSError()
|
||||||
|
|
||||||
|
proc rawCreateDir(dir: string) =
|
||||||
|
when defined(unix):
|
||||||
|
if mkdir(dir, 0o711) != 0'i32 and errno != EEXIST:
|
||||||
|
OSError()
|
||||||
|
else:
|
||||||
|
if CreateDirectoryA(dir, nil) == 0'i32 and GetLastError() != 183'i32:
|
||||||
|
OSError()
|
||||||
|
|
||||||
proc createDir(dir: string) =
|
proc createDir(dir: string) =
|
||||||
when defined(unix):
|
for i in 0.. dir.len-1:
|
||||||
if mkdir(dir, 0o711) != 0 and int(errno) != EEXIST:
|
if dir[i] in {dirsep, altsep}: rawCreateDir(copy(dir, 0, i-1))
|
||||||
raise newException(EOS, "cannot create directory '$1'" % dir)
|
rawCreateDir(dir)
|
||||||
else:
|
|
||||||
if CreateDirectory(dir, nil) == 0 and GetLastError() != 183:
|
|
||||||
raise newException(EOS, "cannot create directory '$1'" % dir)
|
|
||||||
|
|
||||||
proc existsDir(dir: string): bool =
|
|
||||||
var safe = getCurrentDir()
|
|
||||||
# just try to set the current dir to dir; if it works, it must exist:
|
|
||||||
result = chdir(dir) == 0
|
|
||||||
if result:
|
|
||||||
setCurrentDir(safe) # set back to the old working directory
|
|
||||||
|
|
||||||
proc executeProcess(command: string): int =
|
|
||||||
return csystem(command) # XXX: do this without shell
|
|
||||||
|
|
||||||
proc executeShellCommand(command: string): int =
|
proc executeShellCommand(command: string): int =
|
||||||
return csystem(command)
|
return csystem(command)
|
||||||
|
|
||||||
var
|
var
|
||||||
envComputed: bool = false
|
envComputed: bool = false
|
||||||
environment {.noStatic.}: seq[string] = []
|
environment: seq[string] = @[]
|
||||||
|
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
# because we support Windows GUI applications, things get really
|
# because we support Windows GUI applications, things get really
|
||||||
# messy here...
|
# messy here...
|
||||||
proc GetEnvironmentStrings(): Pointer {.
|
proc GetEnvironmentStringsA*(): cstring {.
|
||||||
importc: "GetEnvironmentStrings", header: "<windows.h>".}
|
stdcall, dynlib: "kernel32", importc.}
|
||||||
proc FreeEnvironmentStrings(env: Pointer) {.
|
proc FreeEnvironmentStringsA*(para1: cstring): int32 {.
|
||||||
importc: "FreeEnvironmentStrings", header: "<windows.h>".}
|
stdcall, dynlib: "kernel32", importc.}
|
||||||
|
|
||||||
proc strEnd(cstr: CString, c = 0): CString {.importc: "strchr", nodecl.}
|
proc strEnd(cstr: CString, c = 0): CString {.importc: "strchr", nodecl.}
|
||||||
|
|
||||||
proc getEnvVarsC() {.noStatic.} =
|
proc getEnvVarsC() =
|
||||||
if not envComputed:
|
if not envComputed:
|
||||||
var
|
var
|
||||||
env = cast[CString](getEnvironmentStrings())
|
env = getEnvironmentStringsA()
|
||||||
e = env
|
e = env
|
||||||
if e == nil: return # an error occured
|
if e == nil: return # an error occured
|
||||||
while True:
|
while True:
|
||||||
var eend = strEnd(e)
|
var eend = strEnd(e)
|
||||||
add environment, $e
|
add(environment, $e)
|
||||||
e = cast[CString](cast[TAddress](eend)+1)
|
e = cast[CString](cast[TAddress](eend)+1)
|
||||||
if eend[1] == '\0': break
|
if eend[1] == '\0': break
|
||||||
envComputed = true
|
envComputed = true
|
||||||
FreeEnvironmentStrings(env)
|
discard FreeEnvironmentStringsA(env)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
var
|
var
|
||||||
gEnv {.importc: "gEnv".}: ptr array [0..10_000, CString]
|
gEnv {.importc: "gEnv".}: ptr array [0..10_000, CString]
|
||||||
|
|
||||||
proc getEnvVarsC() {.noStatic.} =
|
proc getEnvVarsC() =
|
||||||
# retrieves the variables of char** env of C's main proc
|
# retrieves the variables of char** env of C's main proc
|
||||||
if not envComputed:
|
if not envComputed:
|
||||||
var
|
var
|
||||||
|
|
@ -840,8 +938,12 @@ proc putEnv(key, val: string) =
|
||||||
else:
|
else:
|
||||||
add environment, (key & '=' & val)
|
add environment, (key & '=' & val)
|
||||||
indx = high(environment)
|
indx = high(environment)
|
||||||
if cputenv(environment[indx]) != 0:
|
when defined(unix):
|
||||||
raise newException(EOS, "attempt to set an invalid environment variable")
|
if cputenv(environment[indx]) != 0'i32:
|
||||||
|
OSError()
|
||||||
|
else:
|
||||||
|
if SetEnvironmentVariableA(key, val) == 0'i32:
|
||||||
|
OSError()
|
||||||
|
|
||||||
iterator walkFiles*(pattern: string): string =
|
iterator walkFiles*(pattern: string): string =
|
||||||
## Iterate over all the files that match the `pattern`.
|
## Iterate over all the files that match the `pattern`.
|
||||||
|
|
@ -850,34 +952,108 @@ iterator walkFiles*(pattern: string): string =
|
||||||
## notation is supported.
|
## notation is supported.
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
var
|
var
|
||||||
f: TFindData
|
f: TWin32FindData
|
||||||
res: int
|
res: int
|
||||||
res = findfirst(pattern, addr(f))
|
res = findfirstFileA(pattern, f)
|
||||||
if res != -1:
|
if res != -1:
|
||||||
while true:
|
while true:
|
||||||
yield $f.name
|
if f.cFileName[0] != '.':
|
||||||
if int(findnext(res, addr(f))) == -1: break
|
yield extractDir(pattern) / extractFilename($f.cFileName)
|
||||||
|
if findnextFileA(res, f) == 0'i32: break
|
||||||
findclose(res)
|
findclose(res)
|
||||||
else: # here we use glob
|
else: # here we use glob
|
||||||
var
|
var
|
||||||
f: TFindData
|
f: TGlob
|
||||||
res: int
|
res: int
|
||||||
f.gl_offs = 0
|
f.gl_offs = 0
|
||||||
f.gl_pathc = 0
|
f.gl_pathc = 0
|
||||||
f.gl_pathv = nil
|
f.gl_pathv = nil
|
||||||
res = glob(pattern, 0, nil, addr(f))
|
res = glob(pattern, 0, nil, addr(f))
|
||||||
if res != 0: raise newException(EOS, "walkFiles() failed")
|
if res == 0:
|
||||||
for i in 0.. f.gl_pathc - 1:
|
for i in 0.. f.gl_pathc - 1:
|
||||||
assert(f.gl_pathv[i] != nil)
|
assert(f.gl_pathv[i] != nil)
|
||||||
yield $f.gl_pathv[i]
|
yield $f.gl_pathv[i]
|
||||||
globfree(addr(f))
|
globfree(addr(f))
|
||||||
|
|
||||||
{.push warnings:off.}
|
type
|
||||||
|
TPathComponent* = enum ## Enumeration specifying a path component.
|
||||||
|
pcFile, ## path refers to a file
|
||||||
|
pcLinkToFile, ## path refers to a symbolic link to a file
|
||||||
|
pcDirectory, ## path refers to a directory
|
||||||
|
pcLinkToDirectory ## path refers to a symbolic link to a directory
|
||||||
|
|
||||||
|
when defined(posix):
|
||||||
|
proc S_ISDIR(m: int16): bool {.importc, header: "<sys/stat.h>".}
|
||||||
|
proc S_ISLNK(m: int16): bool {.importc, header: "<sys/stat.h>".}
|
||||||
|
proc S_ISREG(m: int16): bool {.importc, header: "<sys/stat.h>".}
|
||||||
|
|
||||||
|
iterator walkDir*(dir: string): tuple[kind: TPathComponent, path: string] =
|
||||||
|
## walks over the directory `dir` and yields for each directory or file in
|
||||||
|
## `dir`. The component type and full path for each item is returned.
|
||||||
|
## Walking is not recursive.
|
||||||
|
## Example: Assuming this directory structure::
|
||||||
|
## dirA / dirB / fileB1.txt
|
||||||
|
## / dirC
|
||||||
|
## / fileA1.txt
|
||||||
|
## / fileA2.txt
|
||||||
|
##
|
||||||
|
## and this code:
|
||||||
|
##
|
||||||
|
## .. code-block:: Nimrod
|
||||||
|
## for kind, path in walkDir("dirA"):
|
||||||
|
## echo(path)
|
||||||
|
##
|
||||||
|
## produces this output (though not necessarily in this order!)::
|
||||||
|
## dirA/dirB
|
||||||
|
## dirA/dirC
|
||||||
|
## dirA/fileA1.txt
|
||||||
|
## dirA/fileA2.txt
|
||||||
|
when defined(windows):
|
||||||
|
var f: TWIN32_Find_Data
|
||||||
|
var h = findfirstFileA(dir / "*", f)
|
||||||
|
if h != -1:
|
||||||
|
while true:
|
||||||
|
var k = pcFile
|
||||||
|
if f.cFilename[0] != '.':
|
||||||
|
if (int(f.dwFileAttributes) and FILE_ATTRIBUTE_DIRECTORY) != 0:
|
||||||
|
k = pcDirectory
|
||||||
|
yield (k, dir / extractFilename($f.cFilename))
|
||||||
|
if findnextFileA(h, f) == 0'i32: break
|
||||||
|
findclose(h)
|
||||||
|
else:
|
||||||
|
var d = openDir(dir)
|
||||||
|
if d != nil:
|
||||||
|
while true:
|
||||||
|
var x = readDir(d)
|
||||||
|
if x == nil: break
|
||||||
|
var y = $x.d_name
|
||||||
|
if y != "." and y != "..":
|
||||||
|
var s: TStat
|
||||||
|
y = dir / y
|
||||||
|
if stat(y, s) < 0'i32: break
|
||||||
|
var k = pcFile
|
||||||
|
if S_ISDIR(s.st_mode): k = pcDirectory
|
||||||
|
if S_ISLNK(s.st_mode): k = succ(k)
|
||||||
|
yield (k, y)
|
||||||
|
closeDir(d)
|
||||||
|
|
||||||
proc ExistsFile(filename: string): bool =
|
proc ExistsFile(filename: string): bool =
|
||||||
var
|
when defined(windows):
|
||||||
res: TStat
|
var a = GetFileAttributesA(filename)
|
||||||
return stat(filename, res) >= 0
|
if a != -1:
|
||||||
{.pop.}
|
result = (a and FILE_ATTRIBUTE_DIRECTORY) == 0
|
||||||
|
else:
|
||||||
|
var res: TStat
|
||||||
|
return stat(filename, res) >= 0'i32 and S_ISREG(res.st_mode)
|
||||||
|
|
||||||
|
proc existsDir(dir: string): bool =
|
||||||
|
when defined(windows):
|
||||||
|
var a = GetFileAttributesA(dir)
|
||||||
|
if a != -1:
|
||||||
|
result = (a and FILE_ATTRIBUTE_DIRECTORY) != 0
|
||||||
|
else:
|
||||||
|
var res: TStat
|
||||||
|
return stat(dir, res) >= 0'i32 and S_ISDIR(res.st_mode)
|
||||||
|
|
||||||
proc cmpPaths(pathA, pathB: string): int =
|
proc cmpPaths(pathA, pathB: string): int =
|
||||||
if FileSystemCaseSensitive:
|
if FileSystemCaseSensitive:
|
||||||
|
|
@ -886,52 +1062,39 @@ proc cmpPaths(pathA, pathB: string): int =
|
||||||
result = cmpIgnoreCase(pathA, pathB)
|
result = cmpIgnoreCase(pathA, pathB)
|
||||||
|
|
||||||
proc extractDir(path: string): string =
|
proc extractDir(path: string): string =
|
||||||
var
|
if path[path.len-1] in {dirSep, altSep}:
|
||||||
tail: string
|
result = path
|
||||||
|
else:
|
||||||
|
var tail: string
|
||||||
splitPath(path, result, tail)
|
splitPath(path, result, tail)
|
||||||
|
|
||||||
proc extractFilename(path: string): string =
|
proc extractFilename(path: string): string =
|
||||||
var
|
if path[path.len-1] in {dirSep, altSep}:
|
||||||
head: string
|
result = ""
|
||||||
|
else:
|
||||||
|
var head: string
|
||||||
splitPath(path, head, result)
|
splitPath(path, head, result)
|
||||||
|
|
||||||
proc expandFilename(filename: string): string =
|
proc expandFilename(filename: string): string =
|
||||||
# returns the full path of 'filename'; "" on error
|
# returns the full path of 'filename'; "" on error
|
||||||
var
|
when defined(windows):
|
||||||
res: CString
|
var unused: cstring
|
||||||
when defined(unix):
|
result = newString(3072)
|
||||||
res = realpath(filename, nil)
|
var L = GetFullPathNameA(filename, 3072'i32, result, unused)
|
||||||
else:
|
if L <= 0'i32 or L >= 3072'i32: OSError()
|
||||||
res = fullpath(nil, filename, 0)
|
setLen(result, L)
|
||||||
if res == nil:
|
|
||||||
result = "" # an error occured
|
|
||||||
else:
|
else:
|
||||||
|
var res = realpath(filename, nil)
|
||||||
|
if res == nil: OSError()
|
||||||
result = $res
|
result = $res
|
||||||
free(res)
|
free(res)
|
||||||
|
|
||||||
when defined(windows):
|
proc parseCmdLine*(c: string): seq[string] =
|
||||||
proc GetHomeDir(): string = return getEnv("USERPROFILE") & "\\"
|
## Splits a command line into several components; components are separated by
|
||||||
proc GetConfigDir(): string = return getEnv("APPDATA") & "\\"
|
## whitespace or are quoted with the ``"`` or ``'`` characters. This proc is
|
||||||
|
## only occassionally useful, better use the `parseopt` module.
|
||||||
# Since we support GUI applications with Nimrod, we sometimes generate
|
result = @[]
|
||||||
# a WinMain entry proc. But a WinMain proc has no access to the parsed
|
var i = 0
|
||||||
# command line arguments. The way to get them differs. Thus we parse them
|
|
||||||
# ourselves. This has the additional benefit that the program's behaviour
|
|
||||||
# is always the same -- independent of the used C compiler.
|
|
||||||
proc GetCommandLine(): CString {.
|
|
||||||
importc: "GetCommandLine", header: "<windows.h>".}
|
|
||||||
|
|
||||||
var
|
|
||||||
ownArgc: int = -1
|
|
||||||
ownArgv: seq[string] = []
|
|
||||||
|
|
||||||
proc parseCmdLine() =
|
|
||||||
if ownArgc != -1: return # already processed
|
|
||||||
var
|
|
||||||
i = 0
|
|
||||||
j = 0
|
|
||||||
c = getCommandLine()
|
|
||||||
ownArgc = 0
|
|
||||||
while c[i] != '\0':
|
while c[i] != '\0':
|
||||||
var a = ""
|
var a = ""
|
||||||
while c[i] >= '\1' and c[i] <= ' ': inc(i) # skip whitespace
|
while c[i] >= '\1' and c[i] <= ' ': inc(i) # skip whitespace
|
||||||
|
|
@ -945,24 +1108,35 @@ when defined(windows):
|
||||||
if c[i] != '\0': inc(i)
|
if c[i] != '\0': inc(i)
|
||||||
else:
|
else:
|
||||||
while c[i] > ' ':
|
while c[i] > ' ':
|
||||||
add a, c[i]
|
add(a, c[i])
|
||||||
inc(i)
|
inc(i)
|
||||||
add ownArgv, a
|
add(result, a)
|
||||||
inc(ownArgc)
|
|
||||||
|
when defined(windows):
|
||||||
|
proc GetHomeDir(): string = return getEnv("USERPROFILE") & "\\"
|
||||||
|
proc GetConfigDir(): string = return getEnv("APPDATA") & "\\"
|
||||||
|
|
||||||
|
# Since we support GUI applications with Nimrod, we sometimes generate
|
||||||
|
# a WinMain entry proc. But a WinMain proc has no access to the parsed
|
||||||
|
# command line arguments. The way to get them differs. Thus we parse them
|
||||||
|
# ourselves. This has the additional benefit that the program's behaviour
|
||||||
|
# is always the same -- independent of the used C compiler.
|
||||||
|
proc GetCommandLineA(): CString {.importc, stdcall, dynlib: "kernel32".}
|
||||||
|
|
||||||
|
var
|
||||||
|
ownArgv: seq[string]
|
||||||
|
|
||||||
proc paramStr(i: int): string =
|
proc paramStr(i: int): string =
|
||||||
parseCmdLine()
|
if isNil(ownArgv): ownArgv = parseCmdLine($getCommandLineA())
|
||||||
if i < ownArgc and i >= 0:
|
|
||||||
return ownArgv[i]
|
return ownArgv[i]
|
||||||
raise newException(EInvalidIndex, "invalid index")
|
|
||||||
|
|
||||||
proc paramCount(): int =
|
proc paramCount(): int =
|
||||||
parseCmdLine()
|
if isNil(ownArgv): ownArgv = parseCmdLine($getCommandLineA())
|
||||||
result = ownArgc-1
|
result = ownArgv.len-1
|
||||||
|
|
||||||
else:
|
else:
|
||||||
proc GetHomeDir(): string = return getEnv("HOME") & "/"
|
proc GetHomeDir(): string = return getEnv("HOME") & "/"
|
||||||
proc GetConfigDir(): string = return getEnv("HOME") & "/"
|
proc GetConfigDir(): string = return getEnv("HOME") & "/.config/"
|
||||||
|
|
||||||
var
|
var
|
||||||
cmdCount {.importc: "cmdCount".}: int
|
cmdCount {.importc: "cmdCount".}: int
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
|
|
||||||
import
|
import
|
||||||
hashes, strutils, lexbase
|
hashes, strutils, lexbase, streams
|
||||||
|
|
||||||
type
|
type
|
||||||
TCfgEventKind* = enum ## enumation of all events that may occur when parsing
|
TCfgEventKind* = enum ## enumation of all events that may occur when parsing
|
||||||
|
|
@ -37,7 +37,7 @@ type
|
||||||
|
|
||||||
TCfgEvent* = object of TObject ## describes a parsing event
|
TCfgEvent* = object of TObject ## describes a parsing event
|
||||||
case kind*: TCfgEventKind ## the kind of the event
|
case kind*: TCfgEventKind ## the kind of the event
|
||||||
of cfgEof: dummy: string
|
of cfgEof: nil
|
||||||
of cfgSectionStart:
|
of cfgSectionStart:
|
||||||
section*: string ## `section` contains the name of the
|
section*: string ## `section` contains the name of the
|
||||||
## parsed section start (syntax: ``[section]``)
|
## parsed section start (syntax: ``[section]``)
|
||||||
|
|
@ -59,21 +59,18 @@ type
|
||||||
literal: string # the parsed (string) literal
|
literal: string # the parsed (string) literal
|
||||||
|
|
||||||
TParserState = enum
|
TParserState = enum
|
||||||
startState, commaState
|
startState # , commaState # not yet used
|
||||||
TCfgParser* = object of TBaseLexer ## the parser object.
|
TCfgParser* = object of TBaseLexer ## the parser object.
|
||||||
tok: TToken
|
tok: TToken
|
||||||
state: TParserState
|
state: TParserState
|
||||||
filename: string
|
filename: string
|
||||||
|
|
||||||
proc Open*(c: var TCfgParser, filename: string): bool
|
proc open*(c: var TCfgParser, input: PStream, filename: string)
|
||||||
## initializes the parser, open the file for reading and returns true if
|
## initializes the parser with an input stream. `Filename` is only used
|
||||||
## successful (the file has been found).
|
## for nice error messages.
|
||||||
|
|
||||||
proc OpenFromBuffer*(c: var TCfgParser, buf: string)
|
|
||||||
## initializes the parser with a buffer. This cannot fail.
|
|
||||||
|
|
||||||
proc close*(c: var TCfgParser)
|
proc close*(c: var TCfgParser)
|
||||||
## closes the parser `c`.
|
## closes the parser `c` and its associated input stream.
|
||||||
|
|
||||||
proc next*(c: var TCfgParser): TCfgEvent
|
proc next*(c: var TCfgParser): TCfgEvent
|
||||||
## retrieves the first/next event. This controls the parser.
|
## retrieves the first/next event. This controls the parser.
|
||||||
|
|
@ -87,6 +84,10 @@ proc getLine*(c: TCfgParser): int
|
||||||
proc getFilename*(c: TCfgParser): string
|
proc getFilename*(c: TCfgParser): string
|
||||||
## get the filename of the file that the parser processes.
|
## get the filename of the file that the parser processes.
|
||||||
|
|
||||||
|
proc errorStr*(c: TCfgParser, msg: string): string
|
||||||
|
## returns a properly formated error message containing current line and
|
||||||
|
## column information.
|
||||||
|
|
||||||
|
|
||||||
# implementation
|
# implementation
|
||||||
|
|
||||||
|
|
@ -94,24 +95,16 @@ 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)
|
proc rawGetTok(c: var TCfgParser, tok: var TToken)
|
||||||
proc open(c: var TCfgParser, filename: string): bool =
|
proc open(c: var TCfgParser, input: PStream, filename: string) =
|
||||||
result = initBaseLexer(c, filename)
|
lexbase.open(c, input)
|
||||||
c.filename = filename
|
c.filename = filename
|
||||||
c.state = startState
|
c.state = startState
|
||||||
c.tok.kind = tkInvalid
|
c.tok.kind = tkInvalid
|
||||||
c.tok.literal = ""
|
c.tok.literal = ""
|
||||||
if result: rawGetTok(c, c.tok)
|
|
||||||
|
|
||||||
proc openFromBuffer(c: var TCfgParser, buf: string) =
|
|
||||||
initBaseLexerFromBuffer(c, buf)
|
|
||||||
c.filename = "buffer"
|
|
||||||
c.state = startState
|
|
||||||
c.tok.kind = tkInvalid
|
|
||||||
c.tok.literal = ""
|
|
||||||
rawGetTok(c, c.tok)
|
rawGetTok(c, c.tok)
|
||||||
|
|
||||||
proc close(c: var TCfgParser) =
|
proc close(c: var TCfgParser) =
|
||||||
deinitBaseLexer(c)
|
lexbase.close(c)
|
||||||
|
|
||||||
proc getColumn(c: TCfgParser): int =
|
proc getColumn(c: TCfgParser): int =
|
||||||
result = getColNumber(c, c.bufPos)
|
result = getColNumber(c, c.bufPos)
|
||||||
|
|
@ -285,6 +278,7 @@ proc rawGetTok(c: var TCfgParser, tok: var TToken) =
|
||||||
of '=':
|
of '=':
|
||||||
tok.kind = tkEquals
|
tok.kind = tkEquals
|
||||||
inc(c.bufpos)
|
inc(c.bufpos)
|
||||||
|
tok.literal = "="
|
||||||
of '-':
|
of '-':
|
||||||
inc(c.bufPos)
|
inc(c.bufPos)
|
||||||
if c.buf[c.bufPos] == '-': inc(c.bufPos)
|
if c.buf[c.bufPos] == '-': inc(c.bufPos)
|
||||||
|
|
@ -312,6 +306,7 @@ proc rawGetTok(c: var TCfgParser, tok: var TToken) =
|
||||||
getString(c, tok, false)
|
getString(c, tok, false)
|
||||||
of lexbase.EndOfFile:
|
of lexbase.EndOfFile:
|
||||||
tok.kind = tkEof
|
tok.kind = tkEof
|
||||||
|
tok.literal = "[EOF]"
|
||||||
else: getSymbol(c, tok)
|
else: getSymbol(c, tok)
|
||||||
|
|
||||||
proc errorStr(c: TCfgParser, msg: string): string =
|
proc errorStr(c: TCfgParser, msg: string): string =
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Nimrod's Runtime Library
|
# Nimrod's Runtime Library
|
||||||
# (c) Copyright 2006 Andreas Rumpf
|
# (c) Copyright 2008 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -20,12 +20,16 @@
|
||||||
## ALL types are named the same as in the POSIX standard except that they start
|
## ALL types are named the same as in the POSIX standard except that they start
|
||||||
## with 'T' or 'P' (if they are pointers) and without the '_t' prefix to be
|
## with 'T' or 'P' (if they are pointers) and without the '_t' prefix to be
|
||||||
## consistent with Nimrod conventions. If an identifier is a Nimrod keyword
|
## consistent with Nimrod conventions. If an identifier is a Nimrod keyword
|
||||||
## the `identifier` notation is used.
|
## the \`identifier\` notation is used.
|
||||||
##
|
##
|
||||||
## This library relies on the header files of your C compiler. Thus the
|
## This library relies on the header files of your C compiler. Thus the
|
||||||
## resulting C code will just include <XYZ.h> and *not* define the
|
## resulting C code will just include <XYZ.h> and *not* define the
|
||||||
## symbols declared here.
|
## symbols declared here.
|
||||||
|
|
||||||
|
const
|
||||||
|
hasSpawnH = defined(linux)
|
||||||
|
hasAioH = defined(linux)
|
||||||
|
|
||||||
const
|
const
|
||||||
C_IRUSR* = 0c000400 ## Read by owner.
|
C_IRUSR* = 0c000400 ## Read by owner.
|
||||||
C_IWUSR* = 0c000200 ## Write by owner.
|
C_IWUSR* = 0c000200 ## Write by owner.
|
||||||
|
|
@ -55,28 +59,19 @@ const
|
||||||
MM_NULLACT* = nil
|
MM_NULLACT* = nil
|
||||||
MM_NULLTAG* = nil
|
MM_NULLTAG* = nil
|
||||||
|
|
||||||
STDERR_FILENO = 2 ## File number of stderr;
|
STDERR_FILENO* = 2 ## File number of stderr;
|
||||||
STDIN_FILENO = 0 ## File number of stdin;
|
STDIN_FILENO* = 0 ## File number of stdin;
|
||||||
STDOUT_FILENO = 1 ## File number of stdout;
|
STDOUT_FILENO* = 1 ## File number of stdout;
|
||||||
|
|
||||||
type
|
type
|
||||||
Taiocb* {.importc: "struct aiocb", header: "<aio.h>", final.} = object
|
TDIR* {.importc: "DIR", header: "<dirent.h>", final, pure.} = object
|
||||||
aio_fildes*: cint ## File descriptor.
|
|
||||||
aio_offset*: TOff ## File offset.
|
|
||||||
aio_buf*: pointer ## Location of buffer.
|
|
||||||
aio_nbytes*: int ## Length of transfer.
|
|
||||||
aio_reqprio*: cint ## Request priority offset.
|
|
||||||
aio_sigevent*: TSigEvent ## Signal number and value.
|
|
||||||
aio_lio_opcode: cint ## Operation to be performed.
|
|
||||||
|
|
||||||
TDIR* {.importc: "DIR", header: "<dirent.h>", final.} = object
|
|
||||||
## A type representing a directory stream.
|
## A type representing a directory stream.
|
||||||
|
|
||||||
Tdirent* {.importc: "struct dirent", header: "<dirent.h>", final.} = object
|
Tdirent* {.importc: "struct dirent", header: "<dirent.h>", final, pure.} = object
|
||||||
d_ino*: TIno ## File serial number.
|
d_ino*: TIno ## File serial number.
|
||||||
d_name*: array [0..255, char] ## Name of entry.
|
d_name*: array [0..255, char] ## Name of entry.
|
||||||
|
|
||||||
Tflock* {.importc: "flock", header: "<fcntl>", final.} = object
|
Tflock* {.importc: "flock", header: "<fcntl.h>", final, pure.} = object
|
||||||
l_type*: cshort ## Type of lock; F_RDLCK, F_WRLCK, F_UNLCK.
|
l_type*: cshort ## Type of lock; F_RDLCK, F_WRLCK, F_UNLCK.
|
||||||
l_whence*: cshort ## Flag for starting offset.
|
l_whence*: cshort ## Flag for starting offset.
|
||||||
l_start*: Toff ## Relative offset in bytes.
|
l_start*: Toff ## Relative offset in bytes.
|
||||||
|
|
@ -84,12 +79,12 @@ type
|
||||||
l_pid*: TPid ## Process ID of the process holding the lock;
|
l_pid*: TPid ## Process ID of the process holding the lock;
|
||||||
## returned with F_GETLK.
|
## returned with F_GETLK.
|
||||||
|
|
||||||
Tfenv* {.importc: "fenv_t", header: "<fenv.h>", final.} =
|
Tfenv* {.importc: "fenv_t", header: "<fenv.h>", final, pure.} =
|
||||||
object ## Represents the entire floating-point environment. The
|
object ## Represents the entire floating-point environment. The
|
||||||
## floating-point environment refers collectively to any
|
## floating-point environment refers collectively to any
|
||||||
## floating-point status flags and control modes supported
|
## floating-point status flags and control modes supported
|
||||||
## by the implementation.
|
## by the implementation.
|
||||||
Tfexcept* {.importc: "fexcept_t", header: "<fenv.h>", final.} =
|
Tfexcept* {.importc: "fexcept_t", header: "<fenv.h>", final, pure.} =
|
||||||
object ## Represents the floating-point status flags collectively,
|
object ## Represents the floating-point status flags collectively,
|
||||||
## including any status the implementation associates with the
|
## including any status the implementation associates with the
|
||||||
## flags. A floating-point status flag is a system variable
|
## flags. A floating-point status flag is a system variable
|
||||||
|
|
@ -100,25 +95,25 @@ type
|
||||||
## whose value may be set by the user to affect the subsequent
|
## whose value may be set by the user to affect the subsequent
|
||||||
## behavior of floating-point arithmetic.
|
## behavior of floating-point arithmetic.
|
||||||
|
|
||||||
TFTW* {.importc: "struct FTW", header: "<ftw.h>", final.} = object
|
TFTW* {.importc: "struct FTW", header: "<ftw.h>", final, pure.} = object
|
||||||
base*: cint
|
base*: cint
|
||||||
level*: cint
|
level*: cint
|
||||||
|
|
||||||
TGlob* {.importc: "glob_t", header: "<glob.h>", final.} = object
|
TGlob* {.importc: "glob_t", header: "<glob.h>", final, pure.} = object
|
||||||
gl_pathc*: int ## Count of paths matched by pattern.
|
gl_pathc*: int ## Count of paths matched by pattern.
|
||||||
gl_pathv*: ptr cstring ## Pointer to a list of matched pathnames.
|
gl_pathv*: ptr cstring ## Pointer to a list of matched pathnames.
|
||||||
gl_offs*: int ## Slots to reserve at the beginning of gl_pathv.
|
gl_offs*: int ## Slots to reserve at the beginning of gl_pathv.
|
||||||
|
|
||||||
TGroup* {.importc: "struct group", header: "<grp.h>", final.} = object
|
TGroup* {.importc: "struct group", header: "<grp.h>", final, pure.} = object
|
||||||
gr_name*: cstring ## The name of the group.
|
gr_name*: cstring ## The name of the group.
|
||||||
gr_gid*: TGid ## Numerical group ID.
|
gr_gid*: TGid ## Numerical group ID.
|
||||||
gr_mem*: cstringArray ## Pointer to a null-terminated array of character
|
gr_mem*: cstringArray ## Pointer to a null-terminated array of character
|
||||||
## pointers to member names.
|
## pointers to member names.
|
||||||
|
|
||||||
Ticonv* {.importc: "iconv_t", header: "<iconv.h>", final.} =
|
Ticonv* {.importc: "iconv_t", header: "<iconv.h>", final, pure.} =
|
||||||
object ## Identifies the conversion from one codeset to another.
|
object ## Identifies the conversion from one codeset to another.
|
||||||
|
|
||||||
Tlconv* {.importc: "struct lconv", header: "<locale.h>", final.} = object
|
Tlconv* {.importc: "struct lconv", header: "<locale.h>", final, pure.} = object
|
||||||
currency_symbol*: cstring
|
currency_symbol*: cstring
|
||||||
decimal_point*: cstring
|
decimal_point*: cstring
|
||||||
frac_digits*: char
|
frac_digits*: char
|
||||||
|
|
@ -144,14 +139,14 @@ type
|
||||||
p_sign_posn*: char
|
p_sign_posn*: char
|
||||||
thousands_sep*: cstring
|
thousands_sep*: cstring
|
||||||
|
|
||||||
TMqd* {.importc: "mqd_t", header: "<mqueue.h>", final.} = object
|
TMqd* {.importc: "mqd_t", header: "<mqueue.h>", final, pure.} = object
|
||||||
TMqAttr* {.importc: "struct mq_attr", header: "<mqueue.h>", final.} = object
|
TMqAttr* {.importc: "struct mq_attr", header: "<mqueue.h>", final, pure.} = object
|
||||||
mq_flags*: int ## Message queue flags.
|
mq_flags*: int ## Message queue flags.
|
||||||
mq_maxmsg*: int ## Maximum number of messages.
|
mq_maxmsg*: int ## Maximum number of messages.
|
||||||
mq_msgsize*: int ## Maximum message size.
|
mq_msgsize*: int ## Maximum message size.
|
||||||
mq_curmsgs*: int ## Number of messages currently queued.
|
mq_curmsgs*: int ## Number of messages currently queued.
|
||||||
|
|
||||||
TPasswd* {.importc: "struct passwd", header: "<pwd.h>", final.} = object
|
TPasswd* {.importc: "struct passwd", header: "<pwd.h>", final, pure.} = object
|
||||||
pw_name*: cstring ## User's login name.
|
pw_name*: cstring ## User's login name.
|
||||||
pw_uid*: TUid ## Numerical user ID.
|
pw_uid*: TUid ## Numerical user ID.
|
||||||
pw_gid*: TGid ## Numerical group ID.
|
pw_gid*: TGid ## Numerical group ID.
|
||||||
|
|
@ -198,7 +193,7 @@ type
|
||||||
Tuid* {.importc: "uid_t", header: "<sys/types.h>".} = int
|
Tuid* {.importc: "uid_t", header: "<sys/types.h>".} = int
|
||||||
Tuseconds* {.importc: "useconds_t", header: "<sys/types.h>".} = int
|
Tuseconds* {.importc: "useconds_t", header: "<sys/types.h>".} = int
|
||||||
|
|
||||||
Tutsname* {.importc: "struct utsname", header: "<sys/utsname.h>", final.} = object
|
Tutsname* {.importc: "struct utsname", header: "<sys/utsname.h>", final, pure.} = object
|
||||||
sysname*, ## Name of this implementation of the operating system.
|
sysname*, ## Name of this implementation of the operating system.
|
||||||
nodename*, ## Name of this node within the communications
|
nodename*, ## Name of this node within the communications
|
||||||
## network to which this node is attached, if any.
|
## network to which this node is attached, if any.
|
||||||
|
|
@ -207,15 +202,15 @@ type
|
||||||
machine*: array [0..255, char] ## Name of the hardware type on which the
|
machine*: array [0..255, char] ## Name of the hardware type on which the
|
||||||
## system is running.
|
## system is running.
|
||||||
|
|
||||||
TSem* {.importc: "sem_t", header: "<semaphore.h>", final.} = object
|
TSem* {.importc: "sem_t", header: "<semaphore.h>", final, pure.} = object
|
||||||
Tipc_perm* {.importc: "struct ipc_perm", header: "<sys/ipc.h>", final.} = object
|
Tipc_perm* {.importc: "struct ipc_perm", header: "<sys/ipc.h>", final, pure.} = object
|
||||||
uid*: tuid ## Owner's user ID.
|
uid*: tuid ## Owner's user ID.
|
||||||
gid*: tgid ## Owner's group ID.
|
gid*: tgid ## Owner's group ID.
|
||||||
cuid*: Tuid ## Creator's user ID.
|
cuid*: Tuid ## Creator's user ID.
|
||||||
cgid*: Tgid ## Creator's group ID.
|
cgid*: Tgid ## Creator's group ID.
|
||||||
mode*: TMode ## Read/write permission.
|
mode*: TMode ## Read/write permission.
|
||||||
|
|
||||||
TStat* {.importc: "struct stat", header: "<sys/stat.h>", final.} = object
|
TStat* {.importc: "struct stat", header: "<sys/stat.h>", final, pure.} = object
|
||||||
st_dev*: TDev ## Device ID of device containing file.
|
st_dev*: TDev ## Device ID of device containing file.
|
||||||
st_ino*: TIno ## File serial number.
|
st_ino*: TIno ## File serial number.
|
||||||
st_mode*: TMode ## Mode of file (see below).
|
st_mode*: TMode ## Mode of file (see below).
|
||||||
|
|
@ -239,7 +234,7 @@ type
|
||||||
st_blocks*: Tblkcnt ## Number of blocks allocated for this object.
|
st_blocks*: Tblkcnt ## Number of blocks allocated for this object.
|
||||||
|
|
||||||
|
|
||||||
TStatvfs* {.importc: "struct statvfs", header: "<sys/statvfs.h>", final.} = object
|
TStatvfs* {.importc: "struct statvfs", header: "<sys/statvfs.h>", final, pure.} = object
|
||||||
f_bsize*: int ## File system block size.
|
f_bsize*: int ## File system block size.
|
||||||
f_frsize*: int ## Fundamental file system block size.
|
f_frsize*: int ## Fundamental file system block size.
|
||||||
f_blocks*: Tfsblkcnt ## Total number of blocks on file system in units of f_frsize.
|
f_blocks*: Tfsblkcnt ## Total number of blocks on file system in units of f_frsize.
|
||||||
|
|
@ -255,10 +250,10 @@ type
|
||||||
f_namemax*: int ## Maximum filename length.
|
f_namemax*: int ## Maximum filename length.
|
||||||
|
|
||||||
Tposix_typed_mem_info* {.importc: "struct posix_typed_mem_info",
|
Tposix_typed_mem_info* {.importc: "struct posix_typed_mem_info",
|
||||||
header: "<sys/mman.h>", final.} = object
|
header: "<sys/mman.h>", final, pure.} = object
|
||||||
posix_tmi_length*: int
|
posix_tmi_length*: int
|
||||||
|
|
||||||
Ttm* {.importc: "struct tm", header: "<time.h>", final.} = object
|
Ttm* {.importc: "struct tm", header: "<time.h>", final, pure.} = object
|
||||||
tm_sec*: cint ## Seconds [0,60].
|
tm_sec*: cint ## Seconds [0,60].
|
||||||
tm_min*: cint ## Minutes [0,59].
|
tm_min*: cint ## Minutes [0,59].
|
||||||
tm_hour*: cint ## Hour [0,23].
|
tm_hour*: cint ## Hour [0,23].
|
||||||
|
|
@ -268,10 +263,10 @@ type
|
||||||
tm_wday*: cint ## Day of week [0,6] (Sunday =0).
|
tm_wday*: cint ## Day of week [0,6] (Sunday =0).
|
||||||
tm_yday*: cint ## Day of year [0,365].
|
tm_yday*: cint ## Day of year [0,365].
|
||||||
tm_isdst*: cint ## Daylight Savings flag.
|
tm_isdst*: cint ## Daylight Savings flag.
|
||||||
Ttimespec* {.importc: "struct timespec", header: "<time.h>", final.} = object
|
Ttimespec* {.importc: "struct timespec", header: "<time.h>", final, pure.} = object
|
||||||
tv_sec*: Ttime ## Seconds.
|
tv_sec*: Ttime ## Seconds.
|
||||||
tv_nsec*: int ## Nanoseconds.
|
tv_nsec*: int ## Nanoseconds.
|
||||||
titimerspec* {.importc: "struct itimerspec", header: "<time.h>", final.} = object
|
titimerspec* {.importc: "struct itimerspec", header: "<time.h>", final, pure.} = object
|
||||||
it_interval*: ttimespec ## Timer period.
|
it_interval*: ttimespec ## Timer period.
|
||||||
it_value*: ttimespec ## Timer expiration.
|
it_value*: ttimespec ## Timer expiration.
|
||||||
|
|
||||||
|
|
@ -279,19 +274,19 @@ type
|
||||||
## Possibly volatile-qualified integer type of an object that can be
|
## Possibly volatile-qualified integer type of an object that can be
|
||||||
## accessed as an atomic entity, even in the presence of asynchronous
|
## accessed as an atomic entity, even in the presence of asynchronous
|
||||||
## interrupts.
|
## interrupts.
|
||||||
Tsigset* {.importc: "sigset_t", header: "<signal.h>", final.} = object
|
Tsigset* {.importc: "sigset_t", header: "<signal.h>", final, pure.} = object
|
||||||
|
|
||||||
TsigEvent* {.importc: "struct sigevent", header: "<signal.h>", final.} = object
|
TsigEvent* {.importc: "struct sigevent", header: "<signal.h>", final, pure.} = object
|
||||||
sigev_notify*: cint ## Notification type.
|
sigev_notify*: cint ## Notification type.
|
||||||
sigev_signo*: cint ## Signal number.
|
sigev_signo*: cint ## Signal number.
|
||||||
sigev_value*: Tsigval ## Signal value.
|
sigev_value*: Tsigval ## Signal value.
|
||||||
sigev_notify_function*: proc (x: TSigval) {.noconv.} ## Notification function.
|
sigev_notify_function*: proc (x: TSigval) {.noconv.} ## Notification function.
|
||||||
sigev_notify_attributes*: ptr Tpthreadattr ## Notification attributes.
|
sigev_notify_attributes*: ptr Tpthreadattr ## Notification attributes.
|
||||||
|
|
||||||
TsigVal* {.importc: "union sigval", header: "<signal.h>", final.} = object
|
TsigVal* {.importc: "union sigval", header: "<signal.h>", final, pure.} = object
|
||||||
sival_ptr*: pointer ## pointer signal value;
|
sival_ptr*: pointer ## pointer signal value;
|
||||||
## integer signal value not defined!
|
## integer signal value not defined!
|
||||||
TSigaction* {.importc: "struct sigaction", header: "<signal.h>", final.} = object
|
TSigaction* {.importc: "struct sigaction", header: "<signal.h>", final, pure.} = object
|
||||||
sa_handler*: proc (x: cint) {.noconv.} ## Pointer to a signal-catching
|
sa_handler*: proc (x: cint) {.noconv.} ## Pointer to a signal-catching
|
||||||
## function or one of the macros
|
## function or one of the macros
|
||||||
## SIG_IGN or SIG_DFL.
|
## SIG_IGN or SIG_DFL.
|
||||||
|
|
@ -300,16 +295,16 @@ type
|
||||||
sa_flags*: cint ## Special flags.
|
sa_flags*: cint ## Special flags.
|
||||||
sa_sigaction*: proc (x: cint, y: var TSigInfo, z: pointer) {.noconv.}
|
sa_sigaction*: proc (x: cint, y: var TSigInfo, z: pointer) {.noconv.}
|
||||||
|
|
||||||
TStack* {.importc: "stack_t", header: "<signal.h>", final.} = object
|
TStack* {.importc: "stack_t", header: "<signal.h>", final, pure.} = object
|
||||||
ss_sp*: pointer ## Stack base or pointer.
|
ss_sp*: pointer ## Stack base or pointer.
|
||||||
ss_size*: int ## Stack size.
|
ss_size*: int ## Stack size.
|
||||||
ss_flags*: cint ## Flags.
|
ss_flags*: cint ## Flags.
|
||||||
|
|
||||||
TSigStack* {.importc: "struct sigstack", header: "<signal.h>", final.} = object
|
TSigStack* {.importc: "struct sigstack", header: "<signal.h>", final, pure.} = object
|
||||||
ss_onstack*: cint ## Non-zero when signal stack is in use.
|
ss_onstack*: cint ## Non-zero when signal stack is in use.
|
||||||
ss_sp*: pointer ## Signal stack pointer.
|
ss_sp*: pointer ## Signal stack pointer.
|
||||||
|
|
||||||
TsigInfo* {.importc: "siginfo_t", header: "<signal.h>", final.} = object
|
TsigInfo* {.importc: "siginfo_t", header: "<signal.h>", final, pure.} = object
|
||||||
si_signo*: cint ## Signal number.
|
si_signo*: cint ## Signal number.
|
||||||
si_code*: cint ## Signal code.
|
si_code*: cint ## Signal code.
|
||||||
si_errno*: cint ## If non-zero, an errno value associated with
|
si_errno*: cint ## If non-zero, an errno value associated with
|
||||||
|
|
@ -324,7 +319,7 @@ type
|
||||||
Tnl_item* {.importc: "nl_item", header: "<nl_types.h>".} = cint
|
Tnl_item* {.importc: "nl_item", header: "<nl_types.h>".} = cint
|
||||||
Tnl_catd* {.importc: "nl_catd", header: "<nl_types.h>".} = cint
|
Tnl_catd* {.importc: "nl_catd", header: "<nl_types.h>".} = cint
|
||||||
|
|
||||||
Tsched_param* {.importc: "struct sched_param", header: "<sched.h>", final.} = object
|
Tsched_param* {.importc: "struct sched_param", header: "<sched.h>", final, pure.} = object
|
||||||
sched_priority*: cint
|
sched_priority*: cint
|
||||||
sched_ss_low_priority*: cint ## Low scheduling priority for
|
sched_ss_low_priority*: cint ## Low scheduling priority for
|
||||||
## sporadic server.
|
## sporadic server.
|
||||||
|
|
@ -334,15 +329,12 @@ type
|
||||||
sched_ss_max_repl*: cint ## Maximum pending replenishments for
|
sched_ss_max_repl*: cint ## Maximum pending replenishments for
|
||||||
## sporadic server.
|
## sporadic server.
|
||||||
|
|
||||||
Ttimeval* {.importc: "struct timeval", header: "<sys/select.h>", final.} = object
|
Ttimeval* {.importc: "struct timeval", header: "<sys/select.h>", final, pure.} = object
|
||||||
tv_sec*: ttime ## Seconds.
|
tv_sec*: ttime ## Seconds.
|
||||||
tv_usec*: tsuseconds ## Microseconds.
|
tv_usec*: tsuseconds ## Microseconds.
|
||||||
Tfd_set* {.importc: "struct fd_set", header: "<sys/select.h>", final.} = object
|
Tfd_set* {.importc: "struct fd_set", header: "<sys/select.h>", final, pure.} = object
|
||||||
|
Tmcontext* {.importc: "mcontext_t", header: "<ucontext.h>", final, pure.} = object
|
||||||
Tposix_spawnattr* {.importc: "posix_spawnattr_t", header: "<spawn.h>".} = cint
|
Tucontext* {.importc: "ucontext_t", header: "<ucontext.h>", final, pure.} = object
|
||||||
Tposix_spawn_file_actions* {.importc: "posix_spawn_file_actions_t", header: "<spawn.h>".} = cint
|
|
||||||
Tmcontext* {.importc: "mcontext_t", header: "<ucontext.h>", final.} = object
|
|
||||||
Tucontext* {.importc: "ucontext_t", header: "<ucontext.h>", final.} = object
|
|
||||||
uc_link*: ptr Tucontext ## Pointer to the context that is resumed
|
uc_link*: ptr Tucontext ## Pointer to the context that is resumed
|
||||||
## when this context returns.
|
## when this context returns.
|
||||||
uc_sigmask*: Tsigset ## The set of signals that are blocked when this
|
uc_sigmask*: Tsigset ## The set of signals that are blocked when this
|
||||||
|
|
@ -351,10 +343,26 @@ type
|
||||||
uc_mcontext*: Tmcontext ## A machine-specific representation of the saved
|
uc_mcontext*: Tmcontext ## A machine-specific representation of the saved
|
||||||
## context.
|
## context.
|
||||||
|
|
||||||
|
when hasAioH:
|
||||||
|
type
|
||||||
|
Taiocb* {.importc: "struct aiocb", header: "<aio.h>", final, pure.} = object
|
||||||
|
aio_fildes*: cint ## File descriptor.
|
||||||
|
aio_offset*: TOff ## File offset.
|
||||||
|
aio_buf*: pointer ## Location of buffer.
|
||||||
|
aio_nbytes*: int ## Length of transfer.
|
||||||
|
aio_reqprio*: cint ## Request priority offset.
|
||||||
|
aio_sigevent*: TSigEvent ## Signal number and value.
|
||||||
|
aio_lio_opcode: cint ## Operation to be performed.
|
||||||
|
|
||||||
|
when hasSpawnH:
|
||||||
|
type
|
||||||
|
Tposix_spawnattr* {.importc: "posix_spawnattr_t", header: "<spawn.h>".} = cint
|
||||||
|
Tposix_spawn_file_actions* {.importc: "posix_spawn_file_actions_t", header: "<spawn.h>".} = cint
|
||||||
|
|
||||||
|
|
||||||
# Constants as variables:
|
# Constants as variables:
|
||||||
var
|
when hasAioH:
|
||||||
|
var
|
||||||
AIO_ALLDONE* {.importc, header: "<aio.h>".}: cint
|
AIO_ALLDONE* {.importc, header: "<aio.h>".}: cint
|
||||||
## A return value indicating that none of the requested operations
|
## A return value indicating that none of the requested operations
|
||||||
## could be canceled since they are already complete.
|
## could be canceled since they are already complete.
|
||||||
|
|
@ -380,6 +388,7 @@ var
|
||||||
LIO_WRITE* {.importc, header: "<aio.h>".}: cint
|
LIO_WRITE* {.importc, header: "<aio.h>".}: cint
|
||||||
## A lio_listio() element operation option requesting a write.
|
## A lio_listio() element operation option requesting a write.
|
||||||
|
|
||||||
|
var
|
||||||
RTLD_LAZY* {.importc, header: "<dlfcn.h>".}: cint
|
RTLD_LAZY* {.importc, header: "<dlfcn.h>".}: cint
|
||||||
## Relocations are performed at an implementation-defined time.
|
## Relocations are performed at an implementation-defined time.
|
||||||
RTLD_NOW* {.importc, header: "<dlfcn.h>".}: cint
|
RTLD_NOW* {.importc, header: "<dlfcn.h>".}: cint
|
||||||
|
|
@ -1246,6 +1255,12 @@ var
|
||||||
SCHED_OTHER* {.importc, header: "<sched.h>".}: cint
|
SCHED_OTHER* {.importc, header: "<sched.h>".}: cint
|
||||||
FD_SETSIZE* {.importc, header: "<sys/select.h>".}: cint
|
FD_SETSIZE* {.importc, header: "<sys/select.h>".}: cint
|
||||||
|
|
||||||
|
SEEK_SET* {.importc, header: "<unistd.h>".}: cint
|
||||||
|
SEEK_CUR* {.importc, header: "<unistd.h>".}: cint
|
||||||
|
SEEK_END* {.importc, header: "<unistd.h>".}: cint
|
||||||
|
|
||||||
|
when hasSpawnh:
|
||||||
|
var
|
||||||
POSIX_SPAWN_RESETIDS* {.importc, header: "<spawn.h>".}: cint
|
POSIX_SPAWN_RESETIDS* {.importc, header: "<spawn.h>".}: cint
|
||||||
POSIX_SPAWN_SETPGROUP* {.importc, header: "<spawn.h>".}: cint
|
POSIX_SPAWN_SETPGROUP* {.importc, header: "<spawn.h>".}: cint
|
||||||
POSIX_SPAWN_SETSCHEDPARAM* {.importc, header: "<spawn.h>".}: cint
|
POSIX_SPAWN_SETSCHEDPARAM* {.importc, header: "<spawn.h>".}: cint
|
||||||
|
|
@ -1253,15 +1268,16 @@ var
|
||||||
POSIX_SPAWN_SETSIGDEF* {.importc, header: "<spawn.h>".}: cint
|
POSIX_SPAWN_SETSIGDEF* {.importc, header: "<spawn.h>".}: cint
|
||||||
POSIX_SPAWN_SETSIGMASK* {.importc, header: "<spawn.h>".}: cint
|
POSIX_SPAWN_SETSIGMASK* {.importc, header: "<spawn.h>".}: cint
|
||||||
|
|
||||||
proc aio_cancel*(a1: cint, a2: ptr Taiocb): cint {.importc, header: "<aio.h>".}
|
when hasAioH:
|
||||||
proc aio_error*(a1: ptr Taiocb): cint {.importc, header: "<aio.h>".}
|
proc aio_cancel*(a1: cint, a2: ptr Taiocb): cint {.importc, header: "<aio.h>".}
|
||||||
proc aio_fsync*(a1: cint, a2: ptr Taiocb): cint {.importc, header: "<aio.h>".}
|
proc aio_error*(a1: ptr Taiocb): cint {.importc, header: "<aio.h>".}
|
||||||
proc aio_read*(a1: ptr Taiocb): cint {.importc, header: "<aio.h>".}
|
proc aio_fsync*(a1: cint, a2: ptr Taiocb): cint {.importc, header: "<aio.h>".}
|
||||||
proc aio_return*(a1: ptr Taiocb): int {.importc, header: "<aio.h>".}
|
proc aio_read*(a1: ptr Taiocb): cint {.importc, header: "<aio.h>".}
|
||||||
proc aio_suspend*(a1: ptr ptr Taiocb, a2: cint, a3: ptr ttimespec): cint {.
|
proc aio_return*(a1: ptr Taiocb): int {.importc, header: "<aio.h>".}
|
||||||
|
proc aio_suspend*(a1: ptr ptr Taiocb, a2: cint, a3: ptr ttimespec): cint {.
|
||||||
importc, header: "<aio.h>".}
|
importc, header: "<aio.h>".}
|
||||||
proc aio_write*(a1: ptr Taiocb): cint {.importc, header: "<aio.h>".}
|
proc aio_write*(a1: ptr Taiocb): cint {.importc, header: "<aio.h>".}
|
||||||
proc lio_listio*(a1: cint, a2: ptr ptr Taiocb, a3: cint,
|
proc lio_listio*(a1: cint, a2: ptr ptr Taiocb, a3: cint,
|
||||||
a4: ptr Tsigevent): cint {.importc, header: "<aio.h>".}
|
a4: ptr Tsigevent): cint {.importc, header: "<aio.h>".}
|
||||||
|
|
||||||
# arpa/inet.h
|
# arpa/inet.h
|
||||||
|
|
@ -1371,7 +1387,7 @@ proc mq_unlink*(a1: cstring): cint {.importc, header: "<mqueue.h>".}
|
||||||
|
|
||||||
proc getpwnam*(a1: cstring): ptr TPasswd {.importc, header: "<pwd.h>".}
|
proc getpwnam*(a1: cstring): ptr TPasswd {.importc, header: "<pwd.h>".}
|
||||||
proc getpwuid*(a1: Tuid): ptr TPasswd {.importc, header: "<pwd.h>".}
|
proc getpwuid*(a1: Tuid): ptr TPasswd {.importc, header: "<pwd.h>".}
|
||||||
proc getpwnam_r(a1: cstring, a2: ptr Tpasswd, a3: cstring, a4: int,
|
proc getpwnam_r*(a1: cstring, a2: ptr Tpasswd, a3: cstring, a4: int,
|
||||||
a5: ptr ptr Tpasswd): cint {.importc, header: "<pwd.h>".}
|
a5: ptr ptr Tpasswd): cint {.importc, header: "<pwd.h>".}
|
||||||
proc getpwuid_r*(a1: Tuid, a2: ptr Tpasswd, a3: cstring,
|
proc getpwuid_r*(a1: Tuid, a2: ptr Tpasswd, a3: cstring,
|
||||||
a4: int, a5: ptr ptr Tpasswd): cint {.importc, header: "<pwd.h>".}
|
a4: int, a5: ptr ptr Tpasswd): cint {.importc, header: "<pwd.h>".}
|
||||||
|
|
@ -1771,43 +1787,44 @@ proc pselect*(a1: cint, a2, a3, a4: var Tfd_set, a5: var ttimespec,
|
||||||
proc select*(a1: cint, a2, a3, a4: var Tfd_set, a5: var ttimeval): cint {.
|
proc select*(a1: cint, a2, a3, a4: var Tfd_set, a5: var ttimeval): cint {.
|
||||||
importc, header: "<sys/select.h>".}
|
importc, header: "<sys/select.h>".}
|
||||||
|
|
||||||
proc posix_spawn*(a1: var tpid, a2: cstring,
|
when hasSpawnH:
|
||||||
|
proc posix_spawn*(a1: var tpid, a2: cstring,
|
||||||
a3: var Tposix_spawn_file_actions,
|
a3: var Tposix_spawn_file_actions,
|
||||||
a4: var Tposix_spawnattr, a5, a6: cstringArray): cint {.importc, header: "<spawn.h>".}
|
a4: var Tposix_spawnattr, a5, a6: cstringArray): cint {.importc, header: "<spawn.h>".}
|
||||||
proc posix_spawn_file_actions_addclose*(a1: var tposix_spawn_file_actions,
|
proc posix_spawn_file_actions_addclose*(a1: var tposix_spawn_file_actions,
|
||||||
a2: cint): cint {.importc, header: "<spawn.h>".}
|
a2: cint): cint {.importc, header: "<spawn.h>".}
|
||||||
proc posix_spawn_file_actions_adddup2*(a1: var tposix_spawn_file_actions,
|
proc posix_spawn_file_actions_adddup2*(a1: var tposix_spawn_file_actions,
|
||||||
a2, a3: cint): cint {.importc, header: "<spawn.h>".}
|
a2, a3: cint): cint {.importc, header: "<spawn.h>".}
|
||||||
proc posix_spawn_file_actions_addopen*(a1: var tposix_spawn_file_actions,
|
proc posix_spawn_file_actions_addopen*(a1: var tposix_spawn_file_actions,
|
||||||
a2: cint, a3: cstring, a4: cint, a5: tmode): cint {.importc, header: "<spawn.h>".}
|
a2: cint, a3: cstring, a4: cint, a5: tmode): cint {.importc, header: "<spawn.h>".}
|
||||||
proc posix_spawn_file_actions_destroy*(a1: var tposix_spawn_file_actions): cint {.importc, header: "<spawn.h>".}
|
proc posix_spawn_file_actions_destroy*(a1: var tposix_spawn_file_actions): cint {.importc, header: "<spawn.h>".}
|
||||||
proc posix_spawn_file_actions_init*(a1: var tposix_spawn_file_actions): cint {.importc, header: "<spawn.h>".}
|
proc posix_spawn_file_actions_init*(a1: var tposix_spawn_file_actions): cint {.importc, header: "<spawn.h>".}
|
||||||
proc posix_spawnattr_destroy*(a1: var tposix_spawnattr): cint {.importc, header: "<spawn.h>".}
|
proc posix_spawnattr_destroy*(a1: var tposix_spawnattr): cint {.importc, header: "<spawn.h>".}
|
||||||
proc posix_spawnattr_getsigdefault*(a1: var tposix_spawnattr,
|
proc posix_spawnattr_getsigdefault*(a1: var tposix_spawnattr,
|
||||||
a2: var Tsigset): cint {.importc, header: "<spawn.h>".}
|
a2: var Tsigset): cint {.importc, header: "<spawn.h>".}
|
||||||
proc posix_spawnattr_getflags*(a1: var tposix_spawnattr,
|
proc posix_spawnattr_getflags*(a1: var tposix_spawnattr,
|
||||||
a2: var cshort): cint {.importc, header: "<spawn.h>".}
|
a2: var cshort): cint {.importc, header: "<spawn.h>".}
|
||||||
proc posix_spawnattr_getpgroup*(a1: var tposix_spawnattr,
|
proc posix_spawnattr_getpgroup*(a1: var tposix_spawnattr,
|
||||||
a2: var tpid): cint {.importc, header: "<spawn.h>".}
|
a2: var tpid): cint {.importc, header: "<spawn.h>".}
|
||||||
proc posix_spawnattr_getschedparam*(a1: var tposix_spawnattr,
|
proc posix_spawnattr_getschedparam*(a1: var tposix_spawnattr,
|
||||||
a2: var tsched_param): cint {.importc, header: "<spawn.h>".}
|
a2: var tsched_param): cint {.importc, header: "<spawn.h>".}
|
||||||
proc posix_spawnattr_getschedpolicy*(a1: var tposix_spawnattr,
|
proc posix_spawnattr_getschedpolicy*(a1: var tposix_spawnattr,
|
||||||
a2: var cint): cint {.importc, header: "<spawn.h>".}
|
a2: var cint): cint {.importc, header: "<spawn.h>".}
|
||||||
proc posix_spawnattr_getsigmask*(a1: var tposix_spawnattr,
|
proc posix_spawnattr_getsigmask*(a1: var tposix_spawnattr,
|
||||||
a2: var tsigset): cint {.importc, header: "<spawn.h>".}
|
a2: var tsigset): cint {.importc, header: "<spawn.h>".}
|
||||||
|
|
||||||
proc posix_spawnattr_init*(a1: var tposix_spawnattr): cint {.importc, header: "<spawn.h>".}
|
proc posix_spawnattr_init*(a1: var tposix_spawnattr): cint {.importc, header: "<spawn.h>".}
|
||||||
proc posix_spawnattr_setsigdefault*(a1: var tposix_spawnattr,
|
proc posix_spawnattr_setsigdefault*(a1: var tposix_spawnattr,
|
||||||
a2: var tsigset): cint {.importc, header: "<spawn.h>".}
|
a2: var tsigset): cint {.importc, header: "<spawn.h>".}
|
||||||
proc posix_spawnattr_setflags*(a1: var tposix_spawnattr, a2: cshort): cint {.importc, header: "<spawn.h>".}
|
proc posix_spawnattr_setflags*(a1: var tposix_spawnattr, a2: cshort): cint {.importc, header: "<spawn.h>".}
|
||||||
proc posix_spawnattr_setpgroup*(a1: var tposix_spawnattr, a2: tpid): cint {.importc, header: "<spawn.h>".}
|
proc posix_spawnattr_setpgroup*(a1: var tposix_spawnattr, a2: tpid): cint {.importc, header: "<spawn.h>".}
|
||||||
|
|
||||||
proc posix_spawnattr_setschedparam*(a1: var tposix_spawnattr,
|
proc posix_spawnattr_setschedparam*(a1: var tposix_spawnattr,
|
||||||
a2: var tsched_param): cint {.importc, header: "<spawn.h>".}
|
a2: var tsched_param): cint {.importc, header: "<spawn.h>".}
|
||||||
proc posix_spawnattr_setschedpolicy*(a1: var tposix_spawnattr, a2: cint): cint {.importc, header: "<spawn.h>".}
|
proc posix_spawnattr_setschedpolicy*(a1: var tposix_spawnattr, a2: cint): cint {.importc, header: "<spawn.h>".}
|
||||||
proc posix_spawnattr_setsigmask*(a1: var tposix_spawnattr,
|
proc posix_spawnattr_setsigmask*(a1: var tposix_spawnattr,
|
||||||
a2: var tsigset): cint {.importc, header: "<spawn.h>".}
|
a2: var tsigset): cint {.importc, header: "<spawn.h>".}
|
||||||
proc posix_spawnp*(a1: var tpid, a2: cstring,
|
proc posix_spawnp*(a1: var tpid, a2: cstring,
|
||||||
a3: var tposix_spawn_file_actions,
|
a3: var tposix_spawn_file_actions,
|
||||||
a4: var tposix_spawnattr,
|
a4: var tposix_spawnattr,
|
||||||
a5, a6: cstringArray): cint {.importc, header: "<spawn.h>".}
|
a5, a6: cstringArray): cint {.importc, header: "<spawn.h>".}
|
||||||
|
|
|
||||||
1009
lib/process.nim
1009
lib/process.nim
File diff suppressed because it is too large
Load diff
|
|
@ -85,7 +85,7 @@ proc reprSetAux(result: var string, p: pointer, typ: PNimType) =
|
||||||
else:
|
else:
|
||||||
var a = cast[pbyteArray](p)
|
var a = cast[pbyteArray](p)
|
||||||
for i in 0 .. typ.size*8-1:
|
for i in 0 .. typ.size*8-1:
|
||||||
if (a[i div 8] and (1 shl (i mod 8))) != 0:
|
if (ze(a[i div 8]) and (1 shl (i mod 8))) != 0:
|
||||||
if elemCounter > 0: add result, ", "
|
if elemCounter > 0: add result, ", "
|
||||||
addSetElem(result, i+typ.node.len, typ.base)
|
addSetElem(result, i+typ.node.len, typ.base)
|
||||||
inc(elemCounter)
|
inc(elemCounter)
|
||||||
|
|
|
||||||
22
lib/sets.nim
22
lib/sets.nim
|
|
@ -24,36 +24,36 @@ include cntbits
|
||||||
|
|
||||||
proc unionSets(res: var TNimSet, a, b: TNimSet, len: int) {.
|
proc unionSets(res: var TNimSet, a, b: TNimSet, len: int) {.
|
||||||
compilerproc, inline.} =
|
compilerproc, inline.} =
|
||||||
for i in countup(0, len-1): res[i] = toU8(ze(a[i]) or ze(b[i]))
|
for i in countup(0, len-1): res[i] = a[i] or b[i]
|
||||||
|
|
||||||
proc diffSets(res: var TNimSet, a, b: TNimSet, len: int) {.
|
proc diffSets(res: var TNimSet, a, b: TNimSet, len: int) {.
|
||||||
compilerproc, inline.} =
|
compilerproc, inline.} =
|
||||||
for i in countup(0, len-1): res[i] = toU8(ze(a[i]) and not ze(b[i]))
|
for i in countup(0, len-1): res[i] = a[i] and not b[i]
|
||||||
|
|
||||||
proc intersectSets(res: var TNimSet, a, b: TNimSet, len: int) {.
|
proc intersectSets(res: var TNimSet, a, b: TNimSet, len: int) {.
|
||||||
compilerproc, inline.} =
|
compilerproc, inline.} =
|
||||||
for i in countup(0, len-1): res[i] = toU8(ze(a[i]) and ze(b[i]))
|
for i in countup(0, len-1): res[i] = a[i] and b[i]
|
||||||
|
|
||||||
proc symdiffSets(res: var TNimSet, a, b: TNimSet, len: int) {.
|
proc symdiffSets(res: var TNimSet, a, b: TNimSet, len: int) {.
|
||||||
compilerproc, inline.} =
|
compilerproc, inline.} =
|
||||||
for i in countup(0, len-1): res[i] = toU8(ze(a[i]) xor ze(b[i]))
|
for i in countup(0, len-1): res[i] = a[i] xor b[i]
|
||||||
|
|
||||||
proc containsSets(a, b: TNimSet, len: int): bool {.compilerproc, inline.} =
|
proc containsSets(a, b: TNimSet, len: int): bool {.compilerproc, inline.} =
|
||||||
# s1 <= s2 ?
|
# s1 <= s2 ?
|
||||||
for i in countup(0, len-1):
|
for i in countup(0, len-1):
|
||||||
if (ze(a[i]) and not ze(b[i])) != 0: return false
|
if (a[i] and not b[i]) != 0'i8: return false
|
||||||
return true
|
return true
|
||||||
|
|
||||||
proc containsSubsets(a, b: TNimSet, len: int): bool {.compilerproc, inline.} =
|
proc containsSubsets(a, b: TNimSet, len: int): bool {.compilerproc, inline.} =
|
||||||
# s1 < s2 ?
|
# s1 < s2 ?
|
||||||
result = false # assume they are equal
|
result = false # assume they are equal
|
||||||
for i in countup(0, len-1):
|
for i in countup(0, len-1):
|
||||||
if (ze(a[i]) and not ze(b[i])) != 0: return false
|
if (a[i]) and not b[i]) != 0'i32: return false
|
||||||
if ze(a[i]) != ze(b[i]): result = true # they are not equal
|
if a[i] != b[i]: result = true # they are not equal
|
||||||
|
|
||||||
proc equalSets(a, b: TNimSet, len: int): bool {.compilerproc, inline.} =
|
proc equalSets(a, b: TNimSet, len: int): bool {.compilerproc, inline.} =
|
||||||
for i in countup(0, len-1):
|
for i in countup(0, len-1):
|
||||||
if ze(a[i]) != ze(b[i]): return false
|
if a[i] != b[i]: return false
|
||||||
return true
|
return true
|
||||||
|
|
||||||
proc cardSet(s: TNimSet, len: int): int {.compilerproc, inline.} =
|
proc cardSet(s: TNimSet, len: int): int {.compilerproc, inline.} =
|
||||||
|
|
@ -68,7 +68,7 @@ proc inSet(s: TNimSet, elem: int): bool {.compilerproc, inline.} =
|
||||||
return (s[elem /% WORD_SIZE] and (1 shl (elem %% WORD_SIZE))) != 0
|
return (s[elem /% WORD_SIZE] and (1 shl (elem %% WORD_SIZE))) != 0
|
||||||
|
|
||||||
proc inclSets(s: var TNimSet, e: int) {.compilerproc, inline.} =
|
proc inclSets(s: var TNimSet, e: int) {.compilerproc, inline.} =
|
||||||
s[e /% WORD_SIZE] = toU8(s[e /% WORD_SIZE] or (1 shl (e %% WORD_SIZE)))
|
s[e /% WORD_SIZE] = s[e /% WORD_SIZE] or toU8(1 shl (e %% WORD_SIZE))
|
||||||
|
|
||||||
proc inclRange(s: var TNimSet, first, last: int) {.compilerproc.} =
|
proc inclRange(s: var TNimSet, first, last: int) {.compilerproc.} =
|
||||||
# not very fast, but it is seldom used
|
# not very fast, but it is seldom used
|
||||||
|
|
@ -80,8 +80,8 @@ proc smallInclRange(s: var int, first, last: int) {.compilerproc.} =
|
||||||
s = s or (1 shl (i %% sizeof(int)*8))
|
s = s or (1 shl (i %% sizeof(int)*8))
|
||||||
|
|
||||||
proc exclSets(s: var TNimSet, e: int) {.compilerproc, inline.} =
|
proc exclSets(s: var TNimSet, e: int) {.compilerproc, inline.} =
|
||||||
s[e /% WORD_SIZE] = toU8(s[e /% WORD_SIZE] and
|
s[e /% WORD_SIZE] = s[e /% WORD_SIZE] and
|
||||||
not (1 shl (e %% WORD_SIZE)))
|
not toU8(1 shl (e %% WORD_SIZE))
|
||||||
|
|
||||||
proc smallContainsSubsets(a, b: int): bool {.compilerProc, inline.} =
|
proc smallContainsSubsets(a, b: int): bool {.compilerProc, inline.} =
|
||||||
# not used by new code generator
|
# not used by new code generator
|
||||||
|
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
# Handle small allocations efficiently
|
|
||||||
# We allocate and manage memory by pages. All objects within a page belong to
|
|
||||||
# the same type. Thus, we safe the type field. Minimum requested block is
|
|
||||||
# 8 bytes. Alignment is 8 bytes.
|
|
||||||
|
|
||||||
|
|
||||||
type
|
|
||||||
TChunk {.pure.} = object
|
|
||||||
kind: TChunkKind
|
|
||||||
prev, next: ptr TChunk
|
|
||||||
|
|
||||||
TSmallChunk = object of TChunk # all objects of the same size
|
|
||||||
typ: PNimType
|
|
||||||
free: int
|
|
||||||
data: array [0.., int]
|
|
||||||
|
|
||||||
proc allocSmall(typ: PNimType): pointer =
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -83,8 +83,7 @@ proc newStringTable(mode: TStringTableMode = modeCaseSensitive): PStringTable =
|
||||||
new(result)
|
new(result)
|
||||||
result.mode = mode
|
result.mode = mode
|
||||||
result.counter = 0
|
result.counter = 0
|
||||||
result.data = []
|
newSeq(result.data, startSize)
|
||||||
setlen(result.data, startSize) # XXX
|
|
||||||
|
|
||||||
proc newStringTable(keyValuePairs: openarray[string],
|
proc newStringTable(keyValuePairs: openarray[string],
|
||||||
mode: TStringTableMode = modeCaseSensitive): PStringTable =
|
mode: TStringTableMode = modeCaseSensitive): PStringTable =
|
||||||
|
|
@ -110,9 +109,6 @@ proc mustRehash(length, counter: int): bool =
|
||||||
assert(length > counter)
|
assert(length > counter)
|
||||||
result = (length * 2 < counter * 3) or (length - counter < 4)
|
result = (length * 2 < counter * 3) or (length - counter < 4)
|
||||||
|
|
||||||
const
|
|
||||||
EmptySeq = []
|
|
||||||
|
|
||||||
proc nextTry(h, maxHash: THash): THash =
|
proc nextTry(h, maxHash: THash): THash =
|
||||||
result = ((5 * h) + 1) and maxHash # For any initial h in range(maxHash), repeating that maxHash times
|
result = ((5 * h) + 1) and maxHash # For any initial h in range(maxHash), repeating that maxHash times
|
||||||
# generates each int in range(maxHash) exactly once (see any text on
|
# generates each int in range(maxHash) exactly once (see any text on
|
||||||
|
|
@ -146,8 +142,7 @@ proc RawInsert(t: PStringTable, data: var TKeyValuePairSeq, key, val: string) =
|
||||||
|
|
||||||
proc Enlarge(t: PStringTable) =
|
proc Enlarge(t: PStringTable) =
|
||||||
var n: TKeyValuePairSeq
|
var n: TKeyValuePairSeq
|
||||||
n = emptySeq
|
newSeq(n, len(t.data) * growthFactor)
|
||||||
setlen(n, len(t.data) * growthFactor)
|
|
||||||
for i in countup(0, high(t.data)):
|
for i in countup(0, high(t.data)):
|
||||||
if not isNil(t.data[i].key): RawInsert(t, n, t.data[i].key, t.data[i].val)
|
if not isNil(t.data[i].key): RawInsert(t, n, t.data[i].key, t.data[i].val)
|
||||||
swap(t.data, n)
|
swap(t.data, n)
|
||||||
|
|
|
||||||
177
lib/strutils.nim
177
lib/strutils.nim
|
|
@ -24,6 +24,7 @@ template newException(exceptn, message: expr): expr =
|
||||||
e.msg = message
|
e.msg = message
|
||||||
e
|
e
|
||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
TCharSet* = set[char] # for compability for Nim
|
TCharSet* = set[char] # for compability for Nim
|
||||||
|
|
||||||
|
|
@ -73,6 +74,9 @@ proc findSubStr*(sub: char, s: string, start: int = 0): int {.noSideEffect.}
|
||||||
proc replaceStr*(s, sub, by: string): string {.noSideEffect.}
|
proc replaceStr*(s, sub, by: string): string {.noSideEffect.}
|
||||||
## Replaces `sub` in `s` by the string `by`.
|
## Replaces `sub` in `s` by the string `by`.
|
||||||
|
|
||||||
|
proc replaceStr*(s: string, sub, by: char): string {.noSideEffect.}
|
||||||
|
## optimized version for characters.
|
||||||
|
|
||||||
proc deleteStr*(s: var string, first, last: int)
|
proc deleteStr*(s: var string, first, last: int)
|
||||||
## Deletes in `s` the characters at position `first`..`last`. This modifies
|
## Deletes in `s` the characters at position `first`..`last`. This modifies
|
||||||
## `s` itself, it does not return a copy.
|
## `s` itself, it does not return a copy.
|
||||||
|
|
@ -113,6 +117,43 @@ iterator split*(s: string, seps: set[char] = Whitespace): string =
|
||||||
while last < len(s) and s[last] not_in seps: inc(last) # BUGFIX!
|
while last < len(s) and s[last] not_in seps: inc(last) # BUGFIX!
|
||||||
yield copy(s, first, last-1)
|
yield copy(s, first, last-1)
|
||||||
|
|
||||||
|
iterator splitLines*(s: string): string =
|
||||||
|
## Splits the string `s` into its containing lines. Each newline
|
||||||
|
## combination (CR, LF, CR-LF) is supported. The result strings contain
|
||||||
|
## no trailing ``\n``.
|
||||||
|
##
|
||||||
|
## Example::
|
||||||
|
##
|
||||||
|
## for line in lines("\nthis\nis\nan\n\nexample\n"):
|
||||||
|
## writeln(stdout, line)
|
||||||
|
##
|
||||||
|
## Results in::
|
||||||
|
##
|
||||||
|
## ""
|
||||||
|
## "this"
|
||||||
|
## "is"
|
||||||
|
## "an"
|
||||||
|
## ""
|
||||||
|
## "example"
|
||||||
|
## ""
|
||||||
|
var first = 0
|
||||||
|
var last = 0
|
||||||
|
while true:
|
||||||
|
while s[last] notin {'\0', '\c', '\l'}: inc(last)
|
||||||
|
yield copy(s, first, last-1)
|
||||||
|
# skip newlines:
|
||||||
|
if s[last] == '\l': inc(last)
|
||||||
|
elif s[last] == '\c':
|
||||||
|
inc(last)
|
||||||
|
if s[last] == '\l': inc(last)
|
||||||
|
else: break # was '\0'
|
||||||
|
first = last
|
||||||
|
|
||||||
|
proc splitLinesSeq*(s: string): seq[string] {.noSideEffect.} =
|
||||||
|
## The same as `split`, but is a proc that returns a sequence of substrings.
|
||||||
|
result = @[]
|
||||||
|
for line in splitLines(s): add(result, line)
|
||||||
|
|
||||||
proc splitSeq*(s: string, seps: set[char] = Whitespace): seq[string] {.
|
proc splitSeq*(s: string, seps: set[char] = Whitespace): seq[string] {.
|
||||||
noSideEffect.}
|
noSideEffect.}
|
||||||
## The same as `split`, but is a proc that returns a sequence of substrings.
|
## The same as `split`, but is a proc that returns a sequence of substrings.
|
||||||
|
|
@ -159,7 +200,8 @@ proc ParseBiggestInt*(s: string): biggestInt {.noSideEffect.}
|
||||||
|
|
||||||
proc ParseFloat*(s: string): float {.noSideEffect.}
|
proc ParseFloat*(s: string): float {.noSideEffect.}
|
||||||
## Parses a decimal floating point value contained in `s`. If `s` is not
|
## Parses a decimal floating point value contained in `s`. If `s` is not
|
||||||
## a valid floating point number, `EInvalidValue` is raised.
|
## a valid floating point number, `EInvalidValue` is raised. ``NAN``,
|
||||||
|
## ``INF``, ``-INF`` are also supported (case insensitive comparison).
|
||||||
# XXX: make this biggestfloat.
|
# XXX: make this biggestfloat.
|
||||||
|
|
||||||
# the stringify and format operators:
|
# the stringify and format operators:
|
||||||
|
|
@ -344,7 +386,7 @@ proc cmpIgnoreStyle(a, b: string): int =
|
||||||
# ---------- splitting -----------------------------------------------------
|
# ---------- splitting -----------------------------------------------------
|
||||||
|
|
||||||
proc splitSeq(s: string, seps: set[char]): seq[string] =
|
proc splitSeq(s: string, seps: set[char]): seq[string] =
|
||||||
result = []
|
result = @[]
|
||||||
for sub in split(s, seps): add result, sub
|
for sub in split(s, seps): add result, sub
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
@ -469,6 +511,14 @@ proc replaceStr(s, sub, by: string): string =
|
||||||
# copy the rest:
|
# copy the rest:
|
||||||
add result, copy(s, i)
|
add result, copy(s, i)
|
||||||
|
|
||||||
|
proc replaceStr(s: string, sub, by: char): string =
|
||||||
|
result = newString(s.len)
|
||||||
|
var i = 0
|
||||||
|
while i < s.len:
|
||||||
|
if s[i] == sub: result[i] = by
|
||||||
|
else: result[i] = s[i]
|
||||||
|
inc(i)
|
||||||
|
|
||||||
proc deleteStr(s: var string, first, last: int) =
|
proc deleteStr(s: var string, first, last: int) =
|
||||||
# example: "abc___uvwxyz\0" (___ is to be deleted)
|
# example: "abc___uvwxyz\0" (___ is to be deleted)
|
||||||
# --> first == 3, last == 5
|
# --> first == 3, last == 5
|
||||||
|
|
@ -489,7 +539,7 @@ proc toHex(x: BiggestInt, len: int): string =
|
||||||
shift: BiggestInt
|
shift: BiggestInt
|
||||||
result = newString(len)
|
result = newString(len)
|
||||||
for j in countdown(len-1, 0):
|
for j in countdown(len-1, 0):
|
||||||
result[j] = HexChars[toU32(x shr shift) and 0xF]
|
result[j] = HexChars[toU32(x shr shift) and 0xF'i32]
|
||||||
shift = shift + 4
|
shift = shift + 4
|
||||||
|
|
||||||
{.push overflowChecks: on.}
|
{.push overflowChecks: on.}
|
||||||
|
|
@ -552,6 +602,16 @@ proc ParseFloat(s: string): float =
|
||||||
elif s[i] == '-':
|
elif s[i] == '-':
|
||||||
sign = -1.0
|
sign = -1.0
|
||||||
inc(i)
|
inc(i)
|
||||||
|
if s[i] == 'N' or s[i] == 'n':
|
||||||
|
if s[i+1] == 'A' or s[i+1] == 'a':
|
||||||
|
if s[i+2] == 'N' or s[i+2] == 'n':
|
||||||
|
if s[i+3] == '\0': return NaN
|
||||||
|
raise newException(EInvalidValue, "invalid float: " & s)
|
||||||
|
if s[i] == 'I' or s[i] == 'i':
|
||||||
|
if s[i+1] == 'N' or s[i+1] == 'n':
|
||||||
|
if s[i+2] == 'F' or s[i+2] == 'f':
|
||||||
|
if s[i+3] == '\0': return Inf*sign
|
||||||
|
raise newException(EInvalidValue, "invalid float: " & s)
|
||||||
while s[i] in {'0'..'9'}:
|
while s[i] in {'0'..'9'}:
|
||||||
# Read integer part
|
# Read integer part
|
||||||
flags = flags or 1
|
flags = flags or 1
|
||||||
|
|
@ -572,7 +632,7 @@ proc ParseFloat(s: string): float =
|
||||||
result = result / hd # this complicated way preserves precision
|
result = result / hd # this complicated way preserves precision
|
||||||
# Again, read integer and fractional part
|
# Again, read integer and fractional part
|
||||||
if flags == 0:
|
if flags == 0:
|
||||||
raise newException(EInvalidValue, "invalid float:" & s)
|
raise newException(EInvalidValue, "invalid float: " & s)
|
||||||
# Exponent?
|
# Exponent?
|
||||||
if s[i] in {'e', 'E'}:
|
if s[i] in {'e', 'E'}:
|
||||||
inc(i)
|
inc(i)
|
||||||
|
|
@ -624,4 +684,113 @@ proc toBin*(x: BiggestInt, len: int): string =
|
||||||
shift = shift + 1
|
shift = shift + 1
|
||||||
mask = mask shl 1
|
mask = mask shl 1
|
||||||
|
|
||||||
|
proc escape*(s: string, prefix, suffix = "\""): string =
|
||||||
|
## Escapes a string `s`. This does these operations (at the same time):
|
||||||
|
## * replaces any ``\`` by ``\\``
|
||||||
|
## * replaces any ``'`` by ``\'``
|
||||||
|
## * replaces any ``"`` by ``\"``
|
||||||
|
## * replaces any other character in the set ``{'\0'..'\31', '\128'..'\255'}``
|
||||||
|
## by ``\xHH`` where ``HH`` is its hexadecimal value.
|
||||||
|
## The procedure has been designed so that its output is usable for many
|
||||||
|
## different common syntaxes. The resulting string is prefixed with
|
||||||
|
## ``prefix`` and suffixed with ``suffix``. Both may be empty strings.
|
||||||
|
result = prefix
|
||||||
|
for c in items(s):
|
||||||
|
case c
|
||||||
|
of '\0'..'\31', '\128'..'\255':
|
||||||
|
add(result, '\\')
|
||||||
|
add(result, toHex(ord(c), 2))
|
||||||
|
of '\\': add(result, "\\\\")
|
||||||
|
of '\'': add(result, "\\'")
|
||||||
|
of '\"': add(result, "\\\"")
|
||||||
|
else: add(result, c)
|
||||||
|
add(result, suffix)
|
||||||
|
|
||||||
|
proc editDistance*(a, b: string): int =
|
||||||
|
## returns the edit distance between `s` and `t`. This uses the Levenshtein
|
||||||
|
## distance algorithm with only a linear memory overhead. This implementation
|
||||||
|
## is highly optimized!
|
||||||
|
var len1 = a.len
|
||||||
|
var len2 = b.len
|
||||||
|
if len1 > len2:
|
||||||
|
# make `b` the longer string
|
||||||
|
return editDistance(b, a)
|
||||||
|
|
||||||
|
# strip common prefix:
|
||||||
|
var s = 0
|
||||||
|
while a[s] == b[s] and a[s] != '\0':
|
||||||
|
inc(s)
|
||||||
|
dec(len1)
|
||||||
|
dec(len2)
|
||||||
|
# strip common suffix:
|
||||||
|
while len1 > 0 and len2 > 0 and a[s+len1-1] == b[s+len2-1]:
|
||||||
|
dec(len1)
|
||||||
|
dec(len2)
|
||||||
|
# trivial cases:
|
||||||
|
if len1 == 0: return len2
|
||||||
|
if len2 == 0: return len1
|
||||||
|
|
||||||
|
# another special case:
|
||||||
|
if len1 == 1:
|
||||||
|
for j in s..len2-1:
|
||||||
|
if a[s] == b[j]: return len2 - 1
|
||||||
|
return len2
|
||||||
|
|
||||||
|
inc(len1)
|
||||||
|
inc(len2)
|
||||||
|
var half = len1 shr 1
|
||||||
|
# initalize first row:
|
||||||
|
#var row = cast[ptr array[0..high(int) div 8, int]](alloc(len2 * sizeof(int)))
|
||||||
|
var row: seq[int]
|
||||||
|
newSeq(row, len2)
|
||||||
|
var e = s + len2 - 1 # end marker
|
||||||
|
for i in 1..len2 - half - 1: row[i] = i
|
||||||
|
row[0] = len1 - half - 1
|
||||||
|
for i in 1 .. len1 - 1:
|
||||||
|
var char1 = a[i + s - 1]
|
||||||
|
var char2p: int
|
||||||
|
var D, x: int
|
||||||
|
var p: int
|
||||||
|
if i >= len1 - half:
|
||||||
|
# skip the upper triangle:
|
||||||
|
var offset = i - len1 + half
|
||||||
|
char2p = offset
|
||||||
|
p = offset
|
||||||
|
var c3 = row[p] + ord(char1 != b[s + char2p])
|
||||||
|
inc(p)
|
||||||
|
inc(char2p)
|
||||||
|
x = row[p] + 1
|
||||||
|
D = x
|
||||||
|
if x > c3: x = c3
|
||||||
|
row[p] = x
|
||||||
|
inc(p)
|
||||||
|
else:
|
||||||
|
p = 1
|
||||||
|
char2p = 0
|
||||||
|
D = i
|
||||||
|
x = i
|
||||||
|
if i <= half + 1:
|
||||||
|
# skip the lower triangle:
|
||||||
|
e = len2 + i - half - 2
|
||||||
|
# main:
|
||||||
|
while p <= e:
|
||||||
|
dec(D)
|
||||||
|
var c3 = D + ord(char1 != b[char2p + s])
|
||||||
|
inc(char2p)
|
||||||
|
inc(x)
|
||||||
|
if x > c3: x = c3
|
||||||
|
D = row[p] + 1
|
||||||
|
if x > D: x = D
|
||||||
|
row[p] = x
|
||||||
|
inc(p)
|
||||||
|
# lower triangle sentinel:
|
||||||
|
if i <= half:
|
||||||
|
dec(D)
|
||||||
|
var c3 = D + ord(char1 != b[char2p + s])
|
||||||
|
inc(x)
|
||||||
|
if x > c3: x = c3
|
||||||
|
row[p] = x
|
||||||
|
result = row[e]
|
||||||
|
#dealloc(row)
|
||||||
|
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
proc fputs(c: cstring, f: TFile) {.importc: "fputs", noDecl.}
|
proc fputs(c: cstring, f: TFile) {.importc: "fputs", noDecl.}
|
||||||
proc fgets(c: cstring, n: int, f: TFile): cstring {.importc: "fgets", noDecl.}
|
proc fgets(c: cstring, n: int, f: TFile): cstring {.importc: "fgets", noDecl.}
|
||||||
proc fgetc(stream: TFile): int {.importc: "fgetc", nodecl.}
|
proc fgetc(stream: TFile): int {.importc: "fgetc", nodecl.}
|
||||||
proc ungetc(c: int, f: TFile) {.importc: "ungetc", nodecl.}
|
proc ungetc(c: cint, f: TFile) {.importc: "ungetc", nodecl.}
|
||||||
proc putc(c: Char, stream: TFile) {.importc: "putc", nodecl.}
|
proc putc(c: Char, stream: TFile) {.importc: "putc", nodecl.}
|
||||||
proc fprintf(f: TFile, frmt: CString) {.importc: "fprintf", nodecl, varargs.}
|
proc fprintf(f: TFile, frmt: CString) {.importc: "fprintf", nodecl, varargs.}
|
||||||
proc strlen(c: cstring): int {.importc: "strlen", nodecl.}
|
proc strlen(c: cstring): int {.importc: "strlen", nodecl.}
|
||||||
|
|
@ -33,7 +33,7 @@ var
|
||||||
IOFBF {.importc: "_IOFBF", nodecl.}: cint
|
IOFBF {.importc: "_IOFBF", nodecl.}: cint
|
||||||
IONBF {.importc: "_IONBF", nodecl.}: cint
|
IONBF {.importc: "_IONBF", nodecl.}: cint
|
||||||
|
|
||||||
proc rawReadLine(f: TFile, result: var string) {.noStatic.} =
|
proc rawReadLine(f: TFile, result: var string) =
|
||||||
# of course this could be optimized a bit; but IO is slow anyway...
|
# of course this could be optimized a bit; but IO is slow anyway...
|
||||||
# and it was difficult to get this CORRECT with Ansi C's methods
|
# and it was difficult to get this CORRECT with Ansi C's methods
|
||||||
var
|
var
|
||||||
|
|
@ -41,13 +41,11 @@ proc rawReadLine(f: TFile, result: var string) {.noStatic.} =
|
||||||
setLen(result, 0) # reuse the buffer!
|
setLen(result, 0) # reuse the buffer!
|
||||||
while True:
|
while True:
|
||||||
c = fgetc(f)
|
c = fgetc(f)
|
||||||
if c < 0:
|
if c < 0'i32: break # EOF
|
||||||
result = nil
|
if c == 10'i32: break # LF
|
||||||
break # EOF
|
if c == 13'i32: # CR
|
||||||
if c == 10: break # LF
|
|
||||||
if c == 13: # CR
|
|
||||||
c = fgetc(f) # is the next char LF?
|
c = fgetc(f) # is the next char LF?
|
||||||
if c != 10: ungetc(c, f) # no, put the character back
|
if c != 10'i32: ungetc(c, f) # no, put the character back
|
||||||
break
|
break
|
||||||
add result, chr(int(c))
|
add result, chr(int(c))
|
||||||
|
|
||||||
|
|
@ -117,11 +115,18 @@ proc OpenFile(f: var TFile, filename: string,
|
||||||
result = (p != nil)
|
result = (p != nil)
|
||||||
f = cast[TFile](p)
|
f = cast[TFile](p)
|
||||||
if bufSize > 0:
|
if bufSize > 0:
|
||||||
if setvbuf(f, nil, IOFBF, bufSize) != 0:
|
if setvbuf(f, nil, IOFBF, bufSize) != 0'i32:
|
||||||
raise newException(EOutOfMemory, "out of memory")
|
raise newException(EOutOfMemory, "out of memory")
|
||||||
elif bufSize == 0:
|
elif bufSize == 0:
|
||||||
discard setvbuf(f, nil, IONBF, 0)
|
discard setvbuf(f, nil, IONBF, 0)
|
||||||
|
|
||||||
|
proc fdopen(filehandle: TFileHandle, mode: cstring): TFile {.
|
||||||
|
importc: pccHack & "fdopen", header: "<stdio.h>".}
|
||||||
|
|
||||||
|
proc openFile(f: var TFile, filehandle: TFileHandle, mode: TFileMode): bool =
|
||||||
|
f = fdopen(filehandle, FormatOpen[mode])
|
||||||
|
result = f != nil
|
||||||
|
|
||||||
# C routine that is used here:
|
# C routine that is used here:
|
||||||
proc fread(buf: Pointer, size, n: int, f: TFile): int {.
|
proc fread(buf: Pointer, size, n: int, f: TFile): int {.
|
||||||
importc: "fread", noDecl.}
|
importc: "fread", noDecl.}
|
||||||
|
|
|
||||||
121
lib/sysstr.nim
121
lib/sysstr.nim
|
|
@ -16,53 +16,55 @@
|
||||||
# the programmer may not want
|
# the programmer may not want
|
||||||
|
|
||||||
type
|
type
|
||||||
TStringDesc {.importc, nodecl, final.} = object
|
# len and space without counting the terminating zero:
|
||||||
len, space: int # len and space without counting the terminating zero
|
NimStringDesc {.compilerproc, final.} = object of TGenericSeq
|
||||||
data: array[0..0, char] # for the '\0' character
|
data: array[0..100_000_000, char] # for the '\0' character
|
||||||
|
|
||||||
mstring {.importc: "string".} = ptr TStringDesc
|
NimString = ptr NimStringDesc
|
||||||
|
|
||||||
# implementation:
|
# implementation:
|
||||||
|
|
||||||
proc resize(old: int): int {.inline.} =
|
proc resize(old: int): int {.inline.} =
|
||||||
if old <= 0: return 1
|
if old <= 0: return 4
|
||||||
elif old < 65536: return old * 2
|
elif old < 65536: return old * 2
|
||||||
else: return old * 3 div 2 # for large arrays * 3/2 is better
|
else: return old * 3 div 2 # for large arrays * 3/2 is better
|
||||||
|
|
||||||
proc cmpStrings(a, b: mstring): int {.inline, compilerProc.} =
|
proc cmpStrings(a, b: NimString): int {.inline, compilerProc.} =
|
||||||
if a == b: return 0
|
if a == b: return 0
|
||||||
if a == nil: return -1
|
if a == nil: return -1
|
||||||
if b == nil: return 1
|
if b == nil: return 1
|
||||||
return c_strcmp(a.data, b.data)
|
return c_strcmp(a.data, b.data)
|
||||||
|
|
||||||
proc eqStrings(a, b: mstring): bool {.inline, compilerProc.} =
|
proc eqStrings(a, b: NimString): bool {.inline, compilerProc.} =
|
||||||
if a == b: return true
|
if a == b: return true
|
||||||
if a == nil or b == nil: return false
|
if a == nil or b == nil: return false
|
||||||
return a.len == b.len and
|
return a.len == b.len and
|
||||||
c_memcmp(a.data, b.data, a.len * sizeof(char)) == 0
|
c_memcmp(a.data, b.data, a.len * sizeof(char)) == 0'i32
|
||||||
|
|
||||||
proc rawNewString(space: int): mstring {.compilerProc.} =
|
proc rawNewString(space: int): NimString {.compilerProc.} =
|
||||||
result = cast[mstring](newObj(addr(strDesc), sizeof(TStringDesc) +
|
var s = space
|
||||||
space * sizeof(char)))
|
if s < 8: s = 7
|
||||||
result.len = 0
|
result = cast[NimString](newObj(addr(strDesc), sizeof(TGenericSeq) +
|
||||||
result.space = space
|
(s+1) * sizeof(char)))
|
||||||
result.data[0] = '\0'
|
#result.len = 0
|
||||||
|
result.space = s
|
||||||
|
#result.data[0] = '\0'
|
||||||
|
|
||||||
proc mnewString(len: int): mstring {.exportc.} =
|
proc mnewString(len: int): NimString {.exportc.} =
|
||||||
result = rawNewString(len)
|
result = rawNewString(len)
|
||||||
result.len = len
|
result.len = len
|
||||||
result.data[len] = '\0'
|
#result.data[len] = '\0'
|
||||||
|
|
||||||
proc toNimStr(str: CString, len: int): mstring {.compilerProc.} =
|
proc toNimStr(str: CString, len: int): NimString {.compilerProc.} =
|
||||||
result = rawNewString(len)
|
result = rawNewString(len)
|
||||||
result.len = len
|
result.len = len
|
||||||
c_memcpy(result.data, str, (len+1) * sizeof(Char))
|
c_memcpy(result.data, str, (len+1) * sizeof(Char))
|
||||||
result.data[len] = '\0' # IO.readline relies on this!
|
result.data[len] = '\0' # IO.readline relies on this!
|
||||||
|
|
||||||
proc cstrToNimstr(str: CString): mstring {.compilerProc.} =
|
proc cstrToNimstr(str: CString): NimString {.compilerProc.} =
|
||||||
return toNimstr(str, c_strlen(str))
|
return toNimstr(str, c_strlen(str))
|
||||||
|
|
||||||
proc copyString(src: mstring): mstring {.compilerProc.} =
|
proc copyString(src: NimString): NimString {.compilerProc.} =
|
||||||
if src == nil: return nil
|
if src == nil: return nil
|
||||||
result = rawNewString(src.space)
|
result = rawNewString(src.space)
|
||||||
result.len = src.len
|
result.len = src.len
|
||||||
|
|
@ -71,9 +73,7 @@ proc copyString(src: mstring): mstring {.compilerProc.} =
|
||||||
proc hashString(s: string): int {.compilerproc.} =
|
proc hashString(s: string): int {.compilerproc.} =
|
||||||
# the compiler needs exactly the same hash function!
|
# the compiler needs exactly the same hash function!
|
||||||
# this used to be used for efficient generation of string case statements
|
# this used to be used for efficient generation of string case statements
|
||||||
var
|
var h = 0
|
||||||
h: int
|
|
||||||
h = 0
|
|
||||||
for i in 0..Len(s)-1:
|
for i in 0..Len(s)-1:
|
||||||
h = h +% Ord(s[i])
|
h = h +% Ord(s[i])
|
||||||
h = h +% h shl 10
|
h = h +% h shl 10
|
||||||
|
|
@ -91,8 +91,7 @@ proc hashString(s: string): int {.compilerproc.} =
|
||||||
# setLength(var s: string, newlen: int)
|
# setLength(var s: string, newlen: int)
|
||||||
# {.extern: "setLengthStr", noDecl, noSideEffect.}
|
# {.extern: "setLengthStr", noDecl, noSideEffect.}
|
||||||
|
|
||||||
|
proc copyStrLast(s: NimString, start, last: int): NimString {.exportc.} =
|
||||||
proc copyStrLast(s: mstring, start, last: int): mstring {.exportc.} =
|
|
||||||
var
|
var
|
||||||
len: int
|
len: int
|
||||||
if start >= s.len: return mnewString(0) # BUGFIX
|
if start >= s.len: return mnewString(0) # BUGFIX
|
||||||
|
|
@ -105,15 +104,19 @@ proc copyStrLast(s: mstring, start, last: int): mstring {.exportc.} =
|
||||||
c_memcpy(result.data, addr(s.data[start]), len * sizeof(Char))
|
c_memcpy(result.data, addr(s.data[start]), len * sizeof(Char))
|
||||||
result.data[len] = '\0'
|
result.data[len] = '\0'
|
||||||
|
|
||||||
proc copyStr(s: mstring, start: int): mstring {.exportc.} =
|
proc copyStr(s: NimString, start: int): NimString {.exportc.} =
|
||||||
return copyStrLast(s, start, s.len-1)
|
return copyStrLast(s, start, s.len-1)
|
||||||
|
|
||||||
proc addChar(s: mstring, c: char): mstring {.compilerProc.} =
|
proc addChar(s: NimString, c: char): NimString {.compilerProc.} =
|
||||||
result = s
|
result = s
|
||||||
if result.len >= result.space:
|
if result.len >= result.space:
|
||||||
result.space = resize(result.space)
|
result.space = resize(result.space)
|
||||||
result = cast[mstring](growObj(result,
|
result = cast[NimString](growObj(result,
|
||||||
sizeof(TStringDesc) + result.space * sizeof(char)))
|
sizeof(TGenericSeq) + (result.space+1) * sizeof(char)))
|
||||||
|
#var space = resize(result.space)
|
||||||
|
#result = rawNewString(space)
|
||||||
|
#copyMem(result, s, s.len * sizeof(char) + sizeof(TGenericSeq))
|
||||||
|
#result.space = space
|
||||||
result.data[result.len] = c
|
result.data[result.len] = c
|
||||||
result.data[result.len+1] = '\0'
|
result.data[result.len+1] = '\0'
|
||||||
inc(result.len)
|
inc(result.len)
|
||||||
|
|
@ -149,27 +152,28 @@ proc addChar(s: mstring, c: char): mstring {.compilerProc.} =
|
||||||
# <generated C code>
|
# <generated C code>
|
||||||
# s = rawNewString(0);
|
# s = rawNewString(0);
|
||||||
|
|
||||||
proc resizeString(dest: mstring, addlen: int): mstring {.compilerproc.} =
|
proc resizeString(dest: NimString, addlen: int): NimString {.compilerproc.} =
|
||||||
if dest.len + addLen + 1 <= dest.space: # BUGFIX: this is horrible!
|
if dest.len + addLen + 1 <= dest.space: # BUGFIX: this is horrible!
|
||||||
result = dest
|
result = dest
|
||||||
else: # slow path:
|
else: # slow path:
|
||||||
var
|
var sp = max(resize(dest.space), dest.len + addLen + 1)
|
||||||
sp = max(resize(dest.space), dest.len + addLen + 1)
|
result = cast[NimString](growObj(dest, sizeof(TGenericSeq) +
|
||||||
result = cast[mstring](growObj(dest, sizeof(TStringDesc) +
|
(sp+1) * sizeof(Char)))
|
||||||
sp * sizeof(Char)))
|
|
||||||
# DO NOT UPDATE LEN YET: dest.len = newLen
|
|
||||||
result.space = sp
|
result.space = sp
|
||||||
|
#result = rawNewString(sp)
|
||||||
|
#copyMem(result, dest, dest.len * sizeof(char) + sizeof(TGenericSeq))
|
||||||
|
# DO NOT UPDATE LEN YET: dest.len = newLen
|
||||||
|
|
||||||
proc appendString(dest, src: mstring) {.compilerproc, inline.} =
|
proc appendString(dest, src: NimString) {.compilerproc, inline.} =
|
||||||
c_memcpy(addr(dest.data[dest.len]), src.data, (src.len + 1) * sizeof(Char))
|
c_memcpy(addr(dest.data[dest.len]), src.data, (src.len + 1) * sizeof(Char))
|
||||||
inc(dest.len, src.len)
|
inc(dest.len, src.len)
|
||||||
|
|
||||||
proc appendChar(dest: mstring, c: char) {.compilerproc, inline.} =
|
proc appendChar(dest: NimString, c: char) {.compilerproc, inline.} =
|
||||||
dest.data[dest.len] = c
|
dest.data[dest.len] = c
|
||||||
dest.data[dest.len+1] = '\0'
|
dest.data[dest.len+1] = '\0'
|
||||||
inc(dest.len)
|
inc(dest.len)
|
||||||
|
|
||||||
proc setLengthStr(s: mstring, newLen: int): mstring {.compilerProc.} =
|
proc setLengthStr(s: NimString, newLen: int): NimString {.compilerProc.} =
|
||||||
var n = max(newLen, 0)
|
var n = max(newLen, 0)
|
||||||
if n <= s.space:
|
if n <= s.space:
|
||||||
result = s
|
result = s
|
||||||
|
|
@ -187,36 +191,53 @@ proc incrSeq(seq: PGenericSeq, elemSize: int): PGenericSeq {.compilerProc.} =
|
||||||
# add seq x generates:
|
# add seq x generates:
|
||||||
# seq = incrSeq(seq, sizeof(x));
|
# seq = incrSeq(seq, sizeof(x));
|
||||||
# seq[seq->len-1] = x;
|
# seq[seq->len-1] = x;
|
||||||
|
when false:
|
||||||
|
# broken version:
|
||||||
|
result = seq
|
||||||
|
if result.len >= result.space:
|
||||||
|
var s = resize(result.space)
|
||||||
|
result = cast[PGenericSeq](newSeq(extGetCellType(seq), s))
|
||||||
|
genericSeqAssign(result, seq, XXX)
|
||||||
|
#copyMem(result, seq, seq.len * elemSize + GenericSeqSize)
|
||||||
|
inc(result.len)
|
||||||
|
else:
|
||||||
result = seq
|
result = seq
|
||||||
if result.len >= result.space:
|
if result.len >= result.space:
|
||||||
var
|
|
||||||
s: TAddress
|
|
||||||
result.space = resize(result.space)
|
result.space = resize(result.space)
|
||||||
result = cast[PGenericSeq](growObj(result, elemSize * result.space +
|
result = cast[PGenericSeq](growObj(result, elemSize * result.space +
|
||||||
GenericSeqSize))
|
GenericSeqSize))
|
||||||
# set new elements to zero:
|
# set new elements to zero:
|
||||||
s = cast[TAddress](result)
|
#var s = cast[TAddress](result)
|
||||||
zeroMem(cast[pointer](s + GenericSeqSize + (result.len * elemSize)),
|
#zeroMem(cast[pointer](s + GenericSeqSize + (result.len * elemSize)),
|
||||||
(result.space - result.len) * elemSize)
|
# (result.space - result.len) * elemSize)
|
||||||
# for i in len .. space-1:
|
# for i in len .. space-1:
|
||||||
# seq->data[i] = 0
|
# seq->data[i] = 0
|
||||||
inc(result.len)
|
inc(result.len)
|
||||||
|
|
||||||
proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
|
proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
|
||||||
compilerProc.} =
|
compilerProc.} =
|
||||||
|
when false:
|
||||||
|
# broken version:
|
||||||
|
result = seq
|
||||||
|
if result.space < newLen:
|
||||||
|
var s = max(resize(result.space), newLen)
|
||||||
|
result = cast[PGenericSeq](newSeq(extGetCellType(seq), s))
|
||||||
|
result.len = newLen
|
||||||
|
else:
|
||||||
result = seq
|
result = seq
|
||||||
if result.space < newLen:
|
if result.space < newLen:
|
||||||
var
|
|
||||||
s: TAddress
|
|
||||||
result.space = max(resize(result.space), newLen)
|
result.space = max(resize(result.space), newLen)
|
||||||
result = cast[PGenericSeq](growObj(result, elemSize * result.space +
|
result = cast[PGenericSeq](growObj(result, elemSize * result.space +
|
||||||
GenericSeqSize))
|
GenericSeqSize))
|
||||||
# set new elements to zero (needed for GC):
|
elif newLen < result.len:
|
||||||
s = cast[TAddress](result)
|
# we need to decref here, otherwise the GC leaks!
|
||||||
zeroMem(cast[pointer](s + GenericSeqSize + (result.len * elemSize)),
|
for i in newLen..result.len-1:
|
||||||
(result.space - result.len) * elemSize)
|
forAllChildrenAux(cast[pointer](cast[TAddress](result) +%
|
||||||
# Else: We could decref references, if we had type information here :-(
|
GenericSeqSize +% (i*%elemSize)),
|
||||||
# However, this does not happen often
|
extGetCellType(result).base, waZctDecRef)
|
||||||
|
# and set the memory to nil:
|
||||||
|
zeroMem(cast[pointer](cast[TAddress](result) +% GenericSeqSize +%
|
||||||
|
(newLen*%elemSize)), (result.len-%newLen) *% elemSize)
|
||||||
result.len = newLen
|
result.len = newLen
|
||||||
|
|
||||||
# --------------- other string routines ----------------------------------
|
# --------------- other string routines ----------------------------------
|
||||||
|
|
|
||||||
589
lib/system.nim
589
lib/system.nim
|
|
@ -19,6 +19,30 @@
|
||||||
|
|
||||||
{.push hints: off.}
|
{.push hints: off.}
|
||||||
|
|
||||||
|
type
|
||||||
|
int* {.magic: Int.} ## default integer type; bitwidth depends on
|
||||||
|
## architecture, but is always the same as a pointer
|
||||||
|
int8* {.magic: Int8.} ## signed 8 bit integer type
|
||||||
|
int16* {.magic: Int16.} ## signed 16 bit integer type
|
||||||
|
int32* {.magic: Int32.} ## signed 32 bit integer type
|
||||||
|
int64* {.magic: Int64.} ## signed 64 bit integer type
|
||||||
|
float* {.magic: Float.} ## default floating point type
|
||||||
|
float32* {.magic: Float32.} ## 32 bit floating point type
|
||||||
|
float64* {.magic: Float64.} ## 64 bit floating point type
|
||||||
|
type # we need to start a new type section here, so that ``0`` can have a type
|
||||||
|
bool* {.magic: Bool.} = enum ## built-in boolean type
|
||||||
|
false = 0, true = 1
|
||||||
|
|
||||||
|
type
|
||||||
|
char* {.magic: Char.} ## built-in 8 bit character type (unsigned)
|
||||||
|
string* {.magic: String.} ## built-in string type
|
||||||
|
cstring* {.magic: Cstring.} ## built-in cstring (*compatible string*) type
|
||||||
|
pointer* {.magic: Pointer.} ## built-in pointer type
|
||||||
|
TAnyEnum {.magic: AnyEnum.}
|
||||||
|
|
||||||
|
type
|
||||||
|
`nil` {.magic: "Nil".}
|
||||||
|
|
||||||
proc defined*[T] (x: T): bool {.magic: "Defined", noSideEffect.}
|
proc defined*[T] (x: T): bool {.magic: "Defined", noSideEffect.}
|
||||||
## Special comile-time procedure that checks whether `x` is
|
## Special comile-time procedure that checks whether `x` is
|
||||||
## defined. `x` has to be an identifier or a qualified identifier.
|
## defined. `x` has to be an identifier or a qualified identifier.
|
||||||
|
|
@ -30,23 +54,6 @@ proc defined*[T] (x: T): bool {.magic: "Defined", noSideEffect.}
|
||||||
## # provide our own toUpper proc here, because strutils is
|
## # provide our own toUpper proc here, because strutils is
|
||||||
## # missing it.
|
## # missing it.
|
||||||
|
|
||||||
when defined(macosX):
|
|
||||||
{.define: useDL.}
|
|
||||||
|
|
||||||
when defined(linux):
|
|
||||||
{.define: useDL.}
|
|
||||||
|
|
||||||
when defined(unix):
|
|
||||||
# This may seem strange, but we cannot write "when not defined"
|
|
||||||
# here, because ``not`` has not been defined yet.
|
|
||||||
{.hint: "unix is defined".}
|
|
||||||
else:
|
|
||||||
{.define: useDL.}
|
|
||||||
{.hint: "unix is not defined".}
|
|
||||||
# use Doug Lea's memory allocator; you can undefine it if you
|
|
||||||
# know that your system uses this library anyway (smaller code) or if
|
|
||||||
# your malloc() doesn't suck (most systems use it anyway)
|
|
||||||
|
|
||||||
# these require compiler magic:
|
# these require compiler magic:
|
||||||
proc `not` *(x: bool): bool {.magic: "Not", noSideEffect.}
|
proc `not` *(x: bool): bool {.magic: "Not", noSideEffect.}
|
||||||
## Boolean not; returns true iff ``x == false``.
|
## Boolean not; returns true iff ``x == false``.
|
||||||
|
|
@ -98,7 +105,8 @@ type
|
||||||
## is an int type ranging from one to the maximum value
|
## is an int type ranging from one to the maximum value
|
||||||
## of an int. This type is often useful for documentation and debugging.
|
## of an int. This type is often useful for documentation and debugging.
|
||||||
|
|
||||||
TObject* = object ## the root of Nimrod's object hierarchy. Objects should
|
TObject* {.exportc: "TNimObject".} =
|
||||||
|
object ## the root of Nimrod's object hierarchy. Objects should
|
||||||
## inherit from TObject or one of its descendants. However,
|
## inherit from TObject or one of its descendants. However,
|
||||||
## objects that have no ancestor are allowed.
|
## objects that have no ancestor are allowed.
|
||||||
PObject* = ref TObject ## reference to TObject
|
PObject* = ref TObject ## reference to TObject
|
||||||
|
|
@ -206,8 +214,14 @@ proc dec*[T](x: var T, y = 1) {.magic: "Dec".}
|
||||||
## exist, ``EOutOfRange`` is raised or a compile time error occurs. This is a
|
## exist, ``EOutOfRange`` is raised or a compile time error occurs. This is a
|
||||||
## short notation for: ``x = pred(x, y)``.
|
## short notation for: ``x = pred(x, y)``.
|
||||||
|
|
||||||
|
proc newSeq*[T](s: var seq[T], len: int) {.magic: "NewSeq".}
|
||||||
|
## creates a new sequence of type ``seq[T]`` with length ``len``.
|
||||||
|
## This is equivalent to ``s = []; setlen(s, len)``, but more
|
||||||
|
## efficient since no relocation is needed.
|
||||||
|
|
||||||
proc len*[T](x: openarray[T]): int {.magic: "LengthOpenArray", noSideEffect.}
|
proc len*[T](x: openarray[T]): int {.magic: "LengthOpenArray", noSideEffect.}
|
||||||
proc len*(x: string): int {.magic: "LengthStr", noSideEffect.}
|
proc len*(x: string): int {.magic: "LengthStr", noSideEffect.}
|
||||||
|
proc len*(x: cstring): int {.magic: "LengthStr", noSideEffect.}
|
||||||
proc len*[I, T](x: array[I, T]): int {.magic: "LengthArray", noSideEffect.}
|
proc len*[I, T](x: array[I, T]): int {.magic: "LengthArray", noSideEffect.}
|
||||||
proc len*[T](x: seq[T]): int {.magic: "LengthSeq", noSideEffect.}
|
proc len*[T](x: seq[T]): int {.magic: "LengthSeq", noSideEffect.}
|
||||||
## returns the length of an array, a sequence or a string.
|
## returns the length of an array, a sequence or a string.
|
||||||
|
|
@ -236,79 +250,241 @@ proc chr*(u: range[0..255]): char {.magic: "Chr", noSideEffect.}
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
# built-in operators
|
# built-in operators
|
||||||
|
|
||||||
|
proc ze*(x: int8): int {.magic: "Ze8ToI", noSideEffect.}
|
||||||
|
## zero extends a smaller integer type to ``int``. This treats `x` as
|
||||||
|
## unsigned.
|
||||||
|
proc ze*(x: int16): int {.magic: "Ze16ToI", noSideEffect.}
|
||||||
|
## zero extends a smaller integer type to ``int``. This treats `x` as
|
||||||
|
## unsigned.
|
||||||
|
|
||||||
|
proc ze64*(x: int8): int64 {.magic: "Ze8ToI64", noSideEffect.}
|
||||||
|
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
||||||
|
## unsigned.
|
||||||
|
proc ze64*(x: int16): int64 {.magic: "Ze16ToI64", noSideEffect.}
|
||||||
|
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
||||||
|
## unsigned.
|
||||||
|
|
||||||
|
proc ze64*(x: int32): int64 {.magic: "Ze32ToI64", noSideEffect.}
|
||||||
|
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
||||||
|
## unsigned.
|
||||||
|
proc ze64*(x: int): int64 {.magic: "ZeIToI64", noDecl, noSideEffect.}
|
||||||
|
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
||||||
|
## unsigned. Does nothing if the size of an ``int`` is the same as ``int64``.
|
||||||
|
## (This is the case on 64 bit processors.)
|
||||||
|
|
||||||
|
proc toU8*(x: int): int8 {.magic: "ToU8", noSideEffect.}
|
||||||
|
## treats `x` as unsigned and converts it to a byte by taking the last 8 bits
|
||||||
|
## from `x`.
|
||||||
|
proc toU16*(x: int): int16 {.magic: "ToU16", noSideEffect.}
|
||||||
|
## treats `x` as unsigned and converts it to an ``int16`` by taking the last
|
||||||
|
## 16 bits from `x`.
|
||||||
|
proc toU32*(x: int64): int32 {.magic: "ToU32", noSideEffect.}
|
||||||
|
## treats `x` as unsigned and converts it to an ``int32`` by taking the
|
||||||
|
## last 32 bits from `x`.
|
||||||
|
|
||||||
|
|
||||||
# integer calculations:
|
# integer calculations:
|
||||||
proc `+` *(x: int): int {.magic: "UnaryPlusI", noSideEffect.}
|
proc `+` *(x: int): int {.magic: "UnaryPlusI", noSideEffect.}
|
||||||
|
proc `+` *(x: int8): int8 {.magic: "UnaryPlusI", noSideEffect.}
|
||||||
|
proc `+` *(x: int16): int16 {.magic: "UnaryPlusI", noSideEffect.}
|
||||||
|
proc `+` *(x: int32): int32 {.magic: "UnaryPlusI", noSideEffect.}
|
||||||
|
proc `+` *(x: int64): int64 {.magic: "UnaryPlusI64", noSideEffect.}
|
||||||
## Unary `+` operator for an integer. Has no effect.
|
## Unary `+` operator for an integer. Has no effect.
|
||||||
|
|
||||||
proc `-` *(x: int): int {.magic: "UnaryMinusI", noSideEffect.}
|
proc `-` *(x: int): int {.magic: "UnaryMinusI", noSideEffect.}
|
||||||
|
proc `-` *(x: int8): int8 {.magic: "UnaryMinusI", noSideEffect.}
|
||||||
|
proc `-` *(x: int16): int16 {.magic: "UnaryMinusI", noSideEffect.}
|
||||||
|
proc `-` *(x: int32): int32 {.magic: "UnaryMinusI", noSideEffect.}
|
||||||
|
proc `-` *(x: int64): int64 {.magic: "UnaryMinusI64", noSideEffect.}
|
||||||
## Unary `-` operator for an integer. Negates `x`.
|
## Unary `-` operator for an integer. Negates `x`.
|
||||||
|
|
||||||
proc `not` *(x: int): int {.magic: "BitnotI", noSideEffect.}
|
proc `not` *(x: int): int {.magic: "BitnotI", noSideEffect.}
|
||||||
|
proc `not` *(x: int8): int8 {.magic: "BitnotI", noSideEffect.}
|
||||||
|
proc `not` *(x: int16): int16 {.magic: "BitnotI", noSideEffect.}
|
||||||
|
proc `not` *(x: int32): int32 {.magic: "BitnotI", noSideEffect.}
|
||||||
|
proc `not` *(x: int64): int64 {.magic: "BitnotI64", noSideEffect.}
|
||||||
## computes the `bitwise complement` of the integer `x`.
|
## computes the `bitwise complement` of the integer `x`.
|
||||||
|
|
||||||
proc `+` *(x, y: int): int {.magic: "AddI", noSideEffect.}
|
proc `+` *(x, y: int): int {.magic: "AddI", noSideEffect.}
|
||||||
|
proc `+` *(x, y: int8): int8 {.magic: "AddI", noSideEffect.}
|
||||||
|
proc `+` *(x, y: int16): int16 {.magic: "AddI", noSideEffect.}
|
||||||
|
proc `+` *(x, y: int32): int32 {.magic: "AddI", noSideEffect.}
|
||||||
|
proc `+` *(x, y: int64): int64 {.magic: "AddI64", noSideEffect.}
|
||||||
|
## Binary `+` operator for an integer.
|
||||||
|
|
||||||
proc `-` *(x, y: int): int {.magic: "SubI", noSideEffect.}
|
proc `-` *(x, y: int): int {.magic: "SubI", noSideEffect.}
|
||||||
|
proc `-` *(x, y: int8): int8 {.magic: "SubI", noSideEffect.}
|
||||||
|
proc `-` *(x, y: int16): int16 {.magic: "SubI", noSideEffect.}
|
||||||
|
proc `-` *(x, y: int32): int32 {.magic: "SubI", noSideEffect.}
|
||||||
|
proc `-` *(x, y: int64): int64 {.magic: "SubI64", noSideEffect.}
|
||||||
|
## Binary `-` operator for an integer.
|
||||||
|
|
||||||
proc `*` *(x, y: int): int {.magic: "MulI", noSideEffect.}
|
proc `*` *(x, y: int): int {.magic: "MulI", noSideEffect.}
|
||||||
|
proc `*` *(x, y: int8): int8 {.magic: "MulI", noSideEffect.}
|
||||||
|
proc `*` *(x, y: int16): int16 {.magic: "MulI", noSideEffect.}
|
||||||
|
proc `*` *(x, y: int32): int32 {.magic: "MulI", noSideEffect.}
|
||||||
|
proc `*` *(x, y: int64): int64 {.magic: "MulI64", noSideEffect.}
|
||||||
|
## Binary `*` operator for an integer.
|
||||||
|
|
||||||
proc `div` *(x, y: int): int {.magic: "DivI", noSideEffect.}
|
proc `div` *(x, y: int): int {.magic: "DivI", noSideEffect.}
|
||||||
|
proc `div` *(x, y: int8): int8 {.magic: "DivI", noSideEffect.}
|
||||||
|
proc `div` *(x, y: int16): int16 {.magic: "DivI", noSideEffect.}
|
||||||
|
proc `div` *(x, y: int32): int32 {.magic: "DivI", noSideEffect.}
|
||||||
|
proc `div` *(x, y: int64): int64 {.magic: "DivI64", noSideEffect.}
|
||||||
## computes the integer division. This is roughly the same as
|
## computes the integer division. This is roughly the same as
|
||||||
## ``floor(x/y)``.
|
## ``floor(x/y)``.
|
||||||
|
|
||||||
proc `mod` *(x, y: int): int {.magic: "ModI", noSideEffect.}
|
proc `mod` *(x, y: int): int {.magic: "ModI", noSideEffect.}
|
||||||
|
proc `mod` *(x, y: int8): int8 {.magic: "ModI", noSideEffect.}
|
||||||
|
proc `mod` *(x, y: int16): int16 {.magic: "ModI", noSideEffect.}
|
||||||
|
proc `mod` *(x, y: int32): int32 {.magic: "ModI", noSideEffect.}
|
||||||
|
proc `mod` *(x, y: int64): int64 {.magic: "ModI64", noSideEffect.}
|
||||||
## computes the integer modulo operation. This is the same as
|
## computes the integer modulo operation. This is the same as
|
||||||
## ``x - (x div y) * y``.
|
## ``x - (x div y) * y``.
|
||||||
|
|
||||||
proc `shr` *(x, y: int): int {.magic: "ShrI", noSideEffect.}
|
proc `shr` *(x, y: int): int {.magic: "ShrI", noSideEffect.}
|
||||||
## computes the `shift right` operation of `x` and `y`.
|
proc `shr` *(x, y: int8): int8 {.magic: "ShrI", noSideEffect.}
|
||||||
proc `shl` *(x, y: int): int {.magic: "ShlI", noSideEffect.}
|
proc `shr` *(x, y: int16): int16 {.magic: "ShrI", noSideEffect.}
|
||||||
## computes the `shift left` operation of `x` and `y`.
|
proc `shr` *(x, y: int32): int32 {.magic: "ShrI", noSideEffect.}
|
||||||
proc `and` *(x, y: int): int {.magic: "BitandI", noSideEffect.}
|
|
||||||
## computes the `bitwise and` of numbers `x` and `y`.
|
|
||||||
proc `or` *(x, y: int): int {.magic: "BitorI", noSideEffect.}
|
|
||||||
## computes the `bitwise or` of numbers `x` and `y`.
|
|
||||||
proc `xor` *(x, y: int): int {.magic: "BitxorI", noSideEffect.}
|
|
||||||
## computes the `bitwise xor` of numbers `x` and `y`.
|
|
||||||
|
|
||||||
proc `==` *(x, y: int): bool {.magic: "EqI", noSideEffect.}
|
|
||||||
proc `<=` *(x, y: int): bool {.magic: "LeI", noSideEffect.}
|
|
||||||
proc `<` *(x, y: int): bool {.magic: "LtI", noSideEffect.}
|
|
||||||
proc abs*(x: int): int {.magic: "AbsI", noSideEffect.}
|
|
||||||
proc min*(x, y: int): int {.magic: "MinI", noSideEffect.}
|
|
||||||
proc max*(x, y: int): int {.magic: "MaxI", noSideEffect.}
|
|
||||||
|
|
||||||
proc `+` *(x: int64): int64 {.magic: "UnaryPlusI64", noSideEffect.}
|
|
||||||
proc `-` *(x: int64): int64 {.magic: "UnaryMinusI64", noSideEffect.}
|
|
||||||
proc `not` *(x: int64): int64 {.magic: "BitnotI64", noSideEffect.}
|
|
||||||
## computes the `bitwise complement` of the integer `x`.
|
|
||||||
|
|
||||||
proc `+` *(x, y: int64): int64 {.magic: "AddI64", noSideEffect.}
|
|
||||||
## Unary `+` operator for an integer. Has no effect.
|
|
||||||
proc `-` *(x, y: int64): int64 {.magic: "SubI64", noSideEffect.}
|
|
||||||
## Unary `-` operator for an int64. Negates `x`.
|
|
||||||
proc `*` *(x, y: int64): int64 {.magic: "MulI64", noSideEffect.}
|
|
||||||
proc `div` *(x, y: int64): int64 {.magic: "DivI64", noSideEffect.}
|
|
||||||
## computes the integer division. This is roughly the same as
|
|
||||||
## ``floor(x/y)``.
|
|
||||||
proc `mod` *(x, y: int64): int64 {.magic: "ModI64", noSideEffect.}
|
|
||||||
## computes the integer modulo operation. This is the same as
|
|
||||||
## ``x - (x div y) * y``.
|
|
||||||
proc `shr` *(x, y: int64): int64 {.magic: "ShrI64", noSideEffect.}
|
proc `shr` *(x, y: int64): int64 {.magic: "ShrI64", noSideEffect.}
|
||||||
## computes the `shift right` operation of `x` and `y`.
|
## computes the `shift right` operation of `x` and `y`.
|
||||||
|
|
||||||
|
proc `shl` *(x, y: int): int {.magic: "ShlI", noSideEffect.}
|
||||||
|
proc `shl` *(x, y: int8): int8 {.magic: "ShlI", noSideEffect.}
|
||||||
|
proc `shl` *(x, y: int16): int16 {.magic: "ShlI", noSideEffect.}
|
||||||
|
proc `shl` *(x, y: int32): int32 {.magic: "ShlI", noSideEffect.}
|
||||||
proc `shl` *(x, y: int64): int64 {.magic: "ShlI64", noSideEffect.}
|
proc `shl` *(x, y: int64): int64 {.magic: "ShlI64", noSideEffect.}
|
||||||
## computes the `shift left` operation of `x` and `y`.
|
## computes the `shift left` operation of `x` and `y`.
|
||||||
|
|
||||||
|
proc `and` *(x, y: int): int {.magic: "BitandI", noSideEffect.}
|
||||||
|
proc `and` *(x, y: int8): int8 {.magic: "BitandI", noSideEffect.}
|
||||||
|
proc `and` *(x, y: int16): int16 {.magic: "BitandI", noSideEffect.}
|
||||||
|
proc `and` *(x, y: int32): int32 {.magic: "BitandI", noSideEffect.}
|
||||||
proc `and` *(x, y: int64): int64 {.magic: "BitandI64", noSideEffect.}
|
proc `and` *(x, y: int64): int64 {.magic: "BitandI64", noSideEffect.}
|
||||||
## computes the `bitwise and` of numbers `x` and `y`.
|
## computes the `bitwise and` of numbers `x` and `y`.
|
||||||
|
|
||||||
|
proc `or` *(x, y: int): int {.magic: "BitorI", noSideEffect.}
|
||||||
|
proc `or` *(x, y: int8): int8 {.magic: "BitorI", noSideEffect.}
|
||||||
|
proc `or` *(x, y: int16): int16 {.magic: "BitorI", noSideEffect.}
|
||||||
|
proc `or` *(x, y: int32): int32 {.magic: "BitorI", noSideEffect.}
|
||||||
proc `or` *(x, y: int64): int64 {.magic: "BitorI64", noSideEffect.}
|
proc `or` *(x, y: int64): int64 {.magic: "BitorI64", noSideEffect.}
|
||||||
## computes the `bitwise or` of numbers `x` and `y`.
|
## computes the `bitwise or` of numbers `x` and `y`.
|
||||||
|
|
||||||
|
proc `xor` *(x, y: int): int {.magic: "BitxorI", noSideEffect.}
|
||||||
|
proc `xor` *(x, y: int8): int8 {.magic: "BitxorI", noSideEffect.}
|
||||||
|
proc `xor` *(x, y: int16): int16 {.magic: "BitxorI", noSideEffect.}
|
||||||
|
proc `xor` *(x, y: int32): int32 {.magic: "BitxorI", noSideEffect.}
|
||||||
proc `xor` *(x, y: int64): int64 {.magic: "BitxorI64", noSideEffect.}
|
proc `xor` *(x, y: int64): int64 {.magic: "BitxorI64", noSideEffect.}
|
||||||
## computes the `bitwise xor` of numbers `x` and `y`.
|
## computes the `bitwise xor` of numbers `x` and `y`.
|
||||||
|
|
||||||
|
proc `==` *(x, y: int): bool {.magic: "EqI", noSideEffect.}
|
||||||
|
proc `==` *(x, y: int8): bool {.magic: "EqI", noSideEffect.}
|
||||||
|
proc `==` *(x, y: int16): bool {.magic: "EqI", noSideEffect.}
|
||||||
|
proc `==` *(x, y: int32): bool {.magic: "EqI", noSideEffect.}
|
||||||
proc `==` *(x, y: int64): bool {.magic: "EqI64", noSideEffect.}
|
proc `==` *(x, y: int64): bool {.magic: "EqI64", noSideEffect.}
|
||||||
proc `<=` *(x, y: int64): bool {.magic: "LeI64", noSideEffect.}
|
## Compares two integers for equality.
|
||||||
proc `<` *(x, y: int64): bool {.magic: "LtI64", noSideEffect.}
|
|
||||||
proc abs*(x: int64): int64 {.magic: "AbsI64", noSideEffect.}
|
|
||||||
proc min*(x, y: int64): int64 {.magic: "MinI64", noSideEffect.}
|
|
||||||
proc max*(x, y: int64): int64 {.magic: "MaxI64", noSideEffect.}
|
|
||||||
|
|
||||||
# same for floating point:
|
proc `<=` *(x, y: int): bool {.magic: "LeI", noSideEffect.}
|
||||||
|
proc `<=` *(x, y: int8): bool {.magic: "LeI", noSideEffect.}
|
||||||
|
proc `<=` *(x, y: int16): bool {.magic: "LeI", noSideEffect.}
|
||||||
|
proc `<=` *(x, y: int32): bool {.magic: "LeI", noSideEffect.}
|
||||||
|
proc `<=` *(x, y: int64): bool {.magic: "LeI64", noSideEffect.}
|
||||||
|
## Returns true iff `x` is less than or equal to `y`.
|
||||||
|
|
||||||
|
proc `<` *(x, y: int): bool {.magic: "LtI", noSideEffect.}
|
||||||
|
proc `<` *(x, y: int8): bool {.magic: "LtI", noSideEffect.}
|
||||||
|
proc `<` *(x, y: int16): bool {.magic: "LtI", noSideEffect.}
|
||||||
|
proc `<` *(x, y: int32): bool {.magic: "LtI", noSideEffect.}
|
||||||
|
proc `<` *(x, y: int64): bool {.magic: "LtI64", noSideEffect.}
|
||||||
|
## Returns true iff `x` is less than `y`.
|
||||||
|
|
||||||
|
proc abs*(x: int): int {.magic: "AbsI", noSideEffect.}
|
||||||
|
proc abs*(x: int8): int8 {.magic: "AbsI", noSideEffect.}
|
||||||
|
proc abs*(x: int16): int16 {.magic: "AbsI", noSideEffect.}
|
||||||
|
proc abs*(x: int32): int32 {.magic: "AbsI", noSideEffect.}
|
||||||
|
proc abs*(x: int64): int64 {.magic: "AbsI64", noSideEffect.}
|
||||||
|
## returns the absolute value of `x`. If `x` is ``low(x)`` (that is
|
||||||
|
## -MININT for its type), an overflow exception is thrown (if overflow
|
||||||
|
## checking is turned on).
|
||||||
|
|
||||||
|
proc min*(x, y: int): int {.magic: "MinI", noSideEffect.}
|
||||||
|
proc min*(x, y: int8): int8 {.magic: "MinI", noSideEffect.}
|
||||||
|
proc min*(x, y: int16): int16 {.magic: "MinI", noSideEffect.}
|
||||||
|
proc min*(x, y: int32): int32 {.magic: "MinI", noSideEffect.}
|
||||||
|
proc min*(x, y: int64): int64 {.magic: "MinI64", noSideEffect.}
|
||||||
|
## The minimum value of two integers.
|
||||||
|
|
||||||
|
proc max*(x, y: int): int {.magic: "MaxI", noSideEffect.}
|
||||||
|
proc max*(x, y: int8): int8 {.magic: "MaxI", noSideEffect.}
|
||||||
|
proc max*(x, y: int16): int16 {.magic: "MaxI", noSideEffect.}
|
||||||
|
proc max*(x, y: int32): int32 {.magic: "MaxI", noSideEffect.}
|
||||||
|
proc max*(x, y: int64): int64 {.magic: "MaxI64", noSideEffect.}
|
||||||
|
## The maximum value of two integers.
|
||||||
|
|
||||||
|
proc `+%` *(x, y: int): int {.magic: "AddU", noSideEffect.}
|
||||||
|
proc `+%` *(x, y: int8): int8 {.magic: "AddU", noSideEffect.}
|
||||||
|
proc `+%` *(x, y: int16): int16 {.magic: "AddU", noSideEffect.}
|
||||||
|
proc `+%` *(x, y: int32): int32 {.magic: "AddU", noSideEffect.}
|
||||||
|
proc `+%` *(x, y: int64): int64 {.magic: "AddU64", noSideEffect.}
|
||||||
|
## treats `x` and `y` as unsigned and adds them. The result is truncated to
|
||||||
|
## fit into the result. This implements modulo arithmetic. No overflow
|
||||||
|
## errors are possible.
|
||||||
|
|
||||||
|
proc `-%` *(x, y: int): int {.magic: "SubU", noSideEffect.}
|
||||||
|
proc `-%` *(x, y: int8): int8 {.magic: "SubU", noSideEffect.}
|
||||||
|
proc `-%` *(x, y: int16): int16 {.magic: "SubU", noSideEffect.}
|
||||||
|
proc `-%` *(x, y: int32): int32 {.magic: "SubU", noSideEffect.}
|
||||||
|
proc `-%` *(x, y: int64): int64 {.magic: "SubU64", noSideEffect.}
|
||||||
|
## treats `x` and `y` as unsigned and subtracts them. The result is
|
||||||
|
## truncated to fit into the result. This implements modulo arithmetic.
|
||||||
|
## No overflow errors are possible.
|
||||||
|
|
||||||
|
proc `*%` *(x, y: int): int {.magic: "MulU", noSideEffect.}
|
||||||
|
proc `*%` *(x, y: int8): int8 {.magic: "MulU", noSideEffect.}
|
||||||
|
proc `*%` *(x, y: int16): int16 {.magic: "MulU", noSideEffect.}
|
||||||
|
proc `*%` *(x, y: int32): int32 {.magic: "MulU", noSideEffect.}
|
||||||
|
proc `*%` *(x, y: int64): int64 {.magic: "MulU64", noSideEffect.}
|
||||||
|
## treats `x` and `y` as unsigned and multiplies them. The result is
|
||||||
|
## truncated to fit into the result. This implements modulo arithmetic.
|
||||||
|
## No overflow errors are possible.
|
||||||
|
|
||||||
|
proc `/%` *(x, y: int): int {.magic: "DivU", noSideEffect.}
|
||||||
|
proc `/%` *(x, y: int8): int8 {.magic: "DivU", noSideEffect.}
|
||||||
|
proc `/%` *(x, y: int16): int16 {.magic: "DivU", noSideEffect.}
|
||||||
|
proc `/%` *(x, y: int32): int32 {.magic: "DivU", noSideEffect.}
|
||||||
|
proc `/%` *(x, y: int64): int64 {.magic: "DivU64", noSideEffect.}
|
||||||
|
## treats `x` and `y` as unsigned and divides them. The result is
|
||||||
|
## truncated to fit into the result. This implements modulo arithmetic.
|
||||||
|
## No overflow errors are possible.
|
||||||
|
|
||||||
|
proc `%%` *(x, y: int): int {.magic: "ModU", noSideEffect.}
|
||||||
|
proc `%%` *(x, y: int8): int8 {.magic: "ModU", noSideEffect.}
|
||||||
|
proc `%%` *(x, y: int16): int16 {.magic: "ModU", noSideEffect.}
|
||||||
|
proc `%%` *(x, y: int32): int32 {.magic: "ModU", noSideEffect.}
|
||||||
|
proc `%%` *(x, y: int64): int64 {.magic: "ModU64", noSideEffect.}
|
||||||
|
## treats `x` and `y` as unsigned and compute the modulo of `x` and `y`.
|
||||||
|
## The result is truncated to fit into the result.
|
||||||
|
## This implements modulo arithmetic.
|
||||||
|
## No overflow errors are possible.
|
||||||
|
|
||||||
|
proc `<=%` *(x, y: int): bool {.magic: "LeU", noSideEffect.}
|
||||||
|
proc `<=%` *(x, y: int8): bool {.magic: "LeU", noSideEffect.}
|
||||||
|
proc `<=%` *(x, y: int16): bool {.magic: "LeU", noSideEffect.}
|
||||||
|
proc `<=%` *(x, y: int32): bool {.magic: "LeU", noSideEffect.}
|
||||||
|
proc `<=%` *(x, y: int64): bool {.magic: "LeU64", noSideEffect.}
|
||||||
|
## treats `x` and `y` as unsigned and compares them.
|
||||||
|
## Returns true iff ``unsigned(x) <= unsigned(y)``.
|
||||||
|
|
||||||
|
proc `<%` *(x, y: int): bool {.magic: "LtU", noSideEffect.}
|
||||||
|
proc `<%` *(x, y: int8): bool {.magic: "LtU", noSideEffect.}
|
||||||
|
proc `<%` *(x, y: int16): bool {.magic: "LtU", noSideEffect.}
|
||||||
|
proc `<%` *(x, y: int32): bool {.magic: "LtU", noSideEffect.}
|
||||||
|
proc `<%` *(x, y: int64): bool {.magic: "LtU64", noSideEffect.}
|
||||||
|
## treats `x` and `y` as unsigned and compares them.
|
||||||
|
## Returns true iff ``unsigned(x) < unsigned(y)``.
|
||||||
|
|
||||||
|
|
||||||
|
# floating point operations:
|
||||||
proc `+` *(x: float): float {.magic: "UnaryPlusF64", noSideEffect.}
|
proc `+` *(x: float): float {.magic: "UnaryPlusF64", noSideEffect.}
|
||||||
proc `-` *(x: float): float {.magic: "UnaryMinusF64", noSideEffect.}
|
proc `-` *(x: float): float {.magic: "UnaryMinusF64", noSideEffect.}
|
||||||
proc `+` *(x, y: float): float {.magic: "AddF64", noSideEffect.}
|
proc `+` *(x, y: float): float {.magic: "AddF64", noSideEffect.}
|
||||||
|
|
@ -423,11 +599,21 @@ proc cmp*[T](x, y: T): int =
|
||||||
proc cmp*(x, y: string): int {.noSideEffect.}
|
proc cmp*(x, y: string): int {.noSideEffect.}
|
||||||
## Compare proc for strings. More efficient than the generic version.
|
## Compare proc for strings. More efficient than the generic version.
|
||||||
|
|
||||||
|
proc `@` * [IDX, T](a: array[IDX, T]): seq[T] {.
|
||||||
|
magic: "ArrToSeq", nosideeffect.}
|
||||||
|
## turns an array into a sequence. This most often useful for constructing
|
||||||
|
## sequences with the array constructor: ``@[1, 2, 3]`` has the type
|
||||||
|
## ``seq[int]``, while ``[1, 2, 3]`` has the type ``array[0..2, int]``.
|
||||||
|
|
||||||
# concat operator:
|
# concat operator:
|
||||||
proc `&` * (x: string, y: char): string {.magic: "ConStrStr", noSideEffect.}
|
proc `&` * (x: string, y: char): string {.
|
||||||
proc `&` * (x: char, y: char): string {.magic: "ConStrStr", noSideEffect.}
|
magic: "ConStrStr", noSideEffect, merge.}
|
||||||
proc `&` * (x, y: string): string {.magic: "ConStrStr", noSideEffect.}
|
proc `&` * (x: char, y: char): string {.
|
||||||
proc `&` * (x: char, y: string): string {.magic: "ConStrStr", noSideEffect.}
|
magic: "ConStrStr", noSideEffect, merge.}
|
||||||
|
proc `&` * (x, y: string): string {.
|
||||||
|
magic: "ConStrStr", noSideEffect, merge.}
|
||||||
|
proc `&` * (x: char, y: string): string {.
|
||||||
|
magic: "ConStrStr", noSideEffect, merge.}
|
||||||
## is the `concatenation operator`. It concatenates `x` and `y`.
|
## is the `concatenation operator`. It concatenates `x` and `y`.
|
||||||
|
|
||||||
proc add * (x: var string, y: char) {.magic: "AppendStrCh".}
|
proc add * (x: var string, y: char) {.magic: "AppendStrCh".}
|
||||||
|
|
@ -466,7 +652,7 @@ proc repr*[T](x: T): string {.magic: "Repr", noSideEffect.}
|
||||||
type
|
type
|
||||||
TAddress* = int
|
TAddress* = int
|
||||||
## is the signed integer type that should be used for converting
|
## is the signed integer type that should be used for converting
|
||||||
## pointers to integer addresses.
|
## pointers to integer addresses for readability.
|
||||||
|
|
||||||
type
|
type
|
||||||
BiggestInt* = int64
|
BiggestInt* = int64
|
||||||
|
|
@ -500,7 +686,7 @@ type # these work for most platforms:
|
||||||
## This is the same as the type ``long double`` in *C*.
|
## This is the same as the type ``long double`` in *C*.
|
||||||
## This C type is not supported by Nimrod's code generator
|
## This C type is not supported by Nimrod's code generator
|
||||||
|
|
||||||
cstringArray* {.importc: "char**", nodecl.} = array [0..50_000, cstring]
|
cstringArray* {.importc: "char**", nodecl.} = ptr array [0..50_000, cstring]
|
||||||
## This is the same as the type ``char**`` in *C*.
|
## This is the same as the type ``char**`` in *C*.
|
||||||
|
|
||||||
TEndian* = enum ## is a type describing the endianness of a processor.
|
TEndian* = enum ## is a type describing the endianness of a processor.
|
||||||
|
|
@ -512,50 +698,49 @@ type # these work for most platforms:
|
||||||
PInt32* = ptr Int32 ## an alias for ``ptr int32``
|
PInt32* = ptr Int32 ## an alias for ``ptr int32``
|
||||||
|
|
||||||
const
|
const
|
||||||
QuitSuccess* = 0
|
isMainModule* {.magic: "IsMainModule".}: bool = false
|
||||||
## is the value that should be passed to ``quit`` to indicate
|
## is true only when accessed in the main module. This works thanks to
|
||||||
## success.
|
## compiler magic. It is useful to embed testing code in a module.
|
||||||
|
|
||||||
QuitFailure* = 1
|
|
||||||
## is the value that should be passed to ``quit`` to indicate
|
|
||||||
## failure.
|
|
||||||
|
|
||||||
CompileDate* {.magic: "CompileDate"}: string = "0000-00-00"
|
CompileDate* {.magic: "CompileDate"}: string = "0000-00-00"
|
||||||
## is the date of compilation as a string of the form
|
## is the date of compilation as a string of the form
|
||||||
## ``YYYY-MM-DD``.
|
## ``YYYY-MM-DD``. This works thanks to compiler magic.
|
||||||
|
|
||||||
CompileTime* {.magic: "CompileTime"}: string = "00:00:00"
|
CompileTime* {.magic: "CompileTime"}: string = "00:00:00"
|
||||||
## is the time of compilation as a string of the form
|
## is the time of compilation as a string of the form
|
||||||
## ``HH:MM:SS``.
|
## ``HH:MM:SS``. This works thanks to compiler magic.
|
||||||
|
|
||||||
NimrodVersion* {.magic: "NimrodVersion"}: string = "0.0.0"
|
NimrodVersion* {.magic: "NimrodVersion"}: string = "0.0.0"
|
||||||
## is the version of Nimrod as a string.
|
## is the version of Nimrod as a string.
|
||||||
|
## This works thanks to compiler magic.
|
||||||
|
|
||||||
NimrodMajor* {.magic: "NimrodMajor"}: int = 0
|
NimrodMajor* {.magic: "NimrodMajor"}: int = 0
|
||||||
## is the major number of Nimrod's version.
|
## is the major number of Nimrod's version.
|
||||||
|
## This works thanks to compiler magic.
|
||||||
|
|
||||||
NimrodMinor* {.magic: "NimrodMinor"}: int = 0
|
NimrodMinor* {.magic: "NimrodMinor"}: int = 0
|
||||||
## is the minor number of Nimrod's version.
|
## is the minor number of Nimrod's version.
|
||||||
|
## This works thanks to compiler magic.
|
||||||
|
|
||||||
NimrodPatch* {.magic: "NimrodPatch"}: int = 0
|
NimrodPatch* {.magic: "NimrodPatch"}: int = 0
|
||||||
## is the patch number of Nimrod's version.
|
## is the patch number of Nimrod's version.
|
||||||
|
## This works thanks to compiler magic.
|
||||||
|
|
||||||
cpuEndian* {.magic: "CpuEndian"}: TEndian = littleEndian
|
cpuEndian* {.magic: "CpuEndian"}: TEndian = littleEndian
|
||||||
## is the endianness of the target CPU. This is a valuable information
|
## is the endianness of the target CPU. This is a valuable piece of
|
||||||
## for low-level code only.
|
## information for low-level code only. This works thanks to compiler magic.
|
||||||
|
|
||||||
|
|
||||||
proc toFloat*(i: int): float {.
|
proc toFloat*(i: int): float {.
|
||||||
magic: "ToFloat", noSideEffect, importc: "toFloat".}
|
magic: "ToFloat", noSideEffect, importc: "toFloat".}
|
||||||
## converts an integer `i` into a ``float``. If the conversion
|
## converts an integer `i` into a ``float``. If the conversion
|
||||||
## fails, `EInvalidValue` is raised. Note that on most platforms the
|
## fails, `EInvalidValue` is raised. However, on most platforms the
|
||||||
## conversion cannot fail, however.
|
## conversion cannot fail.
|
||||||
|
|
||||||
proc toBiggestFloat*(i: biggestint): biggestfloat {.
|
proc toBiggestFloat*(i: biggestint): biggestfloat {.
|
||||||
magic: "ToBiggestFloat", noSideEffect, importc: "toBiggestFloat".}
|
magic: "ToBiggestFloat", noSideEffect, importc: "toBiggestFloat".}
|
||||||
## converts an biggestint `i` into a ``biggestfloat``. If the conversion
|
## converts an biggestint `i` into a ``biggestfloat``. If the conversion
|
||||||
## fails, `EInvalidValue` is raised. Note that on most platforms the
|
## fails, `EInvalidValue` is raised. However, on most platforms the
|
||||||
## conversion cannot fail, however.
|
## conversion cannot fail.
|
||||||
|
|
||||||
proc toInt*(f: float): int {.
|
proc toInt*(f: float): int {.
|
||||||
magic: "ToInt", noSideEffect, importc: "toInt".}
|
magic: "ToInt", noSideEffect, importc: "toInt".}
|
||||||
|
|
@ -569,15 +754,6 @@ proc toBiggestInt*(f: biggestfloat): biggestint {.
|
||||||
## rounds `f` if it does not contain an integer value. If the conversion
|
## rounds `f` if it does not contain an integer value. If the conversion
|
||||||
## fails (because `f` is infinite for example), `EInvalidValue` is raised.
|
## fails (because `f` is infinite for example), `EInvalidValue` is raised.
|
||||||
|
|
||||||
proc quit*(errorcode: int = QuitSuccess) {.
|
|
||||||
magic: "Exit", importc: "exit", noDecl, noReturn.}
|
|
||||||
## stops the program immediately; before stopping the program the
|
|
||||||
## "quit procedures" are called in the opposite order they were added
|
|
||||||
## with ``addQuitProc``. ``quit`` never returns and ignores any
|
|
||||||
## exception that may have been raised by the quit procedures.
|
|
||||||
## It does *not* call the garbage collector to free all the memory,
|
|
||||||
## unless a quit procedure calls ``GC_collect``.
|
|
||||||
|
|
||||||
proc addQuitProc*(QuitProc: proc {.noconv.}) {.importc: "atexit", nodecl.}
|
proc addQuitProc*(QuitProc: proc {.noconv.}) {.importc: "atexit", nodecl.}
|
||||||
## adds/registers a quit procedure. Each call to ``addQuitProc``
|
## adds/registers a quit procedure. Each call to ``addQuitProc``
|
||||||
## registers another quit procedure. Up to 30 procedures can be
|
## registers another quit procedure. Up to 30 procedures can be
|
||||||
|
|
@ -636,33 +812,29 @@ proc equalMem*(a, b: Pointer, size: int): bool {.
|
||||||
## *unsafe*.
|
## *unsafe*.
|
||||||
|
|
||||||
const
|
const
|
||||||
mallocHeader = if defined(useDL): "dlmalloc.h" else: "<stdlib.h>"
|
mallocHeader = "<stdlib.h>"
|
||||||
|
|
||||||
proc alloc*(size: int): pointer {.
|
proc alloc*(size: int): pointer {.
|
||||||
importc: if defined(useDL): "dlmalloc" else: "malloc",
|
importc: "malloc", header: mallocHeader, noconv.}
|
||||||
header: mallocHeader, noconv.}
|
|
||||||
## allocates a new memory block with at least ``size`` bytes. The
|
## allocates a new memory block with at least ``size`` bytes. The
|
||||||
## block has to be freed with ``realloc(block, 0)`` or
|
## block has to be freed with ``realloc(block, 0)`` or
|
||||||
## ``dealloc(block)``. The block is not initialized, so reading
|
## ``dealloc(block)``. The block is not initialized, so reading
|
||||||
## from it before writing to it is undefined behaviour!
|
## from it before writing to it is undefined behaviour!
|
||||||
proc alloc0*(size: int): pointer {.
|
proc alloc0*(size: int): pointer {.
|
||||||
importc: if defined(useDL): "DL_ALLOC_0" else: "ALLOC_0",
|
importc: "ALLOC_0", header: mallocHeader, noconv.}
|
||||||
header: mallocHeader, noconv.}
|
|
||||||
## allocates a new memory block with at least ``size`` bytes. The
|
## allocates a new memory block with at least ``size`` bytes. The
|
||||||
## block has to be freed with ``realloc(block, 0)`` or
|
## block has to be freed with ``realloc(block, 0)`` or
|
||||||
## ``dealloc(block)``. The block is initialized with all bytes
|
## ``dealloc(block)``. The block is initialized with all bytes
|
||||||
## containing zero, so it is somewhat safer than ``alloc``.
|
## containing zero, so it is somewhat safer than ``alloc``.
|
||||||
proc realloc*(p: Pointer, newsize: int): pointer {.
|
proc realloc*(p: Pointer, newsize: int): pointer {.
|
||||||
importc: if defined(useDL): "dlrealloc" else: "realloc",
|
importc: "realloc", header: mallocHeader, noconv.}
|
||||||
header: mallocHeader, noconv.}
|
|
||||||
## grows or shrinks a given memory block. If p is **nil** then a new
|
## grows or shrinks a given memory block. If p is **nil** then a new
|
||||||
## memory block is returned. In either way the block has at least
|
## memory block is returned. In either way the block has at least
|
||||||
## ``newsize`` bytes. If ``newsize == 0`` and p is not **nil**
|
## ``newsize`` bytes. If ``newsize == 0`` and p is not **nil**
|
||||||
## ``realloc`` calls ``dealloc(p)``. In other cases the block has to
|
## ``realloc`` calls ``dealloc(p)``. In other cases the block has to
|
||||||
## be freed with ``dealloc``.
|
## be freed with ``dealloc``.
|
||||||
proc dealloc*(p: Pointer) {.
|
proc dealloc*(p: Pointer) {.
|
||||||
importc: if defined(useDL): "dlfree" else: "free",
|
importc: "free", header: mallocHeader, noconv.}
|
||||||
header: mallocHeader, noconv.}
|
|
||||||
## frees the memory allocated with ``alloc``, ``alloc0`` or
|
## frees the memory allocated with ``alloc``, ``alloc0`` or
|
||||||
## ``realloc``. This procedure is dangerous! If one forgets to
|
## ``realloc``. This procedure is dangerous! If one forgets to
|
||||||
## free the memory a leak occurs; if one tries to access freed
|
## free the memory a leak occurs; if one tries to access freed
|
||||||
|
|
@ -687,79 +859,6 @@ proc swap*[T](a, b: var T) {.magic: "Swap".}
|
||||||
## swaps the values `a` and `b`. This is often more efficient than
|
## swaps the values `a` and `b`. This is often more efficient than
|
||||||
## ``tmp = a; a = b; b = tmp``. Particularly useful for sorting algorithms.
|
## ``tmp = a; a = b; b = tmp``. Particularly useful for sorting algorithms.
|
||||||
|
|
||||||
proc ze*(x: int8): int {.magic: "Ze8ToI", noSideEffect.}
|
|
||||||
## zero extends a smaller integer type to ``int``. This treats `x` as
|
|
||||||
## unsigned.
|
|
||||||
proc ze*(x: int16): int {.magic: "Ze16ToI", noSideEffect.}
|
|
||||||
## zero extends a smaller integer type to ``int``. This treats `x` as
|
|
||||||
## unsigned.
|
|
||||||
|
|
||||||
proc ze64*(x: int8): int64 {.magic: "Ze8ToI64", noSideEffect.}
|
|
||||||
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
|
||||||
## unsigned.
|
|
||||||
proc ze64*(x: int16): int64 {.magic: "Ze16ToI64", noSideEffect.}
|
|
||||||
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
|
||||||
## unsigned.
|
|
||||||
|
|
||||||
proc ze64*(x: int32): int64 {.magic: "Ze32ToI64", noSideEffect.}
|
|
||||||
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
|
||||||
## unsigned.
|
|
||||||
proc ze64*(x: int): int64 {.magic: "ZeIToI64", noDecl, noSideEffect.}
|
|
||||||
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
|
||||||
## unsigned. Does nothing if the size of an ``int`` is the same as ``int64``.
|
|
||||||
## (This is the case on 64 bit processors.)
|
|
||||||
|
|
||||||
proc toU8*(x: int): int8 {.magic: "ToU8", noSideEffect.}
|
|
||||||
## treats `x` as unsigned and converts it to a byte by taking the last 8 bits
|
|
||||||
## from `x`.
|
|
||||||
proc toU16*(x: int): int16 {.magic: "ToU16", noSideEffect.}
|
|
||||||
## treats `x` as unsigned and converts it to an ``int16`` by taking the last
|
|
||||||
## 16 bits from `x`.
|
|
||||||
proc toU32*(x: int64): int32 {.magic: "ToU32", noSideEffect.}
|
|
||||||
## treats `x` as unsigned and converts it to an ``int32`` by taking the
|
|
||||||
## last 32 bits from `x`.
|
|
||||||
|
|
||||||
proc `+%` *(x, y: int): int {.magic: "AddU", noSideEffect.}
|
|
||||||
proc `+%` *(x, y: int64): int64 {.magic: "AddU64", noSideEffect.}
|
|
||||||
## treats `x` and `y` as unsigned and adds them. The result is truncated to
|
|
||||||
## fit into the result. This implements modulo arithmetic. No overflow
|
|
||||||
## errors are possible.
|
|
||||||
|
|
||||||
proc `-%` *(x, y: int): int {.magic: "SubU", noSideEffect.}
|
|
||||||
proc `-%` *(x, y: int64): int64 {.magic: "SubU64", noSideEffect.}
|
|
||||||
## treats `x` and `y` as unsigned and subtracts them. The result is
|
|
||||||
## truncated to fit into the result. This implements modulo arithmetic.
|
|
||||||
## No overflow errors are possible.
|
|
||||||
|
|
||||||
proc `*%` *(x, y: int): int {.magic: "MulU", noSideEffect.}
|
|
||||||
proc `*%` *(x, y: int64): int64 {.magic: "MulU64", noSideEffect.}
|
|
||||||
## treats `x` and `y` as unsigned and multiplies them. The result is
|
|
||||||
## truncated to fit into the result. This implements modulo arithmetic.
|
|
||||||
## No overflow errors are possible.
|
|
||||||
|
|
||||||
proc `/%` *(x, y: int): int {.magic: "DivU", noSideEffect.}
|
|
||||||
proc `/%` *(x, y: int64): int64 {.magic: "DivU64", noSideEffect.}
|
|
||||||
## treats `x` and `y` as unsigned and divides them. The result is
|
|
||||||
## truncated to fit into the result. This implements modulo arithmetic.
|
|
||||||
## No overflow errors are possible.
|
|
||||||
|
|
||||||
proc `%%` *(x, y: int): int {.magic: "ModU", noSideEffect.}
|
|
||||||
proc `%%` *(x, y: int64): int64 {.magic: "ModU64", noSideEffect.}
|
|
||||||
## treats `x` and `y` as unsigned and compute the modulo of `x` and `y`.
|
|
||||||
## The result is truncated to fit into the result.
|
|
||||||
## This implements modulo arithmetic.
|
|
||||||
## No overflow errors are possible.
|
|
||||||
|
|
||||||
proc `<=%` *(x, y: int): bool {.magic: "LeU", noSideEffect.}
|
|
||||||
proc `<=%` *(x, y: int64): bool {.magic: "LeU64", noSideEffect.}
|
|
||||||
## treats `x` and `y` as unsigned and compares them.
|
|
||||||
## Returns true iff ``unsigned(x) <= unsigned(y)``.
|
|
||||||
|
|
||||||
proc `<%` *(x, y: int): bool {.magic: "LtU", noSideEffect.}
|
|
||||||
proc `<%` *(x, y: int64): bool {.magic: "LtU64", noSideEffect.}
|
|
||||||
## treats `x` and `y` as unsigned and compares them.
|
|
||||||
## Returns true iff ``unsigned(x) < unsigned(y)``.
|
|
||||||
|
|
||||||
template `>=%` *(x, y: expr): expr = y <=% x
|
template `>=%` *(x, y: expr): expr = y <=% x
|
||||||
## treats `x` and `y` as unsigned and compares them.
|
## treats `x` and `y` as unsigned and compares them.
|
||||||
## Returns true iff ``unsigned(x) >= unsigned(y)``.
|
## Returns true iff ``unsigned(x) >= unsigned(y)``.
|
||||||
|
|
@ -803,17 +902,19 @@ proc getRefcount*[T](x: ref T): int {.importc: "getRefcount".}
|
||||||
## value is implementation-dependant.
|
## value is implementation-dependant.
|
||||||
|
|
||||||
#proc writeStackTrace() {.export: "writeStackTrace".}
|
#proc writeStackTrace() {.export: "writeStackTrace".}
|
||||||
proc getCurrentExceptionMsg*(): string {.exportc.}
|
|
||||||
|
when not defined(NimrodVM):
|
||||||
|
proc getCurrentExceptionMsg*(): string {.exportc.}
|
||||||
## retrieves the error message that was attached to the current
|
## retrieves the error message that was attached to the current
|
||||||
## exception; if there is none, "" is returned.
|
## exception; if there is none, "" is returned.
|
||||||
|
|
||||||
# new constants:
|
# new constants:
|
||||||
const
|
const
|
||||||
inf* {.magic: "Inf".} = 0.0
|
inf* {.magic: "Inf".} = 1.0 / 0.0
|
||||||
## contains the IEEE floating point value of positive infinity.
|
## contains the IEEE floating point value of positive infinity.
|
||||||
neginf* {.magic: "NegInf".} = 0.0
|
neginf* {.magic: "NegInf".} = -inf
|
||||||
## contains the IEEE floating point value of negative infinity.
|
## contains the IEEE floating point value of negative infinity.
|
||||||
nan* {.magic: "NaN".} = 0.0
|
nan* {.magic: "NaN".} = 0.0 / 0.0
|
||||||
## contains an IEEE floating point value of *Not A Number*. Note
|
## contains an IEEE floating point value of *Not A Number*. Note
|
||||||
## that you cannot compare a floating point value to this value
|
## that you cannot compare a floating point value to this value
|
||||||
## and expect a reasonable result - use the `classify` procedure
|
## and expect a reasonable result - use the `classify` procedure
|
||||||
|
|
@ -826,19 +927,15 @@ var
|
||||||
## Only code compiled with the ``debugger:on`` switch calls this hook.
|
## Only code compiled with the ``debugger:on`` switch calls this hook.
|
||||||
|
|
||||||
# GC interface:
|
# GC interface:
|
||||||
when defined(Unix) and not defined(macosX) and not defined(linux):
|
|
||||||
# BUGFIX for macosX
|
|
||||||
{.define: nativeDL.}
|
|
||||||
|
|
||||||
when defined(useDL) or defined(nativeDL):
|
proc getOccupiedMem*(): int
|
||||||
proc getOccupiedMem*(): int
|
|
||||||
## returns the number of bytes that are owned by the process and hold data.
|
## returns the number of bytes that are owned by the process and hold data.
|
||||||
|
|
||||||
proc getFreeMem*(): int
|
proc getFreeMem*(): int
|
||||||
## returns the number of bytes that are owned by the process, but do not
|
## returns the number of bytes that are owned by the process, but do not
|
||||||
## hold any meaningful data.
|
## hold any meaningful data.
|
||||||
|
|
||||||
proc getTotalMem*(): int
|
proc getTotalMem*(): int
|
||||||
## returns the number of bytes that are owned by the process.
|
## returns the number of bytes that are owned by the process.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -906,7 +1003,6 @@ iterator items*(a: cstring): char {.inline.} =
|
||||||
yield a[i]
|
yield a[i]
|
||||||
inc(i)
|
inc(i)
|
||||||
|
|
||||||
|
|
||||||
proc isNil*[T](x: seq[T]): bool {.noSideEffect, magic: "IsNil".}
|
proc isNil*[T](x: seq[T]): bool {.noSideEffect, magic: "IsNil".}
|
||||||
proc isNil*[T](x: ref T): bool {.noSideEffect, magic: "IsNil".}
|
proc isNil*[T](x: ref T): bool {.noSideEffect, magic: "IsNil".}
|
||||||
proc isNil*(x: string): bool {.noSideEffect, magic: "IsNil".}
|
proc isNil*(x: string): bool {.noSideEffect, magic: "IsNil".}
|
||||||
|
|
@ -922,23 +1018,20 @@ proc isNil*(x: cstring): bool {.noSideEffect, magic: "IsNil".}
|
||||||
# once in the system module.
|
# once in the system module.
|
||||||
|
|
||||||
proc `&` *[T](x, y: seq[T]): seq[T] {.noSideEffect.} =
|
proc `&` *[T](x, y: seq[T]): seq[T] {.noSideEffect.} =
|
||||||
result = []
|
newSeq(result, x.len + y.len)
|
||||||
setLen(result, x.len + y.len)
|
|
||||||
for i in 0..x.len-1:
|
for i in 0..x.len-1:
|
||||||
result[i] = x[i]
|
result[i] = x[i]
|
||||||
for i in 0..y.len-1:
|
for i in 0..y.len-1:
|
||||||
result[i] = y[i]
|
result[i] = y[i]
|
||||||
|
|
||||||
proc `&` *[T](x: seq[T], y: T): seq[T] {.noSideEffect.} =
|
proc `&` *[T](x: seq[T], y: T): seq[T] {.noSideEffect.} =
|
||||||
result = []
|
newSeq(result, x.len + 1)
|
||||||
setLen(x.len + 1)
|
|
||||||
for i in 0..x.len-1:
|
for i in 0..x.len-1:
|
||||||
result[i] = x[i]
|
result[i] = x[i]
|
||||||
result[x.len] = y
|
result[x.len] = y
|
||||||
|
|
||||||
proc `&` *[T](x: T, y: seq[T]): seq[T] {.noSideEffect.} =
|
proc `&` *[T](x: T, y: seq[T]): seq[T] {.noSideEffect.} =
|
||||||
result = []
|
newSeq(result, y.len + 1)
|
||||||
setLen(y.len + 1)
|
|
||||||
for i in 0..y.len-1:
|
for i in 0..y.len-1:
|
||||||
result[i] = y[i]
|
result[i] = y[i]
|
||||||
result[y.len] = x
|
result[y.len] = x
|
||||||
|
|
@ -946,14 +1039,16 @@ proc `&` *[T](x: T, y: seq[T]): seq[T] {.noSideEffect.} =
|
||||||
proc `&` *[T](x, y: T): seq[T] {.noSideEffect.} =
|
proc `&` *[T](x, y: T): seq[T] {.noSideEffect.} =
|
||||||
return [x, y]
|
return [x, y]
|
||||||
|
|
||||||
when not defined(ECMAScript): # XXX make this local procs
|
when not defined(NimrodVM):
|
||||||
|
when not defined(ECMAScript):
|
||||||
|
# XXX make this local procs
|
||||||
proc seqToPtr*[T](x: seq[T]): pointer {.inline, nosideeffect.} =
|
proc seqToPtr*[T](x: seq[T]): pointer {.inline, nosideeffect.} =
|
||||||
result = cast[pointer](x)
|
result = cast[pointer](x)
|
||||||
else:
|
else:
|
||||||
proc seqToPtr*[T](x: seq[T]): pointer {.pure, nosideeffect.} =
|
proc seqToPtr*[T](x: seq[T]): pointer {.pure, nosideeffect.} =
|
||||||
asm """return `x`"""
|
asm """return `x`"""
|
||||||
|
|
||||||
proc `==` *[T](x, y: seq[T]): bool {.noSideEffect.} =
|
proc `==` *[T](x, y: seq[T]): bool {.noSideEffect.} =
|
||||||
## Generic equals operator for sequences: relies on a equals operator for
|
## Generic equals operator for sequences: relies on a equals operator for
|
||||||
## the element type `T`.
|
## the element type `T`.
|
||||||
if seqToPtr(x) == seqToPtr(y):
|
if seqToPtr(x) == seqToPtr(y):
|
||||||
|
|
@ -965,6 +1060,15 @@ proc `==` *[T](x, y: seq[T]): bool {.noSideEffect.} =
|
||||||
if x[i] != y[i]: return false
|
if x[i] != y[i]: return false
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
|
proc find*[T, S](a: T, item: S): int {.inline.} =
|
||||||
|
## Returns the first index of `item` in `a` or -1 if not found. This requires
|
||||||
|
## appropriate `==` and `items` procs to work.
|
||||||
|
result = 0
|
||||||
|
for i in items(a):
|
||||||
|
if i == item: return
|
||||||
|
inc(result)
|
||||||
|
result = -1
|
||||||
|
|
||||||
# ----------------- FPU ------------------------------------------------------
|
# ----------------- FPU ------------------------------------------------------
|
||||||
|
|
||||||
#proc disableFPUExceptions*()
|
#proc disableFPUExceptions*()
|
||||||
|
|
@ -985,7 +1089,7 @@ proc GC_enable*()
|
||||||
|
|
||||||
proc GC_fullCollect*()
|
proc GC_fullCollect*()
|
||||||
## forces a full garbage collection pass.
|
## forces a full garbage collection pass.
|
||||||
## Ordinary code does not need to call this.
|
## Ordinary code does not need to call this (and should not).
|
||||||
|
|
||||||
type
|
type
|
||||||
TGC_Strategy* = enum ## the strategy the GC should use for the application
|
TGC_Strategy* = enum ## the strategy the GC should use for the application
|
||||||
|
|
@ -1005,12 +1109,28 @@ proc GC_disableMarkAndSweep*()
|
||||||
## does not create cycles. Thus the mark and sweep phase can be deactivated
|
## does not create cycles. Thus the mark and sweep phase can be deactivated
|
||||||
## and activated separately from the rest of the GC.
|
## and activated separately from the rest of the GC.
|
||||||
|
|
||||||
|
proc GC_getStatistics*(): string
|
||||||
|
## returns an informative string about the GC's activity. This may be useful
|
||||||
|
## for tweaking.
|
||||||
|
|
||||||
{.push checks: off, line_dir: off, debugger: off,
|
proc GC_ref*[T](x: ref T) {.magic: "GCref".}
|
||||||
assertions: on.} # obviously we cannot generate checking operations here :-)
|
proc GC_ref*[T](x: seq[T]) {.magic: "GCref".}
|
||||||
# because it would yield into an endless recursion
|
proc GC_ref*(x: string) {.magic: "GCref".}
|
||||||
# however, stack-traces are available for most parts
|
## marks the object `x` as referenced, so that it will not be freed until
|
||||||
# of the code
|
## it is unmarked via `GC_unref`. If called n-times for the same object `x`,
|
||||||
|
## n calls to `GC_unref` are needed to unmark `x`.
|
||||||
|
|
||||||
|
proc GC_unref*[T](x: ref T) {.magic: "GCunref".}
|
||||||
|
proc GC_unref*[T](x: seq[T]) {.magic: "GCunref".}
|
||||||
|
proc GC_unref*(x: string) {.magic: "GCunref".}
|
||||||
|
## see the documentation of `GC_ref`.
|
||||||
|
|
||||||
|
|
||||||
|
{.push checks: off, line_dir: off, debugger: off.}
|
||||||
|
# obviously we cannot generate checking operations here :-)
|
||||||
|
# because it would yield into an endless recursion
|
||||||
|
# however, stack-traces are available for most parts
|
||||||
|
# of the code
|
||||||
|
|
||||||
proc echo*[Ty](x: Ty) {.inline.}
|
proc echo*[Ty](x: Ty) {.inline.}
|
||||||
## equivalent to ``writeln(stdout, x); flush(stdout)``. BUT: This is
|
## equivalent to ``writeln(stdout, x); flush(stdout)``. BUT: This is
|
||||||
|
|
@ -1025,7 +1145,29 @@ template newException(exceptn, message: expr): expr =
|
||||||
e.msg = message
|
e.msg = message
|
||||||
e
|
e
|
||||||
|
|
||||||
when not defined(EcmaScript):
|
const
|
||||||
|
QuitSuccess* = 0
|
||||||
|
## is the value that should be passed to ``quit`` to indicate
|
||||||
|
## success.
|
||||||
|
|
||||||
|
QuitFailure* = 1
|
||||||
|
## is the value that should be passed to ``quit`` to indicate
|
||||||
|
## failure.
|
||||||
|
|
||||||
|
proc quit*(errorcode: int = QuitSuccess) {.
|
||||||
|
magic: "Exit", importc: "exit", noDecl, noReturn.}
|
||||||
|
## stops the program immediately; before stopping the program the
|
||||||
|
## "quit procedures" are called in the opposite order they were added
|
||||||
|
## with ``addQuitProc``. ``quit`` never returns and ignores any
|
||||||
|
## exception that may have been raised by the quit procedures.
|
||||||
|
## It does *not* call the garbage collector to free all the memory,
|
||||||
|
## unless a quit procedure calls ``GC_collect``.
|
||||||
|
|
||||||
|
when not defined(EcmaScript) and not defined(NimrodVM):
|
||||||
|
proc quit*(errormsg: string) {.noReturn.}
|
||||||
|
## a shorthand for ``echo(errormsg); quit(quitFailure)``.
|
||||||
|
|
||||||
|
when not defined(EcmaScript) and not defined(NimrodVM):
|
||||||
|
|
||||||
include hti
|
include hti
|
||||||
|
|
||||||
|
|
@ -1036,6 +1178,7 @@ when not defined(EcmaScript):
|
||||||
|
|
||||||
strDesc.size = sizeof(string)
|
strDesc.size = sizeof(string)
|
||||||
strDesc.kind = tyString
|
strDesc.kind = tyString
|
||||||
|
strDesc.flags = {ntfAcyclic}
|
||||||
initGC() # BUGFIX: need to be called here!
|
initGC() # BUGFIX: need to be called here!
|
||||||
|
|
||||||
{.push stack_trace: off.}
|
{.push stack_trace: off.}
|
||||||
|
|
@ -1043,12 +1186,12 @@ when not defined(EcmaScript):
|
||||||
include ansi_c
|
include ansi_c
|
||||||
|
|
||||||
proc cmp(x, y: string): int =
|
proc cmp(x, y: string): int =
|
||||||
return c_strcmp(x, y)
|
return int(c_strcmp(x, y))
|
||||||
|
|
||||||
|
const pccHack = if defined(pcc): "_" else: "" # Hack for PCC
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
# work-around C's sucking abstraction:
|
# work-around C's sucking abstraction:
|
||||||
# BUGFIX: stdin and stdout should be binary files!
|
# BUGFIX: stdin and stdout should be binary files!
|
||||||
const pccHack = if defined(pcc): "_" else: "" # Hack for PCC
|
|
||||||
proc setmode(handle, mode: int) {.importc: pccHack & "setmode",
|
proc setmode(handle, mode: int) {.importc: pccHack & "setmode",
|
||||||
header: "<io.h>".}
|
header: "<io.h>".}
|
||||||
proc fileno(f: C_TextFileStar): int {.importc: pccHack & "fileno",
|
proc fileno(f: C_TextFileStar): int {.importc: pccHack & "fileno",
|
||||||
|
|
@ -1082,6 +1225,9 @@ when not defined(EcmaScript):
|
||||||
fmAppend ## Open the file for writing only; append data
|
fmAppend ## Open the file for writing only; append data
|
||||||
## at the end.
|
## at the end.
|
||||||
|
|
||||||
|
TFileHandle* = cint ## type that represents an OS file handle; this is
|
||||||
|
## useful for low-level file access
|
||||||
|
|
||||||
# text file handling:
|
# text file handling:
|
||||||
var
|
var
|
||||||
stdin* {.importc: "stdin", noDecl.}: TFile ## The standard input stream.
|
stdin* {.importc: "stdin", noDecl.}: TFile ## The standard input stream.
|
||||||
|
|
@ -1106,6 +1252,12 @@ when not defined(EcmaScript):
|
||||||
## that the programmer needs to provide an appropriate error message anyway
|
## that the programmer needs to provide an appropriate error message anyway
|
||||||
## (yes, even in scripts).
|
## (yes, even in scripts).
|
||||||
|
|
||||||
|
proc OpenFile*(f: var TFile, filehandle: TFileHandle,
|
||||||
|
mode: TFileMode = fmRead): Bool
|
||||||
|
## Creates a ``TFile`` from a `filehandle` with given `mode`.
|
||||||
|
##
|
||||||
|
## Default mode is readonly. Returns true iff the file could be opened.
|
||||||
|
|
||||||
proc CloseFile*(f: TFile) {.importc: "fclose", nodecl.}
|
proc CloseFile*(f: TFile) {.importc: "fclose", nodecl.}
|
||||||
## Closes the file.
|
## Closes the file.
|
||||||
proc EndOfFile*(f: TFile): Bool
|
proc EndOfFile*(f: TFile): Bool
|
||||||
|
|
@ -1201,6 +1353,15 @@ when not defined(EcmaScript):
|
||||||
yield res
|
yield res
|
||||||
CloseFile(f)
|
CloseFile(f)
|
||||||
|
|
||||||
|
proc fileHandle*(f: TFile): TFileHandle {.importc: "fileno",
|
||||||
|
header: "<stdio.h>"}
|
||||||
|
## returns the OS file handle of the file ``f``. This is only useful for
|
||||||
|
## platform specific programming.
|
||||||
|
|
||||||
|
proc quit(errormsg: string) =
|
||||||
|
echo(errormsg)
|
||||||
|
quit(quitFailure)
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
include excpt
|
include excpt
|
||||||
|
|
@ -1211,10 +1372,10 @@ when not defined(EcmaScript):
|
||||||
|
|
||||||
# sequence type declarations here because the GC needs them too:
|
# sequence type declarations here because the GC needs them too:
|
||||||
type
|
type
|
||||||
TGenericSeq {.importc, nodecl, final.} = object
|
TGenericSeq {.compilerproc, pure.} = object
|
||||||
len, space: int
|
len, space: int
|
||||||
|
|
||||||
PGenericSeq {.importc, nodecl.} = ptr TGenericSeq
|
PGenericSeq {.exportc.} = ptr TGenericSeq
|
||||||
|
|
||||||
const
|
const
|
||||||
GenericSeqSize = (2 * sizeof(int))
|
GenericSeqSize = (2 * sizeof(int))
|
||||||
|
|
@ -1235,10 +1396,32 @@ when not defined(EcmaScript):
|
||||||
{.push stack_trace: off.}
|
{.push stack_trace: off.}
|
||||||
when defined(endb):
|
when defined(endb):
|
||||||
include debugger
|
include debugger
|
||||||
|
|
||||||
|
when defined(profiler):
|
||||||
|
include profiler
|
||||||
{.pop.} # stacktrace
|
{.pop.} # stacktrace
|
||||||
|
|
||||||
else:
|
elif defined(ecmaScript):
|
||||||
include ecmasys
|
include ecmasys
|
||||||
|
elif defined(NimrodVM):
|
||||||
|
# Stubs for the GC interface:
|
||||||
|
proc GC_disable() = nil
|
||||||
|
proc GC_enable() = nil
|
||||||
|
proc GC_fullCollect() = nil
|
||||||
|
proc GC_setStrategy(strategy: TGC_Strategy) = nil
|
||||||
|
proc GC_enableMarkAndSweep() = nil
|
||||||
|
proc GC_disableMarkAndSweep() = nil
|
||||||
|
proc GC_getStatistics(): string = return ""
|
||||||
|
|
||||||
|
proc getOccupiedMem(): int = return -1
|
||||||
|
proc getFreeMem(): int = return -1
|
||||||
|
proc getTotalMem(): int = return -1
|
||||||
|
proc echo[Ty](x: Ty) = nil
|
||||||
|
|
||||||
|
proc cmp(x, y: string): int =
|
||||||
|
if x == y: return 0
|
||||||
|
if x < y: return -1
|
||||||
|
return 1
|
||||||
|
|
||||||
include macros
|
include macros
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ type
|
||||||
TWeekDay* = enum ## represents a weekday
|
TWeekDay* = enum ## represents a weekday
|
||||||
dMon, dTue, dWed, dThu, dFri, dSat, dSun
|
dMon, dTue, dWed, dThu, dFri, dSat, dSun
|
||||||
|
|
||||||
TTime* {.importc: "time_t", final.} = object ## abstract type that
|
TTime* {.importc: "time_t", header: "<time.h>", final.} = object ## abstract type that
|
||||||
## represents a time
|
## represents a time
|
||||||
when defined(ECMAScript):
|
when defined(ECMAScript):
|
||||||
getDay: proc (): int
|
getDay: proc (): int
|
||||||
|
|
@ -96,11 +96,9 @@ proc TimeInfoToTime*(timeInfo: TTimeInfo): TTime
|
||||||
## them from the other information in the broken-down time structure.
|
## them from the other information in the broken-down time structure.
|
||||||
|
|
||||||
proc `$` *(timeInfo: TTimeInfo): string
|
proc `$` *(timeInfo: TTimeInfo): string
|
||||||
## converts a `TTimeInfo` object to a
|
## converts a `TTimeInfo` object to a string representation.
|
||||||
## string representation.
|
|
||||||
proc `$` *(time: TTime): string
|
proc `$` *(time: TTime): string
|
||||||
## converts a calendar time to a
|
## converts a calendar time to a string representation.
|
||||||
## string representation.
|
|
||||||
|
|
||||||
proc getDateStr*(): string
|
proc getDateStr*(): string
|
||||||
## gets the current date as a string of the format
|
## gets the current date as a string of the format
|
||||||
|
|
@ -111,6 +109,14 @@ proc getClockStr*(): string
|
||||||
proc `-` *(a, b: TTime): int64
|
proc `-` *(a, b: TTime): int64
|
||||||
## computes the difference of two calendar times. Result is in seconds.
|
## computes the difference of two calendar times. Result is in seconds.
|
||||||
|
|
||||||
|
proc `<` * (a, b: TTime): bool =
|
||||||
|
## returns true iff ``a < b``, that is iff a happened before b.
|
||||||
|
result = a - b < 0
|
||||||
|
|
||||||
|
proc `<=` * (a, b: TTime): bool =
|
||||||
|
## returns true iff ``a <= b``.
|
||||||
|
result = a - b <= 0
|
||||||
|
|
||||||
proc getStartMilsecs*(): int
|
proc getStartMilsecs*(): int
|
||||||
## get the miliseconds from the start of the program
|
## get the miliseconds from the start of the program
|
||||||
|
|
||||||
|
|
@ -162,7 +168,7 @@ when not defined(ECMAScript):
|
||||||
result.hour = int(tm.hour)
|
result.hour = int(tm.hour)
|
||||||
result.monthday = int(tm.monthday)
|
result.monthday = int(tm.monthday)
|
||||||
result.month = TMonth(tm.month)
|
result.month = TMonth(tm.month)
|
||||||
result.year = tm.year + 1900
|
result.year = tm.year + 1900'i32
|
||||||
result.weekday = weekDays[int(tm.weekDay)]
|
result.weekday = weekDays[int(tm.weekDay)]
|
||||||
result.yearday = int(tm.yearday)
|
result.yearday = int(tm.yearday)
|
||||||
|
|
||||||
|
|
@ -180,8 +186,7 @@ when not defined(ECMAScript):
|
||||||
result.isdst = -1
|
result.isdst = -1
|
||||||
|
|
||||||
proc `-` (a, b: TTime): int64 =
|
proc `-` (a, b: TTime): int64 =
|
||||||
return toInt(difftime(a, b)) # XXX: toBiggestInt is needed here, but
|
return toBiggestInt(difftime(a, b))
|
||||||
# Nim does not support it!
|
|
||||||
|
|
||||||
proc getStartMilsecs(): int = return clock() div (clocksPerSec div 1000)
|
proc getStartMilsecs(): int = return clock() div (clocksPerSec div 1000)
|
||||||
proc getTime(): TTime = return timec(nil)
|
proc getTime(): TTime = return timec(nil)
|
||||||
|
|
@ -202,12 +207,23 @@ when not defined(ECMAScript):
|
||||||
# because the header of mktime is broken in my version of libc
|
# because the header of mktime is broken in my version of libc
|
||||||
return mktime(timeInfoToTM(cTimeInfo))
|
return mktime(timeInfoToTM(cTimeInfo))
|
||||||
|
|
||||||
|
proc toStringTillNL(p: cstring): string =
|
||||||
|
result = ""
|
||||||
|
var i = 0
|
||||||
|
while p[i] != '\0' and p[i] != '\10' and p[i] != '\13':
|
||||||
|
add(result, p[i])
|
||||||
|
inc(i)
|
||||||
|
return result
|
||||||
|
|
||||||
proc `$`(timeInfo: TTimeInfo): string =
|
proc `$`(timeInfo: TTimeInfo): string =
|
||||||
return $asctime(timeInfoToTM(timeInfo))
|
# BUGFIX: asctime returns a newline at the end!
|
||||||
|
var p = asctime(timeInfoToTM(timeInfo))
|
||||||
|
result = toStringTillNL(p)
|
||||||
|
|
||||||
proc `$`(time: TTime): string =
|
proc `$`(time: TTime): string =
|
||||||
|
# BUGFIX: ctime returns a newline at the end!
|
||||||
var a = time
|
var a = time
|
||||||
return $ctime(addr(a))
|
return toStringTillNL(ctime(addr(a)))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
proc getTime(): TTime {.importc: "new Date", nodecl.}
|
proc getTime(): TTime {.importc: "new Date", nodecl.}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Nimrod's Runtime Library
|
# Nimrod's Runtime Library
|
||||||
# (c) Copyright 2006 Andreas Rumpf
|
# (c) Copyright 2008 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
type
|
type
|
||||||
TUniChar* = int32 ## type that can hold any Unicode character
|
TUniChar* = int32 ## type that can hold any Unicode character
|
||||||
TUniChar16* = int16 ##
|
TUniChar16* = int16 ## 16 bit Unicode character
|
||||||
|
|
||||||
template ones(n) = ((1 shl n)-1)
|
template ones(n) = ((1 shl n)-1)
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
7
makefile
7
makefile
|
|
@ -1,14 +1,13 @@
|
||||||
# Dummy makefile for people who don't read "readme" files, or automated
|
# Dummy makefile for people who don't read "readme" files, or for automated
|
||||||
# installations
|
# installations
|
||||||
# (c) 2007 Andreas Rumpf
|
|
||||||
|
|
||||||
.PHONY : all
|
.PHONY : all
|
||||||
all:
|
all:
|
||||||
python koch.py all
|
python koch.py boot -d:release
|
||||||
|
|
||||||
.PHONY : install
|
.PHONY : install
|
||||||
install:
|
install:
|
||||||
python koch.py install
|
sh install.sh /usr/bin
|
||||||
|
|
||||||
.PHONY : clean
|
.PHONY : clean
|
||||||
clean:
|
clean:
|
||||||
|
|
|
||||||
742
nim/ast.pas
742
nim/ast.pas
File diff suppressed because it is too large
Load diff
318
nim/astalgo.pas
318
nim/astalgo.pas
|
|
@ -133,7 +133,8 @@ procedure debug(n: PNode); overload;
|
||||||
|
|
||||||
// --------------------------- ident tables ----------------------------------
|
// --------------------------- ident tables ----------------------------------
|
||||||
|
|
||||||
function IdTableGet(const t: TIdTable; key: PIdObj): PObject;
|
function IdTableGet(const t: TIdTable; key: PIdObj): PObject; overload;
|
||||||
|
function IdTableGet(const t: TIdTable; key: int): PObject; overload;
|
||||||
procedure IdTablePut(var t: TIdTable; key: PIdObj; val: PObject);
|
procedure IdTablePut(var t: TIdTable; key: PIdObj; val: PObject);
|
||||||
|
|
||||||
function IdTableHasObjectAsKey(const t: TIdTable; key: PIdObj): bool;
|
function IdTableHasObjectAsKey(const t: TIdTable; key: PIdObj): bool;
|
||||||
|
|
@ -145,33 +146,6 @@ procedure IdNodeTablePut(var t: TIdNodeTable; key: PIdObj; val: PNode);
|
||||||
|
|
||||||
procedure writeIdNodeTable(const t: TIdNodeTable);
|
procedure writeIdNodeTable(const t: TIdNodeTable);
|
||||||
|
|
||||||
// ------------- efficient integer sets -------------------------------------
|
|
||||||
const
|
|
||||||
IntsPerTrunk = 8;
|
|
||||||
InitIntSetSize = 8; // must be a power of two!
|
|
||||||
BitsPerTrunk = IntsPerTrunk * sizeof(int) * 8;
|
|
||||||
BitsPerInt = sizeof(int) * 8;
|
|
||||||
|
|
||||||
type
|
|
||||||
PTrunk = ^TTrunk;
|
|
||||||
TTrunk = record
|
|
||||||
next: PTrunk; // all nodes are connected with this pointer
|
|
||||||
key: int; // start address at bit 0
|
|
||||||
bits: array [0..IntsPerTrunk-1] of int; // a bit vector
|
|
||||||
end;
|
|
||||||
TTrunkSeq = array of PTrunk;
|
|
||||||
TIntSet = record
|
|
||||||
counter, max: int;
|
|
||||||
head: PTrunk;
|
|
||||||
data: TTrunkSeq;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function IntSetContains(const s: TIntSet; key: int): bool;
|
|
||||||
procedure IntSetIncl(var s: TIntSet; key: int);
|
|
||||||
procedure IntSetInit(var s: TIntSet);
|
|
||||||
|
|
||||||
function IntSetContainsOrIncl(var s: TIntSet; key: int): bool;
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
function getSymFromList(list: PNode; ident: PIdent; start: int = 0): PSym;
|
function getSymFromList(list: PNode; ident: PIdent; start: int = 0): PSym;
|
||||||
function lookupInRecord(n: PNode; field: PIdent): PSym;
|
function lookupInRecord(n: PNode; field: PIdent): PSym;
|
||||||
|
|
@ -181,6 +155,24 @@ function getModule(s: PSym): PSym;
|
||||||
function mustRehash(len, counter: int): bool;
|
function mustRehash(len, counter: int): bool;
|
||||||
function nextTry(h, maxHash: THash): THash;
|
function nextTry(h, maxHash: THash): THash;
|
||||||
|
|
||||||
|
// ------------- table[int, int] ---------------------------------------------
|
||||||
|
const
|
||||||
|
InvalidKey = low(int);
|
||||||
|
|
||||||
|
type
|
||||||
|
TIIPair = record
|
||||||
|
key, val: int;
|
||||||
|
end;
|
||||||
|
TIIPairSeq = array of TIIPair;
|
||||||
|
TIITable = record // table[int, int]
|
||||||
|
counter: int;
|
||||||
|
data: TIIPairSeq;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure initIITable(out x: TIITable);
|
||||||
|
function IITableGet(const t: TIITable; key: int): int;
|
||||||
|
procedure IITablePut(var t: TIITable; key, val: int);
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
function lookupInRecord(n: PNode; field: PIdent): PSym;
|
function lookupInRecord(n: PNode; field: PIdent): PSym;
|
||||||
|
|
@ -281,14 +273,14 @@ begin
|
||||||
result := nil;
|
result := nil;
|
||||||
res := '"' + '';
|
res := '"' + '';
|
||||||
for i := strStart to length(s)+strStart-1 do begin
|
for i := strStart to length(s)+strStart-1 do begin
|
||||||
if i mod MaxLineLength = 0 then begin
|
if (i-strStart+1) mod MaxLineLength = 0 then begin
|
||||||
res := res +{&} '"' +{&} nl;
|
res := res +{&} '"' +{&} nl;
|
||||||
app(result, toRope(res));
|
app(result, toRope(res));
|
||||||
res := '"'+''; // reset
|
res := '"'+''; // reset
|
||||||
end;
|
end;
|
||||||
res := res +{&} toYamlChar(s[i]);
|
res := res +{&} toYamlChar(s[i]);
|
||||||
end;
|
end;
|
||||||
res := res + '"';
|
addChar(res, '"');
|
||||||
app(result, toRope(res));
|
app(result, toRope(res));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -349,16 +341,16 @@ begin
|
||||||
toRope(toLinenumber(info)), toRope(toColumn(info))]);
|
toRope(toLinenumber(info)), toRope(toColumn(info))]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function treeToYamlAux(n: PNode; var marker: TObjectSet;
|
function treeToYamlAux(n: PNode; var marker: TIntSet;
|
||||||
indent: int; maxRecDepth: int): PRope;
|
indent: int; maxRecDepth: int): PRope;
|
||||||
forward;
|
forward;
|
||||||
|
|
||||||
function symToYamlAux(n: PSym; var marker: TObjectSet;
|
function symToYamlAux(n: PSym; var marker: TIntSet;
|
||||||
indent: int; maxRecDepth: int): PRope; forward;
|
indent: int; maxRecDepth: int): PRope; forward;
|
||||||
function typeToYamlAux(n: PType; var marker: TObjectSet;
|
function typeToYamlAux(n: PType; var marker: TIntSet;
|
||||||
indent: int; maxRecDepth: int): PRope; forward;
|
indent: int; maxRecDepth: int): PRope; forward;
|
||||||
|
|
||||||
function strTableToYaml(const n: TStrTable; var marker: TObjectSet;
|
function strTableToYaml(const n: TStrTable; var marker: TIntSet;
|
||||||
indent: int; maxRecDepth: int): PRope;
|
indent: int; maxRecDepth: int): PRope;
|
||||||
var
|
var
|
||||||
istr: PRope;
|
istr: PRope;
|
||||||
|
|
@ -396,14 +388,14 @@ begin
|
||||||
appf(result, '$n$1}', [spaces(indent)]);
|
appf(result, '$n$1}', [spaces(indent)]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function symToYamlAux(n: PSym; var marker: TObjectSet;
|
function symToYamlAux(n: PSym; var marker: TIntSet;
|
||||||
indent: int; maxRecDepth: int): PRope;
|
indent: int; maxRecDepth: int): PRope;
|
||||||
var
|
var
|
||||||
ast: PRope;
|
ast: PRope;
|
||||||
begin
|
begin
|
||||||
if n = nil then
|
if n = nil then
|
||||||
result := toRope('null')
|
result := toRope('null')
|
||||||
else if ObjectSetContainsOrIncl(marker, n) then
|
else if IntSetContainsOrIncl(marker, n.id) then
|
||||||
result := ropef('"$1 @$2"', [
|
result := ropef('"$1 @$2"', [
|
||||||
toRope(n.name.s),
|
toRope(n.name.s),
|
||||||
toRope(strutils.toHex({@cast}TAddress(n), sizeof(n)*2))])
|
toRope(strutils.toHex({@cast}TAddress(n), sizeof(n)*2))])
|
||||||
|
|
@ -424,12 +416,12 @@ begin
|
||||||
// YYY: backend info?
|
// YYY: backend info?
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function typeToYamlAux(n: PType; var marker: TObjectSet;
|
function typeToYamlAux(n: PType; var marker: TIntSet;
|
||||||
indent: int; maxRecDepth: int): PRope;
|
indent: int; maxRecDepth: int): PRope;
|
||||||
begin
|
begin
|
||||||
if n = nil then
|
if n = nil then
|
||||||
result := toRope('null')
|
result := toRope('null')
|
||||||
else if objectSetContainsOrIncl(marker, n) then
|
else if intSetContainsOrIncl(marker, n.id) then
|
||||||
result := ropef('"$1 @$2"', [
|
result := ropef('"$1 @$2"', [
|
||||||
toRope(typeKindToStr[n.kind]),
|
toRope(typeKindToStr[n.kind]),
|
||||||
toRope(strutils.toHex({@cast}TAddress(n), sizeof(n)*2))])
|
toRope(strutils.toHex({@cast}TAddress(n), sizeof(n)*2))])
|
||||||
|
|
@ -446,7 +438,7 @@ begin
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function treeToYamlAux(n: PNode; var marker: TObjectSet; indent: int;
|
function treeToYamlAux(n: PNode; var marker: TIntSet; indent: int;
|
||||||
maxRecDepth: int): PRope;
|
maxRecDepth: int): PRope;
|
||||||
var
|
var
|
||||||
istr: PRope;
|
istr: PRope;
|
||||||
|
|
@ -503,25 +495,25 @@ end;
|
||||||
|
|
||||||
function treeToYaml(n: PNode; indent: int = 0; maxRecDepth: int = -1): PRope;
|
function treeToYaml(n: PNode; indent: int = 0; maxRecDepth: int = -1): PRope;
|
||||||
var
|
var
|
||||||
marker: TObjectSet;
|
marker: TIntSet;
|
||||||
begin
|
begin
|
||||||
initObjectSet(marker);
|
IntSetInit(marker);
|
||||||
result := treeToYamlAux(n, marker, indent, maxRecDepth)
|
result := treeToYamlAux(n, marker, indent, maxRecDepth)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function typeToYaml(n: PType; indent: int = 0; maxRecDepth: int = -1): PRope;
|
function typeToYaml(n: PType; indent: int = 0; maxRecDepth: int = -1): PRope;
|
||||||
var
|
var
|
||||||
marker: TObjectSet;
|
marker: TIntSet;
|
||||||
begin
|
begin
|
||||||
initObjectSet(marker);
|
IntSetInit(marker);
|
||||||
result := typeToYamlAux(n, marker, indent, maxRecDepth)
|
result := typeToYamlAux(n, marker, indent, maxRecDepth)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function symToYaml(n: PSym; indent: int = 0; maxRecDepth: int = -1): PRope;
|
function symToYaml(n: PSym; indent: int = 0; maxRecDepth: int = -1): PRope;
|
||||||
var
|
var
|
||||||
marker: TObjectSet;
|
marker: TIntSet;
|
||||||
begin
|
begin
|
||||||
initObjectSet(marker);
|
IntSetInit(marker);
|
||||||
result := symToYamlAux(n, marker, indent, maxRecDepth)
|
result := symToYamlAux(n, marker, indent, maxRecDepth)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -617,7 +609,7 @@ const
|
||||||
EmptySeq = nil;
|
EmptySeq = nil;
|
||||||
{@emit
|
{@emit
|
||||||
const
|
const
|
||||||
EmptySeq = [];
|
EmptySeq = @[];
|
||||||
}
|
}
|
||||||
|
|
||||||
function nextTry(h, maxHash: THash): THash;
|
function nextTry(h, maxHash: THash): THash;
|
||||||
|
|
@ -661,11 +653,12 @@ var
|
||||||
n: TObjectSeq;
|
n: TObjectSeq;
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
|
{@ignore}
|
||||||
n := emptySeq;
|
n := emptySeq;
|
||||||
setLength(n, length(t.data) * growthFactor);
|
setLength(n, length(t.data) * growthFactor);
|
||||||
{@ignore}
|
|
||||||
fillChar(n[0], length(n)*sizeof(n[0]), 0);
|
fillChar(n[0], length(n)*sizeof(n[0]), 0);
|
||||||
{@emit}
|
{@emit
|
||||||
|
newSeq(n, length(t.data) * growthFactor); }
|
||||||
for i := 0 to high(t.data) do
|
for i := 0 to high(t.data) do
|
||||||
if t.data[i] <> nil then objectSetRawInsert(n, t.data[i]);
|
if t.data[i] <> nil then objectSetRawInsert(n, t.data[i]);
|
||||||
{@ignore}
|
{@ignore}
|
||||||
|
|
@ -769,11 +762,12 @@ var
|
||||||
n: TPairSeq;
|
n: TPairSeq;
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
|
{@ignore}
|
||||||
n := emptySeq;
|
n := emptySeq;
|
||||||
setLength(n, length(t.data) * growthFactor);
|
setLength(n, length(t.data) * growthFactor);
|
||||||
{@ignore}
|
|
||||||
fillChar(n[0], length(n)*sizeof(n[0]), 0);
|
fillChar(n[0], length(n)*sizeof(n[0]), 0);
|
||||||
{@emit}
|
{@emit
|
||||||
|
newSeq(n, length(t.data) * growthFactor); }
|
||||||
for i := 0 to high(t.data) do
|
for i := 0 to high(t.data) do
|
||||||
if t.data[i].key <> nil then
|
if t.data[i].key <> nil then
|
||||||
TableRawInsert(n, t.data[i].key, t.data[i].val);
|
TableRawInsert(n, t.data[i].key, t.data[i].val);
|
||||||
|
|
@ -833,11 +827,12 @@ var
|
||||||
n: TSymSeq;
|
n: TSymSeq;
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
|
{@ignore}
|
||||||
n := emptySeq;
|
n := emptySeq;
|
||||||
setLength(n, length(t.data) * growthFactor);
|
setLength(n, length(t.data) * growthFactor);
|
||||||
{@ignore}
|
|
||||||
fillChar(n[0], length(n)*sizeof(n[0]), 0);
|
fillChar(n[0], length(n)*sizeof(n[0]), 0);
|
||||||
{@emit}
|
{@emit
|
||||||
|
newSeq(n, length(t.data) * growthFactor); }
|
||||||
for i := 0 to high(t.data) do
|
for i := 0 to high(t.data) do
|
||||||
if t.data[i] <> nil then StrTableRawInsert(n, t.data[i]);
|
if t.data[i] <> nil then StrTableRawInsert(n, t.data[i]);
|
||||||
{@ignore}
|
{@ignore}
|
||||||
|
|
@ -1022,13 +1017,13 @@ begin
|
||||||
result := false
|
result := false
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function IdTableRawGet(const t: TIdTable; key: PIdObj): int;
|
function IdTableRawGet(const t: TIdTable; key: int): int;
|
||||||
var
|
var
|
||||||
h: THash;
|
h: THash;
|
||||||
begin
|
begin
|
||||||
h := key.id and high(t.data); // start with real hash value
|
h := key and high(t.data); // start with real hash value
|
||||||
while t.data[h].key <> nil do begin
|
while t.data[h].key <> nil do begin
|
||||||
if (t.data[h].key.id = key.id) then begin
|
if (t.data[h].key.id = key) then begin
|
||||||
result := h; exit
|
result := h; exit
|
||||||
end;
|
end;
|
||||||
h := nextTry(h, high(t.data))
|
h := nextTry(h, high(t.data))
|
||||||
|
|
@ -1040,12 +1035,21 @@ function IdTableHasObjectAsKey(const t: TIdTable; key: PIdObj): bool;
|
||||||
var
|
var
|
||||||
index: int;
|
index: int;
|
||||||
begin
|
begin
|
||||||
index := IdTableRawGet(t, key);
|
index := IdTableRawGet(t, key.id);
|
||||||
if index >= 0 then result := t.data[index].key = key
|
if index >= 0 then result := t.data[index].key = key
|
||||||
else result := false
|
else result := false
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function IdTableGet(const t: TIdTable; key: PIdObj): PObject;
|
function IdTableGet(const t: TIdTable; key: PIdObj): PObject;
|
||||||
|
var
|
||||||
|
index: int;
|
||||||
|
begin
|
||||||
|
index := IdTableRawGet(t, key.id);
|
||||||
|
if index >= 0 then result := t.data[index].val
|
||||||
|
else result := nil
|
||||||
|
end;
|
||||||
|
|
||||||
|
function IdTableGet(const t: TIdTable; key: int): PObject;
|
||||||
var
|
var
|
||||||
index: int;
|
index: int;
|
||||||
begin
|
begin
|
||||||
|
|
@ -1074,18 +1078,18 @@ var
|
||||||
index, i: int;
|
index, i: int;
|
||||||
n: TIdPairSeq;
|
n: TIdPairSeq;
|
||||||
begin
|
begin
|
||||||
index := IdTableRawGet(t, key);
|
index := IdTableRawGet(t, key.id);
|
||||||
if index >= 0 then begin
|
if index >= 0 then begin
|
||||||
assert(t.data[index].key <> nil);
|
assert(t.data[index].key <> nil);
|
||||||
t.data[index].val := val
|
t.data[index].val := val
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
if mustRehash(length(t.data), t.counter) then begin
|
if mustRehash(length(t.data), t.counter) then begin
|
||||||
{@emit n := [];}
|
|
||||||
setLength(n, length(t.data) * growthFactor);
|
|
||||||
{@ignore}
|
{@ignore}
|
||||||
|
setLength(n, length(t.data) * growthFactor);
|
||||||
fillChar(n[0], length(n)*sizeof(n[0]), 0);
|
fillChar(n[0], length(n)*sizeof(n[0]), 0);
|
||||||
{@emit}
|
{@emit
|
||||||
|
newSeq(n, length(t.data) * growthFactor); }
|
||||||
for i := 0 to high(t.data) do
|
for i := 0 to high(t.data) do
|
||||||
if t.data[i].key <> nil then
|
if t.data[i].key <> nil then
|
||||||
IdTableRawInsert(n, t.data[i].key, t.data[i].val);
|
IdTableRawInsert(n, t.data[i].key, t.data[i].val);
|
||||||
|
|
@ -1166,11 +1170,11 @@ begin
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
if mustRehash(length(t.data), t.counter) then begin
|
if mustRehash(length(t.data), t.counter) then begin
|
||||||
{@emit n := [];}
|
|
||||||
setLength(n, length(t.data) * growthFactor);
|
|
||||||
{@ignore}
|
{@ignore}
|
||||||
|
setLength(n, length(t.data) * growthFactor);
|
||||||
fillChar(n[0], length(n)*sizeof(n[0]), 0);
|
fillChar(n[0], length(n)*sizeof(n[0]), 0);
|
||||||
{@emit}
|
{@emit
|
||||||
|
newSeq(n, length(t.data) * growthFactor); }
|
||||||
for i := 0 to high(t.data) do
|
for i := 0 to high(t.data) do
|
||||||
if t.data[i].key <> nil then
|
if t.data[i].key <> nil then
|
||||||
IdNodeTableRawInsert(n, t.data[i].key, t.data[i].val);
|
IdNodeTableRawInsert(n, t.data[i].key, t.data[i].val);
|
||||||
|
|
@ -1185,156 +1189,86 @@ begin
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// ---------------- efficient integer sets ----------------------------------
|
// ------------- int-to-int-mapping ------------------------------------------
|
||||||
// Same algorithm as the one the GC uses
|
|
||||||
|
|
||||||
procedure IntSetInit(var s: TIntSet);
|
procedure initIITable(out x: TIITable);
|
||||||
|
var
|
||||||
|
i: int;
|
||||||
begin
|
begin
|
||||||
|
x.counter := 0;
|
||||||
{@ignore}
|
{@ignore}
|
||||||
fillChar(s, sizeof(s), 0);
|
setLength(x.data, startSize);
|
||||||
{@emit
|
{@emit
|
||||||
s.data := []; }
|
newSeq(x.data, startSize); }
|
||||||
setLength(s.data, InitIntSetSize);
|
for i := 0 to startSize-1 do x.data[i].key := InvalidKey;
|
||||||
{@ignore}
|
|
||||||
fillChar(s.data[0], length(s.data)*sizeof(s.data[0]), 0);
|
|
||||||
{@emit}
|
|
||||||
s.max := InitIntSetSize-1;
|
|
||||||
s.counter := 0;
|
|
||||||
s.head := nil
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function IntSetGet(const t: TIntSet; key: int): PTrunk;
|
function IITableRawGet(const t: TIITable; key: int): int;
|
||||||
var
|
var
|
||||||
h: int;
|
h: THash;
|
||||||
begin
|
begin
|
||||||
h := key and t.max;
|
h := key and high(t.data); // start with real hash value
|
||||||
while t.data[h] <> nil do begin
|
while t.data[h].key <> InvalidKey do begin
|
||||||
if t.data[h].key = key then begin
|
if (t.data[h].key = key) then begin
|
||||||
result := t.data[h]; exit
|
result := h; exit
|
||||||
end;
|
end;
|
||||||
h := nextTry(h, t.max)
|
h := nextTry(h, high(t.data))
|
||||||
end;
|
end;
|
||||||
result := nil
|
result := -1
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure IntSetRawInsert(const t: TIntSet; var data: TTrunkSeq;
|
function IITableGet(const t: TIITable; key: int): int;
|
||||||
desc: PTrunk);
|
|
||||||
var
|
var
|
||||||
h: int;
|
index: int;
|
||||||
begin
|
begin
|
||||||
h := desc.key and t.max;
|
index := IITableRawGet(t, key);
|
||||||
while data[h] <> nil do begin
|
if index >= 0 then result := t.data[index].val
|
||||||
assert(data[h] <> desc);
|
else result := InvalidKey
|
||||||
h := nextTry(h, t.max)
|
end;
|
||||||
|
|
||||||
|
procedure IITableRawInsert(var data: TIIPairSeq;
|
||||||
|
key, val: int);
|
||||||
|
var
|
||||||
|
h: THash;
|
||||||
|
begin
|
||||||
|
h := key and high(data);
|
||||||
|
while data[h].key <> InvalidKey do begin
|
||||||
|
assert(data[h].key <> key);
|
||||||
|
h := nextTry(h, high(data))
|
||||||
end;
|
end;
|
||||||
assert(data[h] = nil);
|
assert(data[h].key = InvalidKey);
|
||||||
data[h] := desc
|
data[h].key := key;
|
||||||
|
data[h].val := val;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure IntSetEnlarge(var t: TIntSet);
|
procedure IITablePut(var t: TIITable; key, val: int);
|
||||||
var
|
var
|
||||||
n: TTrunkSeq;
|
index, i: int;
|
||||||
i, oldMax: int;
|
n: TIIPairSeq;
|
||||||
begin
|
begin
|
||||||
oldMax := t.max;
|
index := IITableRawGet(t, key);
|
||||||
t.max := ((t.max+1)*2)-1;
|
if index >= 0 then begin
|
||||||
{@emit n := []}
|
assert(t.data[index].key <> InvalidKey);
|
||||||
setLength(n, t.max + 1);
|
t.data[index].val := val
|
||||||
{@ignore}
|
|
||||||
fillChar(n[0], length(n)*sizeof(n[0]), 0);
|
|
||||||
{@emit}
|
|
||||||
for i := 0 to oldmax do
|
|
||||||
if t.data[i] <> nil then
|
|
||||||
IntSetRawInsert(t, n, t.data[i]);
|
|
||||||
{@ignore}
|
|
||||||
t.data := n;
|
|
||||||
{@emit
|
|
||||||
swap(t.data, n);
|
|
||||||
}
|
|
||||||
end;
|
|
||||||
|
|
||||||
function IntSetPut(var t: TIntSet; key: int): PTrunk;
|
|
||||||
var
|
|
||||||
h: int;
|
|
||||||
begin
|
|
||||||
h := key and t.max;
|
|
||||||
while t.data[h] <> nil do begin
|
|
||||||
if t.data[h].key = key then begin
|
|
||||||
result := t.data[h]; exit
|
|
||||||
end;
|
|
||||||
h := nextTry(h, t.max)
|
|
||||||
end;
|
|
||||||
|
|
||||||
if mustRehash(t.max+1, t.counter) then IntSetEnlarge(t);
|
|
||||||
inc(t.counter);
|
|
||||||
h := key and t.max;
|
|
||||||
while t.data[h] <> nil do h := nextTry(h, t.max);
|
|
||||||
assert(t.data[h] = nil);
|
|
||||||
new(result);
|
|
||||||
{@ignore}
|
|
||||||
fillChar(result^, sizeof(result^), 0);
|
|
||||||
{@emit}
|
|
||||||
result.next := t.head;
|
|
||||||
result.key := key;
|
|
||||||
t.head := result;
|
|
||||||
t.data[h] := result;
|
|
||||||
end;
|
|
||||||
|
|
||||||
// ---------- slightly higher level procs ----------------------------------
|
|
||||||
|
|
||||||
function transform(key: int): int;
|
|
||||||
begin
|
|
||||||
if key < 0 then result := 1000000000 + key // avoid negative numbers!
|
|
||||||
else result := key
|
|
||||||
end;
|
|
||||||
|
|
||||||
function IntSetContains(const s: TIntSet; key: int): bool;
|
|
||||||
var
|
|
||||||
u: int;
|
|
||||||
t: PTrunk;
|
|
||||||
begin
|
|
||||||
u := transform(key);
|
|
||||||
t := IntSetGet(s, u div BitsPerTrunk);
|
|
||||||
if t <> nil then begin
|
|
||||||
u := u mod BitsPerTrunk;
|
|
||||||
result := (t.bits[u div BitsPerInt]
|
|
||||||
and (1 shl (u mod BitsPerInt))) <> 0
|
|
||||||
end
|
|
||||||
else
|
|
||||||
result := false
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure IntSetIncl(var s: TIntSet; key: int);
|
|
||||||
var
|
|
||||||
u: int;
|
|
||||||
t: PTrunk;
|
|
||||||
begin
|
|
||||||
u := transform(key);
|
|
||||||
t := IntSetPut(s, u div BitsPerTrunk);
|
|
||||||
u := u mod BitsPerTrunk;
|
|
||||||
t.bits[u div BitsPerInt] := t.bits[u div BitsPerInt]
|
|
||||||
or (1 shl (u mod BitsPerInt));
|
|
||||||
end;
|
|
||||||
|
|
||||||
function IntSetContainsOrIncl(var s: TIntSet; key: int): bool;
|
|
||||||
var
|
|
||||||
u: int;
|
|
||||||
t: PTrunk;
|
|
||||||
begin
|
|
||||||
u := transform(key);
|
|
||||||
t := IntSetGet(s, u div BitsPerTrunk);
|
|
||||||
if t <> nil then begin
|
|
||||||
u := u mod BitsPerTrunk;
|
|
||||||
result := (t.bits[u div BitsPerInt]
|
|
||||||
and (1 shl (u mod BitsPerInt))) <> 0;
|
|
||||||
if not result then
|
|
||||||
t.bits[u div BitsPerInt] := t.bits[u div BitsPerInt]
|
|
||||||
or (1 shl (u mod BitsPerInt));
|
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
IntSetIncl(s, key);
|
if mustRehash(length(t.data), t.counter) then begin
|
||||||
result := false
|
{@ignore}
|
||||||
end
|
setLength(n, length(t.data) * growthFactor);
|
||||||
|
{@emit
|
||||||
|
newSeq(n, length(t.data) * growthFactor); }
|
||||||
|
for i := 0 to high(n) do n[i].key := InvalidKey;
|
||||||
|
for i := 0 to high(t.data) do
|
||||||
|
if t.data[i].key <> InvalidKey then
|
||||||
|
IITableRawInsert(n, t.data[i].key, t.data[i].val);
|
||||||
|
{@ignore}
|
||||||
|
t.data := n;
|
||||||
|
{@emit
|
||||||
|
swap(t.data, n); }
|
||||||
|
end;
|
||||||
|
IITableRawInsert(t.data, key, val);
|
||||||
|
inc(t.counter)
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
//
|
|
||||||
//
|
|
||||||
// The Nimrod Compiler
|
|
||||||
// (c) Copyright 2008 Andreas Rumpf
|
|
||||||
//
|
|
||||||
// See the file "copying.txt", included in this
|
|
||||||
// distribution, for details about the copyright.
|
|
||||||
//
|
|
||||||
unit backends;
|
|
||||||
|
|
||||||
// This module only contains the PBackend type declaration/interface, each
|
|
||||||
// backend has to adhere to.
|
|
||||||
|
|
||||||
interface
|
|
||||||
|
|
||||||
{$include 'config.inc'}
|
|
||||||
|
|
||||||
uses
|
|
||||||
nsystem, idents, ropes, msgs, ast;
|
|
||||||
|
|
||||||
type
|
|
||||||
PBackend = ^TBackend;
|
|
||||||
|
|
||||||
TBackendEvent = (eNone, eAfterModule);
|
|
||||||
TEventMask = set of TBackendEvent;
|
|
||||||
TBackend = object(NObject)
|
|
||||||
eventMask: TEventMask;
|
|
||||||
module: PSym;
|
|
||||||
filename: string;
|
|
||||||
backendCreator: function (oldBackend: PBackend; module: PSym;
|
|
||||||
const filename: string): PBackend;
|
|
||||||
afterModuleEvent: procedure (b: PBackend; module: PNode);
|
|
||||||
// triggered AFTER a whole module has been checked for semantics
|
|
||||||
end;
|
|
||||||
|
|
||||||
function backendCreator(b: PBackend; module: PSym;
|
|
||||||
const filename: string): PBackend;
|
|
||||||
function newBackend(module: PSym; const filename: string): PBackend;
|
|
||||||
|
|
||||||
implementation
|
|
||||||
|
|
||||||
function newBackend(module: PSym; const filename: string): PBackend;
|
|
||||||
begin
|
|
||||||
new(result);
|
|
||||||
{@ignore}
|
|
||||||
fillChar(result^, sizeof(result^), 0);
|
|
||||||
{@emit}
|
|
||||||
result.backendCreator := backendCreator;
|
|
||||||
result.module := module;
|
|
||||||
result.filename := filename;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function backendCreator(b: PBackend; module: PSym;
|
|
||||||
const filename: string): PBackend;
|
|
||||||
begin
|
|
||||||
result := newBackend(module, filename);
|
|
||||||
end;
|
|
||||||
|
|
||||||
end.
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
//
|
//
|
||||||
unit bitsets;
|
unit bitsets;
|
||||||
|
|
||||||
// this unit handles Nimrod sets; it implements symbolic sets
|
// this unit handles Nimrod sets; it implements bit sets
|
||||||
// the code here should be reused in the Nimrod standard library
|
// the code here should be reused in the Nimrod standard library
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
@ -44,57 +44,58 @@ implementation
|
||||||
|
|
||||||
function BitSetIn(const x: TBitSet; const e: BiggestInt): Boolean;
|
function BitSetIn(const x: TBitSet; const e: BiggestInt): Boolean;
|
||||||
begin
|
begin
|
||||||
result := (x[int(e div ElemSize)] and (1 shl (e mod ElemSize))) <> 0
|
result := (x[int(e div ElemSize)] and toU8(int(1 shl (e mod ElemSize)))) <> toU8(0)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure BitSetIncl(var x: TBitSet; const elem: BiggestInt);
|
procedure BitSetIncl(var x: TBitSet; const elem: BiggestInt);
|
||||||
begin
|
begin
|
||||||
assert(elem >= 0);
|
assert(elem >= 0);
|
||||||
x[int(elem div ElemSize)] := toU8(x[int(elem div ElemSize)] or
|
x[int(elem div ElemSize)] := x[int(elem div ElemSize)] or
|
||||||
int(1 shl (elem mod ElemSize)))
|
toU8(int(1 shl (elem mod ElemSize)))
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure BitSetExcl(var x: TBitSet; const elem: BiggestInt);
|
procedure BitSetExcl(var x: TBitSet; const elem: BiggestInt);
|
||||||
begin
|
begin
|
||||||
x[int(elem div ElemSize)] := toU8(x[int(elem div ElemSize)] and
|
x[int(elem div ElemSize)] := x[int(elem div ElemSize)] and
|
||||||
not int(1 shl (elem mod ElemSize)))
|
not toU8(int(1 shl (elem mod ElemSize)))
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure BitSetInit(out b: TBitSet; len: int);
|
procedure BitSetInit(out b: TBitSet; len: int);
|
||||||
begin
|
begin
|
||||||
{@emit b := [];}
|
|
||||||
setLength(b, len);
|
|
||||||
{@ignore}
|
{@ignore}
|
||||||
|
setLength(b, len);
|
||||||
fillChar(b[0], length(b)*sizeof(b[0]), 0);
|
fillChar(b[0], length(b)*sizeof(b[0]), 0);
|
||||||
{@emit}
|
{@emit
|
||||||
|
newSeq(b, len);
|
||||||
|
}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure BitSetUnion(var x: TBitSet; const y: TBitSet);
|
procedure BitSetUnion(var x: TBitSet; const y: TBitSet);
|
||||||
var
|
var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
for i := 0 to high(x) do x[i] := toU8(x[i] or int(y[i]))
|
for i := 0 to high(x) do x[i] := x[i] or y[i]
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure BitSetDiff(var x: TBitSet; const y: TBitSet);
|
procedure BitSetDiff(var x: TBitSet; const y: TBitSet);
|
||||||
var
|
var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
for i := 0 to high(x) do x[i] := toU8(x[i] and not int(y[i]))
|
for i := 0 to high(x) do x[i] := x[i] and not y[i]
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure BitSetSymDiff(var x: TBitSet; const y: TBitSet);
|
procedure BitSetSymDiff(var x: TBitSet; const y: TBitSet);
|
||||||
var
|
var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
for i := 0 to high(x) do x[i] := toU8(x[i] xor int(y[i]))
|
for i := 0 to high(x) do x[i] := x[i] xor y[i]
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure BitSetIntersect(var x: TBitSet; const y: TBitSet);
|
procedure BitSetIntersect(var x: TBitSet; const y: TBitSet);
|
||||||
var
|
var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
for i := 0 to high(x) do x[i] := toU8(x[i] and int(y[i]))
|
for i := 0 to high(x) do x[i] := x[i] and y[i]
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function BitSetEquals(const x, y: TBitSet): Boolean;
|
function BitSetEquals(const x, y: TBitSet): Boolean;
|
||||||
|
|
@ -102,7 +103,7 @@ var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
for i := 0 to high(x) do
|
for i := 0 to high(x) do
|
||||||
if (x[i] <> int(y[i])) then begin
|
if x[i] <> y[i] then begin
|
||||||
result := false; exit;
|
result := false; exit;
|
||||||
end;
|
end;
|
||||||
result := true
|
result := true
|
||||||
|
|
@ -113,7 +114,7 @@ var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
for i := 0 to high(x) do
|
for i := 0 to high(x) do
|
||||||
if (x[i] and not int(y[i])) <> 0 then begin
|
if (x[i] and not y[i]) <> byte(0) then begin
|
||||||
result := false; exit;
|
result := false; exit;
|
||||||
end;
|
end;
|
||||||
result := true
|
result := true
|
||||||
|
|
|
||||||
704
nim/ccgexprs.pas
704
nim/ccgexprs.pas
File diff suppressed because it is too large
Load diff
|
|
@ -48,25 +48,16 @@ begin
|
||||||
app(p.s[cpsStmts], 'goto BeforeRet;' + tnl)
|
app(p.s[cpsStmts], 'goto BeforeRet;' + tnl)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure genObjectInit(p: BProc; sym: PSym);
|
|
||||||
begin
|
|
||||||
if containsObject(sym.typ) then begin
|
|
||||||
useMagic(p.module, 'objectInit');
|
|
||||||
appf(p.s[cpsInit], 'objectInit($1, $2);$n',
|
|
||||||
[addrLoc(sym.loc), genTypeInfo(p.module, sym.typ)])
|
|
||||||
end
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure initVariable(p: BProc; v: PSym);
|
procedure initVariable(p: BProc; v: PSym);
|
||||||
begin
|
begin
|
||||||
if containsGarbageCollectedRef(v.typ) or (v.ast = nil) then
|
if containsGarbageCollectedRef(v.typ) or (v.ast = nil) then
|
||||||
// Language change: always initialize variables if v.ast == nil!
|
// Language change: always initialize variables if v.ast == nil!
|
||||||
if not (skipVarGenericRange(v.typ).Kind in [tyArray, tyArrayConstr, tySet,
|
if not (skipVarGenericRange(v.typ).Kind in [tyArray, tyArrayConstr, tySet,
|
||||||
tyTuple, tyObject]) then
|
tyTuple, tyObject]) then
|
||||||
appf(p.s[cpsStmts], '$1 = 0;$n', [v.loc.r])
|
appf(p.s[cpsStmts], '$1 = 0;$n', [rdLoc(v.loc)])
|
||||||
else
|
else
|
||||||
appf(p.s[cpsStmts], 'memset((void*)&$1, 0, sizeof($1));$n',
|
appf(p.s[cpsStmts], 'memset((void*)$1, 0, sizeof($2));$n',
|
||||||
[v.loc.r])
|
[addrLoc(v.loc), rdLoc(v.loc)])
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure genVarStmt(p: BProc; n: PNode);
|
procedure genVarStmt(p: BProc; n: PNode);
|
||||||
|
|
@ -93,7 +84,7 @@ begin
|
||||||
genLineDir(p, a);
|
genLineDir(p, a);
|
||||||
expr(p, a.sons[2], v.loc);
|
expr(p, a.sons[2], v.loc);
|
||||||
end;
|
end;
|
||||||
genObjectInit(p, v); // XXX: correct position?
|
genObjectInit(p, v.typ, v.loc, true); // correct position
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -147,7 +138,7 @@ begin
|
||||||
it := n.sons[i];
|
it := n.sons[i];
|
||||||
case it.kind of
|
case it.kind of
|
||||||
nkElifBranch: begin
|
nkElifBranch: begin
|
||||||
a := initLocExpr(p, it.sons[0]);
|
initLocExpr(p, it.sons[0], a);
|
||||||
Lelse := getLabel(p);
|
Lelse := getLabel(p);
|
||||||
appf(p.s[cpsStmts], 'if (!$1) goto $2;$n', [rdLoc(a), Lelse]);
|
appf(p.s[cpsStmts], 'if (!$1) goto $2;$n', [rdLoc(a), Lelse]);
|
||||||
freeTemp(p, a);
|
freeTemp(p, a);
|
||||||
|
|
@ -177,17 +168,23 @@ begin
|
||||||
genLineDir(p, t);
|
genLineDir(p, t);
|
||||||
assert(sonsLen(t) = 2);
|
assert(sonsLen(t) = 2);
|
||||||
inc(p.labels);
|
inc(p.labels);
|
||||||
Labl := con('L'+'', toRope(p.labels));
|
Labl := con('LA', toRope(p.labels));
|
||||||
len := length(p.blocks);
|
len := length(p.blocks);
|
||||||
setLength(p.blocks, len+1);
|
setLength(p.blocks, len+1);
|
||||||
p.blocks[len].id := p.labels; // positive because we use it right away:
|
p.blocks[len].id := -p.labels; // negative because it isn't used yet
|
||||||
p.blocks[len].nestedTryStmts := p.nestedTryStmts;
|
p.blocks[len].nestedTryStmts := p.nestedTryStmts;
|
||||||
app(p.s[cpsStmts], 'while (1) {' + tnl);
|
app(p.s[cpsStmts], 'while (1) {' + tnl);
|
||||||
a := initLocExpr(p, t.sons[0]);
|
initLocExpr(p, t.sons[0], a);
|
||||||
|
if (t.sons[0].kind <> nkIntLit) or (t.sons[0].intVal = 0) then begin
|
||||||
|
p.blocks[len].id := abs(p.blocks[len].id);
|
||||||
appf(p.s[cpsStmts], 'if (!$1) goto $2;$n', [rdLoc(a), Labl]);
|
appf(p.s[cpsStmts], 'if (!$1) goto $2;$n', [rdLoc(a), Labl]);
|
||||||
|
end;
|
||||||
freeTemp(p, a);
|
freeTemp(p, a);
|
||||||
genStmts(p, t.sons[1]);
|
genStmts(p, t.sons[1]);
|
||||||
appf(p.s[cpsStmts], '} $1: ;$n', [Labl]);
|
if p.blocks[len].id > 0 then
|
||||||
|
appf(p.s[cpsStmts], '} $1: ;$n', [Labl])
|
||||||
|
else
|
||||||
|
app(p.s[cpsStmts], '}'+tnl);
|
||||||
setLength(p.blocks, length(p.blocks)-1)
|
setLength(p.blocks, length(p.blocks)-1)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -210,7 +207,7 @@ begin
|
||||||
if t.kind = nkBlockExpr then genStmtListExpr(p, t.sons[1], d)
|
if t.kind = nkBlockExpr then genStmtListExpr(p, t.sons[1], d)
|
||||||
else genStmts(p, t.sons[1]);
|
else genStmts(p, t.sons[1]);
|
||||||
if p.blocks[idx].id > 0 then // label has been used:
|
if p.blocks[idx].id > 0 then // label has been used:
|
||||||
appf(p.s[cpsStmts], 'L$1: ;$n', [toRope(p.blocks[idx].id)]);
|
appf(p.s[cpsStmts], 'LA$1: ;$n', [toRope(p.blocks[idx].id)]);
|
||||||
setLength(p.blocks, idx)
|
setLength(p.blocks, idx)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -236,7 +233,7 @@ begin
|
||||||
end;
|
end;
|
||||||
p.blocks[idx].id := abs(p.blocks[idx].id); // label is used
|
p.blocks[idx].id := abs(p.blocks[idx].id); // label is used
|
||||||
finishTryStmt(p, p.nestedTryStmts - p.blocks[idx].nestedTryStmts);
|
finishTryStmt(p, p.nestedTryStmts - p.blocks[idx].nestedTryStmts);
|
||||||
appf(p.s[cpsStmts], 'goto L$1;$n', [toRope(p.blocks[idx].id)])
|
appf(p.s[cpsStmts], 'goto LA$1;$n', [toRope(p.blocks[idx].id)])
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure genAsmStmt(p: BProc; t: PNode);
|
procedure genAsmStmt(p: BProc; t: PNode);
|
||||||
|
|
@ -287,7 +284,7 @@ begin
|
||||||
genLineDir(p, t);
|
genLineDir(p, t);
|
||||||
if t.sons[0] <> nil then begin
|
if t.sons[0] <> nil then begin
|
||||||
if gCmd <> cmdCompileToCpp then useMagic(p.module, 'raiseException');
|
if gCmd <> cmdCompileToCpp then useMagic(p.module, 'raiseException');
|
||||||
a := InitLocExpr(p, t.sons[0]);
|
InitLocExpr(p, t.sons[0], a);
|
||||||
e := rdLoc(a);
|
e := rdLoc(a);
|
||||||
freeTemp(p, a);
|
freeTemp(p, a);
|
||||||
typ := t.sons[0].typ;
|
typ := t.sons[0].typ;
|
||||||
|
|
@ -324,15 +321,15 @@ begin
|
||||||
len := sonsLen(b);
|
len := sonsLen(b);
|
||||||
for i := 0 to len - 2 do begin
|
for i := 0 to len - 2 do begin
|
||||||
if b.sons[i].kind = nkRange then begin
|
if b.sons[i].kind = nkRange then begin
|
||||||
x := initLocExpr(p, b.sons[i].sons[0]);
|
initLocExpr(p, b.sons[i].sons[0], x);
|
||||||
y := initLocExpr(p, b.sons[i].sons[1]);
|
initLocExpr(p, b.sons[i].sons[1], y);
|
||||||
freeTemp(p, x);
|
freeTemp(p, x);
|
||||||
freeTemp(p, y);
|
freeTemp(p, y);
|
||||||
appf(p.s[cpsStmts], rangeFormat,
|
appf(p.s[cpsStmts], rangeFormat,
|
||||||
[rdCharLoc(e), rdCharLoc(x), rdCharLoc(y), labl])
|
[rdCharLoc(e), rdCharLoc(x), rdCharLoc(y), labl])
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
x := initLocExpr(p, b.sons[i]);
|
initLocExpr(p, b.sons[i], x);
|
||||||
freeTemp(p, x);
|
freeTemp(p, x);
|
||||||
appf(p.s[cpsStmts], eqFormat,
|
appf(p.s[cpsStmts], eqFormat,
|
||||||
[rdCharLoc(e), rdCharLoc(x), labl])
|
[rdCharLoc(e), rdCharLoc(x), labl])
|
||||||
|
|
@ -347,7 +344,7 @@ var
|
||||||
begin
|
begin
|
||||||
Lend := getLabel(p);
|
Lend := getLabel(p);
|
||||||
for i := 1 to sonsLen(t) - 1 do begin
|
for i := 1 to sonsLen(t) - 1 do begin
|
||||||
appf(p.s[cpsStmts], 'L$1: ;$n', [toRope(labId+i)]);
|
appf(p.s[cpsStmts], 'LA$1: ;$n', [toRope(labId+i)]);
|
||||||
if t.sons[i].kind = nkOfBranch then begin
|
if t.sons[i].kind = nkOfBranch then begin
|
||||||
len := sonsLen(t.sons[i]);
|
len := sonsLen(t.sons[i]);
|
||||||
genStmts(p, t.sons[i].sons[len-1]);
|
genStmts(p, t.sons[i].sons[len-1]);
|
||||||
|
|
@ -366,17 +363,17 @@ var
|
||||||
a: TLoc;
|
a: TLoc;
|
||||||
i, labId: int;
|
i, labId: int;
|
||||||
begin
|
begin
|
||||||
a := initLocExpr(p, t.sons[0]);
|
initLocExpr(p, t.sons[0], a);
|
||||||
// fist pass: gnerate ifs+goto:
|
// fist pass: gnerate ifs+goto:
|
||||||
labId := p.labels;
|
labId := p.labels;
|
||||||
for i := 1 to sonsLen(t) - 1 do begin
|
for i := 1 to sonsLen(t) - 1 do begin
|
||||||
inc(p.labels);
|
inc(p.labels);
|
||||||
if t.sons[i].kind = nkOfBranch then
|
if t.sons[i].kind = nkOfBranch then
|
||||||
genCaseGenericBranch(p, t.sons[i], a, rangeFormat, eqFormat,
|
genCaseGenericBranch(p, t.sons[i], a, rangeFormat, eqFormat,
|
||||||
con('L'+'', toRope(p.labels)))
|
con('LA', toRope(p.labels)))
|
||||||
else
|
else
|
||||||
// else statement
|
// else statement
|
||||||
appf(p.s[cpsStmts], 'goto L$1;$n', [toRope(p.labels)]);
|
appf(p.s[cpsStmts], 'goto LA$1;$n', [toRope(p.labels)]);
|
||||||
end;
|
end;
|
||||||
// second pass: generate statements
|
// second pass: generate statements
|
||||||
genCaseSecondPass(p, t, labId);
|
genCaseSecondPass(p, t, labId);
|
||||||
|
|
@ -416,13 +413,13 @@ begin
|
||||||
else begin
|
else begin
|
||||||
a := 0;
|
a := 0;
|
||||||
for i := 0 to Length(s)-1 do begin
|
for i := 0 to Length(s)-1 do begin
|
||||||
a := a +{%} Ord(s[i]);
|
a := a +{%} int32(Ord(s[i]));
|
||||||
a := a +{%} a shl 10;
|
a := a +{%} a shl int32(10);
|
||||||
a := a xor (a shr 6);
|
a := a xor (a shr int32(6));
|
||||||
end;
|
end;
|
||||||
a := a +{%} a shl 3;
|
a := a +{%} a shl int32(3);
|
||||||
a := a xor (a shr 11);
|
a := a xor (a shr int32(11));
|
||||||
a := a +{%} a shl 15;
|
a := a +{%} a shl int32(15);
|
||||||
result := a
|
result := a
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
@ -450,7 +447,7 @@ begin
|
||||||
len := sonsLen(b);
|
len := sonsLen(b);
|
||||||
for i := 0 to len - 2 do begin
|
for i := 0 to len - 2 do begin
|
||||||
assert(b.sons[i].kind <> nkRange);
|
assert(b.sons[i].kind <> nkRange);
|
||||||
x := initLocExpr(p, b.sons[i]);
|
initLocExpr(p, b.sons[i], x);
|
||||||
freeTemp(p, x);
|
freeTemp(p, x);
|
||||||
assert(b.sons[i].kind in [nkStrLit..nkTripleStrLit]);
|
assert(b.sons[i].kind in [nkStrLit..nkTripleStrLit]);
|
||||||
j := int(hashString(b.sons[i].strVal) and high(branches));
|
j := int(hashString(b.sons[i].strVal) and high(branches));
|
||||||
|
|
@ -473,14 +470,16 @@ begin
|
||||||
if strings > stringCaseThreshold then begin
|
if strings > stringCaseThreshold then begin
|
||||||
useMagic(p.module, 'hashString');
|
useMagic(p.module, 'hashString');
|
||||||
bitMask := nmath.nextPowerOfTwo(strings)-1;
|
bitMask := nmath.nextPowerOfTwo(strings)-1;
|
||||||
|
{@ignore}
|
||||||
setLength(branches, bitMask+1);
|
setLength(branches, bitMask+1);
|
||||||
a := initLocExpr(p, t.sons[0]);
|
{@emit newSeq(branches, bitMask+1);}
|
||||||
|
initLocExpr(p, t.sons[0], a);
|
||||||
// fist pass: gnerate ifs+goto:
|
// fist pass: gnerate ifs+goto:
|
||||||
labId := p.labels;
|
labId := p.labels;
|
||||||
for i := 1 to sonsLen(t) - 1 do begin
|
for i := 1 to sonsLen(t) - 1 do begin
|
||||||
inc(p.labels);
|
inc(p.labels);
|
||||||
if t.sons[i].kind = nkOfBranch then
|
if t.sons[i].kind = nkOfBranch then
|
||||||
genCaseStringBranch(p, t.sons[i], a, con('L'+'', toRope(p.labels)),
|
genCaseStringBranch(p, t.sons[i], a, con('LA', toRope(p.labels)),
|
||||||
branches)
|
branches)
|
||||||
else begin
|
else begin
|
||||||
// else statement: nothing to do yet
|
// else statement: nothing to do yet
|
||||||
|
|
@ -497,7 +496,7 @@ begin
|
||||||
app(p.s[cpsStmts], '}' + tnl);
|
app(p.s[cpsStmts], '}' + tnl);
|
||||||
// else statement:
|
// else statement:
|
||||||
if t.sons[sonsLen(t)-1].kind <> nkOfBranch then
|
if t.sons[sonsLen(t)-1].kind <> nkOfBranch then
|
||||||
appf(p.s[cpsStmts], 'goto L$1;$n', [toRope(p.labels)]);
|
appf(p.s[cpsStmts], 'goto LA$1;$n', [toRope(p.labels)]);
|
||||||
// third pass: generate statements
|
// third pass: generate statements
|
||||||
genCaseSecondPass(p, t, labId);
|
genCaseSecondPass(p, t, labId);
|
||||||
freeTemp(p, a);
|
freeTemp(p, a);
|
||||||
|
|
@ -540,7 +539,7 @@ begin
|
||||||
break
|
break
|
||||||
end;
|
end;
|
||||||
if canGenerateSwitch then begin
|
if canGenerateSwitch then begin
|
||||||
a := initLocExpr(p, t.sons[0]);
|
initLocExpr(p, t.sons[0], a);
|
||||||
appf(p.s[cpsStmts], 'switch ($1) {$n', [rdCharLoc(a)]);
|
appf(p.s[cpsStmts], 'switch ($1) {$n', [rdCharLoc(a)]);
|
||||||
freeTemp(p, a);
|
freeTemp(p, a);
|
||||||
for i := 1 to sonsLen(t)-1 do begin
|
for i := 1 to sonsLen(t)-1 do begin
|
||||||
|
|
@ -821,7 +820,7 @@ var
|
||||||
a: TLoc;
|
a: TLoc;
|
||||||
begin
|
begin
|
||||||
genLineDir(p, e); // BUGFIX
|
genLineDir(p, e); // BUGFIX
|
||||||
a := InitLocExpr(p, e.sons[0]);
|
InitLocExpr(p, e.sons[0], a);
|
||||||
assert(a.t <> nil);
|
assert(a.t <> nil);
|
||||||
expr(p, e.sons[1], a);
|
expr(p, e.sons[1], a);
|
||||||
freeTemp(p, a)
|
freeTemp(p, a)
|
||||||
|
|
@ -838,9 +837,9 @@ begin
|
||||||
MessageOut(renderTree(t));
|
MessageOut(renderTree(t));
|
||||||
case t.kind of
|
case t.kind of
|
||||||
nkEmpty: begin end; // nothing to do!
|
nkEmpty: begin end; // nothing to do!
|
||||||
nkStmtList:
|
nkStmtList: begin
|
||||||
for i := 0 to sonsLen(t) - 1 do
|
for i := 0 to sonsLen(t)-1 do genStmts(p, t.sons[i]);
|
||||||
genStmts(p, t.sons[i]);
|
end;
|
||||||
nkBlockStmt: genBlock(p, t, a);
|
nkBlockStmt: genBlock(p, t, a);
|
||||||
nkIfStmt: genIfStmt(p, t);
|
nkIfStmt: genIfStmt(p, t);
|
||||||
nkWhileStmt: genWhileStmt(p, t);
|
nkWhileStmt: genWhileStmt(p, t);
|
||||||
|
|
@ -852,23 +851,25 @@ begin
|
||||||
nkBreakStmt: genBreakStmt(p, t);
|
nkBreakStmt: genBreakStmt(p, t);
|
||||||
nkCall: begin
|
nkCall: begin
|
||||||
genLineDir(p, t);
|
genLineDir(p, t);
|
||||||
a := initLocExpr(p, t);
|
initLocExpr(p, t, a);
|
||||||
freeTemp(p, a);
|
freeTemp(p, a);
|
||||||
end;
|
end;
|
||||||
nkAsgn: genAsgn(p, t);
|
nkAsgn: genAsgn(p, t);
|
||||||
nkDiscardStmt: begin
|
nkDiscardStmt: begin
|
||||||
genLineDir(p, t);
|
genLineDir(p, t);
|
||||||
a := initLocExpr(p, t.sons[0]);
|
initLocExpr(p, t.sons[0], a);
|
||||||
freeTemp(p, a)
|
freeTemp(p, a)
|
||||||
end;
|
end;
|
||||||
nkAsmStmt: genAsmStmt(p, t);
|
nkAsmStmt: genAsmStmt(p, t);
|
||||||
nkTryStmt:
|
nkTryStmt: begin
|
||||||
if gCmd = cmdCompileToCpp then genTryStmtCpp(p, t)
|
if gCmd = cmdCompileToCpp then genTryStmtCpp(p, t)
|
||||||
else genTryStmt(p, t);
|
else genTryStmt(p, t);
|
||||||
|
end;
|
||||||
nkRaiseStmt: genRaiseStmt(p, t);
|
nkRaiseStmt: genRaiseStmt(p, t);
|
||||||
nkTypeSection: begin
|
nkTypeSection: begin
|
||||||
// nothing to do:
|
// we have to emit the type information for object types here to support
|
||||||
// we generate only when the symbol is accessed
|
// seperate compilation:
|
||||||
|
genTypeSection(p.module, t);
|
||||||
end;
|
end;
|
||||||
nkCommentStmt, nkNilLit, nkIteratorDef, nkIncludeStmt, nkImportStmt,
|
nkCommentStmt, nkNilLit, nkIteratorDef, nkIncludeStmt, nkImportStmt,
|
||||||
nkFromStmt, nkTemplateDef, nkMacroDef: begin end;
|
nkFromStmt, nkTemplateDef, nkMacroDef: begin end;
|
||||||
|
|
|
||||||
346
nim/ccgtypes.pas
346
nim/ccgtypes.pas
|
|
@ -7,16 +7,27 @@
|
||||||
// distribution, for details about the copyright.
|
// distribution, for details about the copyright.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
//var
|
||||||
|
// newDummyVar: int; // just to check the rodgen mechanism
|
||||||
|
|
||||||
// ------------------------- Name Mangling --------------------------------
|
// ------------------------- Name Mangling --------------------------------
|
||||||
|
|
||||||
function mangle(const name: string): string;
|
function mangle(const name: string): string;
|
||||||
var
|
var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
if name[strStart] in ['A'..'Z', '0'..'9', 'a'..'z'] then
|
case name[strStart] of
|
||||||
result := toUpper(name[strStart])+''
|
'a'..'z': begin
|
||||||
|
result := '';
|
||||||
|
addChar(result, chr(ord(name[strStart]) - ord('a') + ord('A')));
|
||||||
|
end;
|
||||||
|
'0'..'9', 'A'..'Z': begin
|
||||||
|
result := '';
|
||||||
|
addChar(result, name[strStart]);
|
||||||
|
end;
|
||||||
else
|
else
|
||||||
result := 'HEX' + toHex(ord(name[strStart]), 2);
|
result := 'HEX' + toHex(ord(name[strStart]), 2);
|
||||||
|
end;
|
||||||
for i := strStart+1 to length(name) + strStart-1 do begin
|
for i := strStart+1 to length(name) + strStart-1 do begin
|
||||||
case name[i] of
|
case name[i] of
|
||||||
'A'..'Z': addChar(result, chr(ord(name[i]) - ord('A') + ord('a')));
|
'A'..'Z': addChar(result, chr(ord(name[i]) - ord('A') + ord('a')));
|
||||||
|
|
@ -29,11 +40,28 @@ end;
|
||||||
|
|
||||||
function mangleName(s: PSym): PRope;
|
function mangleName(s: PSym): PRope;
|
||||||
begin
|
begin
|
||||||
result := ropef('$1_$2', [toRope(mangle(s.name.s)), toRope(s.id)]);
|
result := s.loc.r;
|
||||||
|
if result = nil then begin
|
||||||
|
result := toRope(mangle(s.name.s));
|
||||||
|
app(result, '_'+'');
|
||||||
|
app(result, toRope(s.id));
|
||||||
if optGenMapping in gGlobalOptions then
|
if optGenMapping in gGlobalOptions then
|
||||||
if s.owner <> nil then
|
if s.owner <> nil then
|
||||||
appf(gMapping, '$1.$2 $3$n',
|
appf(gMapping, '"$1.$2": $3$n',
|
||||||
[toRope(s.owner.Name.s), toRope(s.name.s), result])
|
[toRope(s.owner.Name.s), toRope(s.name.s), result]);
|
||||||
|
s.loc.r := result;
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
function getTypeName(typ: PType): PRope;
|
||||||
|
begin
|
||||||
|
if (typ.sym <> nil) and ([sfImportc, sfExportc] * typ.sym.flags <> []) then
|
||||||
|
result := typ.sym.loc.r
|
||||||
|
else begin
|
||||||
|
if typ.loc.r = nil then typ.loc.r := con('TY', toRope(typ.id));
|
||||||
|
result := typ.loc.r
|
||||||
|
end;
|
||||||
|
if result = nil then InternalError('getTypeName: ' + typeKindToStr[typ.kind]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// ------------------------------ C type generator ------------------------
|
// ------------------------------ C type generator ------------------------
|
||||||
|
|
@ -44,7 +72,7 @@ begin
|
||||||
tyNone: result := ctVoid;
|
tyNone: result := ctVoid;
|
||||||
tyBool: result := ctBool;
|
tyBool: result := ctBool;
|
||||||
tyChar: result := ctChar;
|
tyChar: result := ctChar;
|
||||||
tyEmptySet, tySet: begin
|
tySet: begin
|
||||||
case int(getSize(typ)) of
|
case int(getSize(typ)) of
|
||||||
1: result := ctInt8;
|
1: result := ctInt8;
|
||||||
2: result := ctInt16;
|
2: result := ctInt16;
|
||||||
|
|
@ -90,7 +118,8 @@ begin
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function getTypeDesc(m: BModule; typ: PType): PRope; forward;
|
function getTypeDescAux(m: BModule; typ: PType;
|
||||||
|
var check: TIntSet): PRope; forward;
|
||||||
|
|
||||||
function needsComplexAssignment(typ: PType): bool;
|
function needsComplexAssignment(typ: PType): bool;
|
||||||
begin
|
begin
|
||||||
|
|
@ -107,7 +136,8 @@ begin
|
||||||
result := true
|
result := true
|
||||||
else begin
|
else begin
|
||||||
case mapType(rettype) of
|
case mapType(rettype) of
|
||||||
ctArray: result := true;
|
ctArray:
|
||||||
|
result := not (skipGeneric(rettype).kind in [tyVar, tyRef, tyPtr]);
|
||||||
ctStruct: result := needsComplexAssignment(skipGeneric(rettype));
|
ctStruct: result := needsComplexAssignment(skipGeneric(rettype));
|
||||||
else result := false;
|
else result := false;
|
||||||
end
|
end
|
||||||
|
|
@ -119,18 +149,20 @@ const
|
||||||
'N_STDCALL', 'N_CDECL', 'N_SAFECALL', 'N_SYSCALL',
|
'N_STDCALL', 'N_CDECL', 'N_SAFECALL', 'N_SYSCALL',
|
||||||
// this is probably not correct for all platforms,
|
// this is probably not correct for all platforms,
|
||||||
// but one can //define it to what you want so there will no problem
|
// but one can //define it to what you want so there will no problem
|
||||||
'N_INLINE', 'N_FASTCALL', 'N_CLOSURE', 'N_NOCONV');
|
'N_INLINE', 'N_NOINLINE', 'N_FASTCALL', 'N_CLOSURE', 'N_NOCONV');
|
||||||
|
|
||||||
function CacheGetType(const tab: TIdTable; key: PType): PRope;
|
function CacheGetType(const tab: TIdTable; key: PType): PRope;
|
||||||
begin
|
begin
|
||||||
// returns nil if we need to declare this type
|
// returns nil if we need to declare this type
|
||||||
result := PRope(TableGetType(tab, key))
|
// since types are now unique via the ``GetUniqueType`` mechanism, this slow
|
||||||
|
// linear search is not necessary anymore:
|
||||||
|
result := PRope(IdTableGet(tab, key))
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function getTempName(): PRope;
|
function getTempName(): PRope;
|
||||||
begin
|
begin
|
||||||
inc(gUnique);
|
result := con('TMP', toRope(gId));
|
||||||
result := con('T'+'', toRope(gUnique))
|
inc(gId);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ccgIntroducedPtr(s: PSym): bool;
|
function ccgIntroducedPtr(s: PSym): bool;
|
||||||
|
|
@ -166,7 +198,8 @@ begin
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure genProcParams(m: BModule; t: PType; out rettype, params: PRope);
|
procedure genProcParams(m: BModule; t: PType; out rettype, params: PRope;
|
||||||
|
var check: TIntSet);
|
||||||
var
|
var
|
||||||
i, j: int;
|
i, j: int;
|
||||||
param: PSym;
|
param: PSym;
|
||||||
|
|
@ -177,12 +210,12 @@ begin
|
||||||
// C cannot return arrays (what a poor language...)
|
// C cannot return arrays (what a poor language...)
|
||||||
rettype := toRope('void')
|
rettype := toRope('void')
|
||||||
else
|
else
|
||||||
rettype := getTypeDesc(m, t.sons[0]);
|
rettype := getTypeDescAux(m, t.sons[0], check);
|
||||||
for i := 1 to sonsLen(t.n)-1 do begin
|
for i := 1 to sonsLen(t.n)-1 do begin
|
||||||
if t.n.sons[i].kind <> nkSym then InternalError(t.n.info, 'genProcParams');
|
if t.n.sons[i].kind <> nkSym then InternalError(t.n.info, 'genProcParams');
|
||||||
param := t.n.sons[i].sym;
|
param := t.n.sons[i].sym;
|
||||||
fillLoc(param.loc, locParam, param.typ, mangleName(param), OnStack);
|
fillLoc(param.loc, locParam, param.typ, mangleName(param), OnStack);
|
||||||
app(params, getTypeDesc(m, param.typ));
|
app(params, getTypeDescAux(m, param.typ, check));
|
||||||
if ccgIntroducedPtr(param) then begin
|
if ccgIntroducedPtr(param) then begin
|
||||||
app(params, '*'+'');
|
app(params, '*'+'');
|
||||||
include(param.loc.flags, lfIndirect);
|
include(param.loc.flags, lfIndirect);
|
||||||
|
|
@ -203,7 +236,7 @@ begin
|
||||||
end;
|
end;
|
||||||
if (t.sons[0] <> nil) and isInvalidReturnType(t.sons[0]) then begin
|
if (t.sons[0] <> nil) and isInvalidReturnType(t.sons[0]) then begin
|
||||||
if params <> nil then app(params, ', ');
|
if params <> nil then app(params, ', ');
|
||||||
app(params, getTypeDesc(m, t.sons[0]));
|
app(params, getTypeDescAux(m, t.sons[0], check));
|
||||||
if mapType(t.sons[0]) <> ctArray then app(params, '*'+'');
|
if mapType(t.sons[0]) <> ctArray then app(params, '*'+'');
|
||||||
app(params, ' Result');
|
app(params, ' Result');
|
||||||
end;
|
end;
|
||||||
|
|
@ -227,25 +260,16 @@ begin
|
||||||
result := (t.sym <> nil) and (sfImportc in t.sym.flags)
|
result := (t.sym <> nil) and (sfImportc in t.sym.flags)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function getTypeName(typ: PType): PRope;
|
function typeNameOrLiteral(t: PType; const literal: string): PRope;
|
||||||
begin
|
begin
|
||||||
if (typ.sym <> nil) and ([sfImportc, sfExportc] * typ.sym.flags <> []) then
|
if (t.sym <> nil) and (sfImportc in t.sym.flags) and
|
||||||
result := typ.sym.loc.r
|
(t.sym.magic = mNone) then
|
||||||
else begin
|
result := getTypeName(t)
|
||||||
if typ.loc.r = nil then typ.loc.r := con('Ty', toRope(typ.id));
|
|
||||||
result := typ.loc.r
|
|
||||||
end
|
|
||||||
end;
|
|
||||||
|
|
||||||
function typeNameOrLiteral(typ: PType; const literal: string): PRope;
|
|
||||||
begin
|
|
||||||
if isImportedType(typ) then
|
|
||||||
result := getTypeName(typ)
|
|
||||||
else
|
else
|
||||||
result := toRope(literal)
|
result := toRope(literal)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function getSimpleTypeDesc(typ: PType): PRope;
|
function getSimpleTypeDesc(m: BModule; typ: PType): PRope;
|
||||||
const
|
const
|
||||||
NumericalTypeToStr: array [tyInt..tyFloat128] of string = (
|
NumericalTypeToStr: array [tyInt..tyFloat128] of string = (
|
||||||
'NI', 'NI8', 'NI16', 'NI32', 'NI64', 'NF', 'NF32', 'NF64', 'NF128');
|
'NI', 'NI8', 'NI16', 'NI32', 'NI64', 'NF', 'NF32', 'NF64', 'NF128');
|
||||||
|
|
@ -267,14 +291,17 @@ begin
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
tyString: result := typeNameOrLiteral(typ, 'string');
|
tyString: begin
|
||||||
|
useMagic(m, 'NimStringDesc');
|
||||||
|
result := typeNameOrLiteral(typ, 'NimStringDesc*');
|
||||||
|
end;
|
||||||
tyCstring: result := typeNameOrLiteral(typ, 'NCSTRING');
|
tyCstring: result := typeNameOrLiteral(typ, 'NCSTRING');
|
||||||
tyBool: result := typeNameOrLiteral(typ, 'NIM_BOOL');
|
tyBool: result := typeNameOrLiteral(typ, 'NIM_BOOL');
|
||||||
tyChar: result := typeNameOrLiteral(typ, 'NIM_CHAR');
|
tyChar: result := typeNameOrLiteral(typ, 'NIM_CHAR');
|
||||||
tyNil: result := typeNameOrLiteral(typ, '0'+'');
|
tyNil: result := typeNameOrLiteral(typ, '0'+'');
|
||||||
tyInt..tyFloat128:
|
tyInt..tyFloat128:
|
||||||
result := typeNameOrLiteral(typ, NumericalTypeToStr[typ.Kind]);
|
result := typeNameOrLiteral(typ, NumericalTypeToStr[typ.Kind]);
|
||||||
tyRange: result := getSimpleTypeDesc(typ.sons[0]);
|
tyRange: result := getSimpleTypeDesc(m, typ.sons[0]);
|
||||||
else result := nil;
|
else result := nil;
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
@ -284,7 +311,7 @@ begin
|
||||||
if typ = nil then
|
if typ = nil then
|
||||||
result := toRope('void')
|
result := toRope('void')
|
||||||
else begin
|
else begin
|
||||||
result := getSimpleTypeDesc(typ);
|
result := getSimpleTypeDesc(m, typ);
|
||||||
if result = nil then
|
if result = nil then
|
||||||
result := CacheGetType(m.typeCache, typ)
|
result := CacheGetType(m.typeCache, typ)
|
||||||
end
|
end
|
||||||
|
|
@ -325,7 +352,7 @@ begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function genRecordFieldsAux(m: BModule; n: PNode; accessExpr: PRope;
|
function genRecordFieldsAux(m: BModule; n: PNode; accessExpr: PRope;
|
||||||
rectype: PType): PRope;
|
rectype: PType; var check: TIntSet): PRope;
|
||||||
var
|
var
|
||||||
i: int;
|
i: int;
|
||||||
ae, uname, sname, a: PRope;
|
ae, uname, sname, a: PRope;
|
||||||
|
|
@ -336,13 +363,14 @@ begin
|
||||||
case n.kind of
|
case n.kind of
|
||||||
nkRecList: begin
|
nkRecList: begin
|
||||||
for i := 0 to sonsLen(n)-1 do begin
|
for i := 0 to sonsLen(n)-1 do begin
|
||||||
app(result, genRecordFieldsAux(m, n.sons[i], accessExpr, rectype));
|
app(result, genRecordFieldsAux(m, n.sons[i], accessExpr,
|
||||||
|
rectype, check));
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
nkRecCase: begin
|
nkRecCase: begin
|
||||||
if (n.sons[0].kind <> nkSym) then
|
if (n.sons[0].kind <> nkSym) then
|
||||||
InternalError(n.info, 'genRecordFieldsAux');
|
InternalError(n.info, 'genRecordFieldsAux');
|
||||||
app(result, genRecordFieldsAux(m, n.sons[0], accessExpr, rectype));
|
app(result, genRecordFieldsAux(m, n.sons[0], accessExpr, rectype, check));
|
||||||
uname := toRope(mangle(n.sons[0].sym.name.s)+ 'U');
|
uname := toRope(mangle(n.sons[0].sym.name.s)+ 'U');
|
||||||
if accessExpr <> nil then ae := ropef('$1.$2', [accessExpr, uname])
|
if accessExpr <> nil then ae := ropef('$1.$2', [accessExpr, uname])
|
||||||
else ae := uname;
|
else ae := uname;
|
||||||
|
|
@ -354,14 +382,14 @@ begin
|
||||||
if k.kind <> nkSym then begin
|
if k.kind <> nkSym then begin
|
||||||
sname := con('S'+'', toRope(i));
|
sname := con('S'+'', toRope(i));
|
||||||
a := genRecordFieldsAux(m, k, ropef('$1.$2', [ae, sname]),
|
a := genRecordFieldsAux(m, k, ropef('$1.$2', [ae, sname]),
|
||||||
rectype);
|
rectype, check);
|
||||||
if a <> nil then begin
|
if a <> nil then begin
|
||||||
app(result, 'struct {');
|
app(result, 'struct {');
|
||||||
app(result, a);
|
app(result, a);
|
||||||
appf(result, '} $1;$n', [sname]);
|
appf(result, '} $1;$n', [sname]);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else app(result, genRecordFieldsAux(m, k, ae, rectype));
|
else app(result, genRecordFieldsAux(m, k, ae, rectype, check));
|
||||||
end;
|
end;
|
||||||
else internalError('genRecordFieldsAux(record case branch)');
|
else internalError('genRecordFieldsAux(record case branch)');
|
||||||
end;
|
end;
|
||||||
|
|
@ -375,18 +403,19 @@ begin
|
||||||
if accessExpr <> nil then ae := ropef('$1.$2', [accessExpr, sname])
|
if accessExpr <> nil then ae := ropef('$1.$2', [accessExpr, sname])
|
||||||
else ae := sname;
|
else ae := sname;
|
||||||
fillLoc(field.loc, locField, field.typ, ae, OnUnknown);
|
fillLoc(field.loc, locField, field.typ, ae, OnUnknown);
|
||||||
appf(result, '$1 $2;$n', [getTypeDesc(m, field.loc.t), sname])
|
appf(result, '$1 $2;$n', [getTypeDescAux(m, field.loc.t, check), sname])
|
||||||
end;
|
end;
|
||||||
else internalError(n.info, 'genRecordFieldsAux()');
|
else internalError(n.info, 'genRecordFieldsAux()');
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function getRecordFields(m: BModule; typ: PType): PRope;
|
function getRecordFields(m: BModule; typ: PType; var check: TIntSet): PRope;
|
||||||
begin
|
begin
|
||||||
result := genRecordFieldsAux(m, typ.n, nil, typ);
|
result := genRecordFieldsAux(m, typ.n, nil, typ, check);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function getRecordDesc(m: BModule; typ: PType; name: PRope): PRope;
|
function getRecordDesc(m: BModule; typ: PType; name: PRope;
|
||||||
|
var check: TIntSet): PRope;
|
||||||
var
|
var
|
||||||
desc: PRope;
|
desc: PRope;
|
||||||
hasField: bool;
|
hasField: bool;
|
||||||
|
|
@ -406,18 +435,18 @@ begin
|
||||||
end
|
end
|
||||||
else if gCmd = cmdCompileToCpp then begin
|
else if gCmd = cmdCompileToCpp then begin
|
||||||
result := ropef('struct $1 : public $2 {$n',
|
result := ropef('struct $1 : public $2 {$n',
|
||||||
[name, getTypeDesc(m, typ.sons[0])]);
|
[name, getTypeDescAux(m, typ.sons[0], check)]);
|
||||||
hasField := true
|
hasField := true
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
result := ropef('struct $1 {$n $2 Sup;$n',
|
result := ropef('struct $1 {$n $2 Sup;$n',
|
||||||
[name, getTypeDesc(m, typ.sons[0])]);
|
[name, getTypeDescAux(m, typ.sons[0], check)]);
|
||||||
hasField := true
|
hasField := true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
result := ropef('struct $1 {$n', [name]);
|
result := ropef('struct $1 {$n', [name]);
|
||||||
desc := getRecordFields(m, typ);
|
desc := getRecordFields(m, typ, check);
|
||||||
if (desc = nil) and not hasField then
|
if (desc = nil) and not hasField then
|
||||||
// no fields in struct are not valid in C, so generate a dummy:
|
// no fields in struct are not valid in C, so generate a dummy:
|
||||||
appf(result, 'char dummy;$n', [])
|
appf(result, 'char dummy;$n', [])
|
||||||
|
|
@ -435,7 +464,7 @@ begin
|
||||||
m.typeStack[L] := typ;
|
m.typeStack[L] := typ;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function getTypeDesc(m: BModule; typ: PType): PRope;
|
function getTypeDescAux(m: BModule; typ: PType; var check: TIntSet): PRope;
|
||||||
// returns only the type's name
|
// returns only the type's name
|
||||||
var
|
var
|
||||||
name, rettype, desc, recdesc: PRope;
|
name, rettype, desc, recdesc: PRope;
|
||||||
|
|
@ -443,12 +472,18 @@ var
|
||||||
t, et: PType;
|
t, et: PType;
|
||||||
begin
|
begin
|
||||||
t := getUniqueType(typ);
|
t := getUniqueType(typ);
|
||||||
if t = nil then InternalError('getTypeDesc: t == nil');
|
if t = nil then InternalError('getTypeDescAux: t == nil');
|
||||||
if t.sym <> nil then useHeader(m, t.sym);
|
if t.sym <> nil then useHeader(m, t.sym);
|
||||||
result := getTypePre(m, t);
|
result := getTypePre(m, t);
|
||||||
if result <> nil then exit;
|
if result <> nil then exit;
|
||||||
|
if IntSetContainsOrIncl(check, t.id) then begin
|
||||||
|
InternalError('cannot generate C type for: ' + typeToString(typ));
|
||||||
|
// XXX: this BUG is hard to fix -> we need to introduce helper structs,
|
||||||
|
// but determining when this needs to be done is hard. We should split
|
||||||
|
// C type generation into an analysis and a code generation phase somehow.
|
||||||
|
end;
|
||||||
case t.Kind of
|
case t.Kind of
|
||||||
tyRef, tyPtr, tyVar, tyOpenArray: begin
|
tyRef, tyPtr, tyVar: begin
|
||||||
et := getUniqueType(t.sons[0]);
|
et := getUniqueType(t.sons[0]);
|
||||||
if et.kind in [tyArrayConstr, tyArray, tyOpenArray] then
|
if et.kind in [tyArrayConstr, tyArray, tyOpenArray] then
|
||||||
et := getUniqueType(elemType(et));
|
et := getUniqueType(elemType(et));
|
||||||
|
|
@ -469,15 +504,20 @@ begin
|
||||||
end;
|
end;
|
||||||
else begin
|
else begin
|
||||||
// else we have a strong dependency :-(
|
// else we have a strong dependency :-(
|
||||||
result := con(getTypeDesc(m, et), '*'+'');
|
result := con(getTypeDescAux(m, et, check), '*'+'');
|
||||||
IdTablePut(m.typeCache, t, result)
|
IdTablePut(m.typeCache, t, result)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
tyOpenArray: begin
|
||||||
|
et := getUniqueType(t.sons[0]);
|
||||||
|
result := con(getTypeDescAux(m, et, check), '*'+'');
|
||||||
|
IdTablePut(m.typeCache, t, result)
|
||||||
|
end;
|
||||||
tyProc: begin
|
tyProc: begin
|
||||||
result := getTypeName(t);
|
result := getTypeName(t);
|
||||||
IdTablePut(m.typeCache, t, result);
|
IdTablePut(m.typeCache, t, result);
|
||||||
genProcParams(m, t, rettype, desc);
|
genProcParams(m, t, rettype, desc, check);
|
||||||
if not isImportedType(t) then begin
|
if not isImportedType(t) then begin
|
||||||
if t.callConv <> ccClosure then
|
if t.callConv <> ccClosure then
|
||||||
appf(m.s[cfsTypes], 'typedef $1_PTR($2, $3) $4;$n',
|
appf(m.s[cfsTypes], 'typedef $1_PTR($2, $3) $4;$n',
|
||||||
|
|
@ -501,12 +541,14 @@ begin
|
||||||
end;
|
end;
|
||||||
assert(CacheGetType(m.typeCache, t) = nil);
|
assert(CacheGetType(m.typeCache, t) = nil);
|
||||||
IdTablePut(m.typeCache, t, con(result, '*'+''));
|
IdTablePut(m.typeCache, t, con(result, '*'+''));
|
||||||
if not isImportedType(t) then
|
if not isImportedType(t) then begin
|
||||||
|
useMagic(m, 'TGenericSeq');
|
||||||
appf(m.s[cfsSeqTypes],
|
appf(m.s[cfsSeqTypes],
|
||||||
'struct $2 {$n' +
|
'struct $2 {$n' +
|
||||||
' NI len, space;$n' +
|
' TGenericSeq Sup;$n' +
|
||||||
' $1 data[SEQ_DECL_SIZE];$n' +
|
' $1 data[SEQ_DECL_SIZE];$n' +
|
||||||
'};$n', [getTypeDesc(m, t.sons[0]), result]);
|
'};$n', [getTypeDescAux(m, t.sons[0], check), result]);
|
||||||
|
end;
|
||||||
app(result, '*'+'');
|
app(result, '*'+'');
|
||||||
end;
|
end;
|
||||||
tyArrayConstr, tyArray: begin
|
tyArrayConstr, tyArray: begin
|
||||||
|
|
@ -516,7 +558,7 @@ begin
|
||||||
IdTablePut(m.typeCache, t, result);
|
IdTablePut(m.typeCache, t, result);
|
||||||
if not isImportedType(t) then
|
if not isImportedType(t) then
|
||||||
appf(m.s[cfsTypes], 'typedef $1 $2[$3];$n',
|
appf(m.s[cfsTypes], 'typedef $1 $2[$3];$n',
|
||||||
[getTypeDesc(m, t.sons[1]), result, ToRope(n)])
|
[getTypeDescAux(m, t.sons[1], check), result, ToRope(n)])
|
||||||
end;
|
end;
|
||||||
tyObject, tyTuple: begin
|
tyObject, tyTuple: begin
|
||||||
result := CacheGetType(m.forwTypeCache, t);
|
result := CacheGetType(m.forwTypeCache, t);
|
||||||
|
|
@ -528,7 +570,8 @@ begin
|
||||||
IdTablePut(m.forwTypeCache, t, result)
|
IdTablePut(m.forwTypeCache, t, result)
|
||||||
end;
|
end;
|
||||||
IdTablePut(m.typeCache, t, result);
|
IdTablePut(m.typeCache, t, result);
|
||||||
recdesc := getRecordDesc(m, t, result); // always call for sideeffects
|
// always call for sideeffects:
|
||||||
|
recdesc := getRecordDesc(m, t, result, check);
|
||||||
if not isImportedType(t) then app(m.s[cfsTypes], recdesc);
|
if not isImportedType(t) then app(m.s[cfsTypes], recdesc);
|
||||||
end;
|
end;
|
||||||
tySet: begin
|
tySet: begin
|
||||||
|
|
@ -546,14 +589,22 @@ begin
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
tyGenericInst: result := getTypeDesc(m, lastSon(t));
|
tyGenericInst: result := getTypeDescAux(m, lastSon(t), check);
|
||||||
else begin
|
else begin
|
||||||
InternalError('getTypeDesc(' + typeKindToStr[t.kind] + ')');
|
InternalError('getTypeDescAux(' + typeKindToStr[t.kind] + ')');
|
||||||
result := nil
|
result := nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function getTypeDesc(m: BModule; typ: PType): PRope;
|
||||||
|
var
|
||||||
|
check: TIntSet;
|
||||||
|
begin
|
||||||
|
IntSetInit(check);
|
||||||
|
result := getTypeDescAux(m, typ, check);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure finishTypeDescriptions(m: BModule);
|
procedure finishTypeDescriptions(m: BModule);
|
||||||
var
|
var
|
||||||
i: int;
|
i: int;
|
||||||
|
|
@ -568,14 +619,16 @@ end;
|
||||||
function genProcHeader(m: BModule; prc: PSym): PRope;
|
function genProcHeader(m: BModule; prc: PSym): PRope;
|
||||||
var
|
var
|
||||||
rettype, params: PRope;
|
rettype, params: PRope;
|
||||||
|
check: TIntSet;
|
||||||
begin
|
begin
|
||||||
// using static is needed for inline procs
|
// using static is needed for inline procs
|
||||||
if (prc.typ.callConv = ccInline) then
|
if (prc.typ.callConv = ccInline) then
|
||||||
result := toRope('static ')
|
result := toRope('static ')
|
||||||
else
|
else
|
||||||
result := nil;
|
result := nil;
|
||||||
|
IntSetInit(check);
|
||||||
fillLoc(prc.loc, locProc, prc.typ, mangleName(prc), OnUnknown);
|
fillLoc(prc.loc, locProc, prc.typ, mangleName(prc), OnUnknown);
|
||||||
genProcParams(m, prc.typ, rettype, params);
|
genProcParams(m, prc.typ, rettype, params, check);
|
||||||
appf(result, '$1($2, $3)$4',
|
appf(result, '$1($2, $3)$4',
|
||||||
[toRope(CallingConvToStr[prc.typ.callConv]),
|
[toRope(CallingConvToStr[prc.typ.callConv]),
|
||||||
rettype, prc.loc.r, params])
|
rettype, prc.loc.r, params])
|
||||||
|
|
@ -583,25 +636,33 @@ end;
|
||||||
|
|
||||||
// ----------------------- type information ----------------------------------
|
// ----------------------- type information ----------------------------------
|
||||||
|
|
||||||
var
|
|
||||||
gTypeInfoGenerated: TIntSet;
|
|
||||||
|
|
||||||
function genTypeInfo(m: BModule; typ: PType): PRope; forward;
|
function genTypeInfo(m: BModule; typ: PType): PRope; forward;
|
||||||
|
|
||||||
procedure allocMemTI(m: BModule; name: PRope);
|
function getNimNode(m: BModule): PRope;
|
||||||
|
begin
|
||||||
|
result := ropef('$1[$2]', [m.typeNodesName, toRope(m.typeNodes)]);
|
||||||
|
inc(m.typeNodes);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function getNimType(m: BModule): PRope;
|
||||||
|
begin
|
||||||
|
result := ropef('$1[$2]', [m.nimTypesName, toRope(m.nimTypes)]);
|
||||||
|
inc(m.nimTypes);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure allocMemTI(m: BModule; typ: PType; name: PRope);
|
||||||
var
|
var
|
||||||
tmp: PRope;
|
tmp: PRope;
|
||||||
begin
|
begin
|
||||||
tmp := getTempName();
|
tmp := getNimType(m);
|
||||||
appf(m.s[cfsTypeInit1], 'static TNimType $1;$n', [tmp]);
|
|
||||||
appf(m.s[cfsTypeInit2], '$2 = &$1;$n', [tmp, name]);
|
appf(m.s[cfsTypeInit2], '$2 = &$1;$n', [tmp, name]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure genTypeInfoAuxBase(m: BModule; typ: PType; name, base: PRope);
|
procedure genTypeInfoAuxBase(m: BModule; typ: PType; name, base: PRope);
|
||||||
var
|
var
|
||||||
nimtypeKind: int;
|
nimtypeKind, flags: int;
|
||||||
begin
|
begin
|
||||||
allocMemTI(m, name);
|
allocMemTI(m, typ, name);
|
||||||
if (typ.kind = tyObject) and (tfFinal in typ.flags)
|
if (typ.kind = tyObject) and (tfFinal in typ.flags)
|
||||||
and (typ.sons[0] = nil) then
|
and (typ.sons[0] = nil) then
|
||||||
nimtypeKind := ord(high(TTypeKind))+1 // tyPureObject
|
nimtypeKind := ord(high(TTypeKind))+1 // tyPureObject
|
||||||
|
|
@ -612,7 +673,15 @@ begin
|
||||||
'$1->kind = $3;$n' +
|
'$1->kind = $3;$n' +
|
||||||
'$1->base = $4;$n', [
|
'$1->base = $4;$n', [
|
||||||
name, getTypeDesc(m, typ), toRope(nimtypeKind), base]);
|
name, getTypeDesc(m, typ), toRope(nimtypeKind), base]);
|
||||||
appf(m.s[cfsVars], 'TNimType* $1;$n', [name]);
|
// compute type flags for GC optimization
|
||||||
|
flags := 0;
|
||||||
|
if not containsGarbageCollectedRef(typ) then flags := flags or 1;
|
||||||
|
if not canFormAcycle(typ) then flags := flags or 2;
|
||||||
|
//else MessageOut('can contain a cycle: ' + typeToString(typ));
|
||||||
|
if flags <> 0 then
|
||||||
|
appf(m.s[cfsTypeInit3], '$1->flags = $2;$n', [name, toRope(flags)]);
|
||||||
|
appf(m.s[cfsVars], 'TNimType* $1; /* $2 */$n',
|
||||||
|
[name, toRope(typeToString(typ))]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure genTypeInfoAux(m: BModule; typ: PType; name: PRope);
|
procedure genTypeInfoAux(m: BModule; typ: PType; name: PRope);
|
||||||
|
|
@ -643,10 +712,8 @@ begin
|
||||||
appf(m.s[cfsTypeInit1], 'static TNimNode* $1[$2];$n',
|
appf(m.s[cfsTypeInit1], 'static TNimNode* $1[$2];$n',
|
||||||
[tmp, toRope(len)]);
|
[tmp, toRope(len)]);
|
||||||
for i := 0 to len-1 do begin
|
for i := 0 to len-1 do begin
|
||||||
tmp2 := getTempName();
|
tmp2 := getNimNode(m);
|
||||||
appf(m.s[cfsTypeInit1], 'static TNimNode $1;$n', [tmp2]);
|
appf(m.s[cfsTypeInit3], '$1[$2] = &$3;$n', [tmp, toRope(i), tmp2]);
|
||||||
appf(m.s[cfsTypeInit3], '$1[$2] = &$3;$n',
|
|
||||||
[tmp, toRope(i), tmp2]);
|
|
||||||
genObjectFields(m, typ, n.sons[i], tmp2);
|
genObjectFields(m, typ, n.sons[i], tmp2);
|
||||||
end;
|
end;
|
||||||
appf(m.s[cfsTypeInit3],
|
appf(m.s[cfsTypeInit3],
|
||||||
|
|
@ -676,10 +743,8 @@ begin
|
||||||
[tmp, toRope(lengthOrd(field.typ)+1)]);
|
[tmp, toRope(lengthOrd(field.typ)+1)]);
|
||||||
for i := 1 to len-1 do begin
|
for i := 1 to len-1 do begin
|
||||||
b := n.sons[i]; // branch
|
b := n.sons[i]; // branch
|
||||||
tmp2 := getTempName();
|
tmp2 := getNimNode(m);
|
||||||
appf(m.s[cfsTypeInit1], 'static TNimNode $1;$n', [tmp2]);
|
|
||||||
genObjectFields(m, typ, lastSon(b), tmp2);
|
genObjectFields(m, typ, lastSon(b), tmp2);
|
||||||
//writeln(output, renderTree(b.sons[j]));
|
|
||||||
case b.kind of
|
case b.kind of
|
||||||
nkOfBranch: begin
|
nkOfBranch: begin
|
||||||
if sonsLen(b) < 2 then
|
if sonsLen(b) < 2 then
|
||||||
|
|
@ -728,42 +793,54 @@ var
|
||||||
begin
|
begin
|
||||||
if typ.kind = tyObject then genTypeInfoAux(m, typ, name)
|
if typ.kind = tyObject then genTypeInfoAux(m, typ, name)
|
||||||
else genTypeInfoAuxBase(m, typ, name, toRope('0'+''));
|
else genTypeInfoAuxBase(m, typ, name, toRope('0'+''));
|
||||||
tmp := getTempName();
|
tmp := getNimNode(m);
|
||||||
appf(m.s[cfsTypeInit1], 'static TNimNode $1;$n', [tmp]);
|
|
||||||
genObjectFields(m, typ, typ.n, tmp);
|
genObjectFields(m, typ, typ.n, tmp);
|
||||||
appf(m.s[cfsTypeInit3], '$1->node = &$2;$n', [name, tmp]);
|
appf(m.s[cfsTypeInit3], '$1->node = &$2;$n', [name, tmp]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure genEnumInfo(m: BModule; typ: PType; name: PRope);
|
procedure genEnumInfo(m: BModule; typ: PType; name: PRope);
|
||||||
var
|
var
|
||||||
tmp, tmp2, tmp3: PRope;
|
nodePtrs, elemNode, enumNames, enumArray, counter, specialCases: PRope;
|
||||||
len, i: int;
|
len, i, firstNimNode: int;
|
||||||
field: PSym;
|
field: PSym;
|
||||||
begin
|
begin
|
||||||
|
// Type information for enumerations is quite heavy, so we do some
|
||||||
|
// optimizations here: The ``typ`` field is never set, as it is redundant
|
||||||
|
// anyway. We generate a cstring array and a loop over it. Exceptional
|
||||||
|
// positions will be reset after the loop.
|
||||||
genTypeInfoAux(m, typ, name);
|
genTypeInfoAux(m, typ, name);
|
||||||
tmp := getTempName();
|
nodePtrs := getTempName();
|
||||||
tmp2 := getTempName();
|
|
||||||
len := sonsLen(typ.n);
|
len := sonsLen(typ.n);
|
||||||
appf(m.s[cfsTypeInit1], 'static TNimNode* $1[$2];$n' +
|
appf(m.s[cfsTypeInit1], 'static TNimNode* $1[$2];$n', [nodePtrs, toRope(len)]);
|
||||||
'static TNimNode $3;$n',
|
enumNames := nil;
|
||||||
[tmp, toRope(len), tmp2]);
|
specialCases := nil;
|
||||||
|
firstNimNode := m.typeNodes;
|
||||||
for i := 0 to len-1 do begin
|
for i := 0 to len-1 do begin
|
||||||
assert(typ.n.sons[i].kind = nkSym);
|
assert(typ.n.sons[i].kind = nkSym);
|
||||||
field := typ.n.sons[i].sym;
|
field := typ.n.sons[i].sym;
|
||||||
tmp3 := getTempName();
|
elemNode := getNimNode(m);
|
||||||
appf(m.s[cfsTypeInit1], 'static TNimNode $1;$n', [tmp3]);
|
app(enumNames, makeCString(field.name.s));
|
||||||
appf(m.s[cfsTypeInit3], '$1[$2] = &$3;$n' +
|
if i < len-1 then app(enumNames, ', '+tnl);
|
||||||
'$3.kind = 1;$n' +
|
if field.position <> i then
|
||||||
'$3.offset = $4;$n' +
|
appf(specialCases, '$1.offset = $2;$n', [elemNode, toRope(field.position)]);
|
||||||
'$3.typ = $5;$n' +
|
|
||||||
'$3.name = $6;$n',
|
|
||||||
[tmp, toRope(i), tmp3,
|
|
||||||
toRope(field.position),
|
|
||||||
name, makeCString(field.name.s)]);
|
|
||||||
end;
|
end;
|
||||||
|
enumArray := getTempName();
|
||||||
|
counter := getTempName();
|
||||||
|
appf(m.s[cfsTypeInit1], 'NI $1;$n', [counter]);
|
||||||
|
appf(m.s[cfsTypeInit1], 'static char* NIM_CONST $1[$2] = {$n$3};$n',
|
||||||
|
[enumArray, toRope(len), enumNames]);
|
||||||
|
appf(m.s[cfsTypeInit3], 'for ($1 = 0; $1 < $2; $1++) {$n' +
|
||||||
|
'$3[$1+$4].kind = 1;$n' +
|
||||||
|
'$3[$1+$4].offset = $1;$n' +
|
||||||
|
'$3[$1+$4].name = $5[$1];$n' +
|
||||||
|
'$6[$1] = &$3[$1+$4];$n' +
|
||||||
|
'}$n',
|
||||||
|
[counter, toRope(len), m.typeNodesName, toRope(firstNimNode),
|
||||||
|
enumArray, nodePtrs]);
|
||||||
|
app(m.s[cfsTypeInit3], specialCases);
|
||||||
appf(m.s[cfsTypeInit3],
|
appf(m.s[cfsTypeInit3],
|
||||||
'$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n$4->node = &$1;$n', [
|
'$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n$4->node = &$1;$n', [
|
||||||
tmp2, toRope(len), tmp, name]);
|
getNimNode(m), toRope(len), nodePtrs, name]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure genSetInfo(m: BModule; typ: PType; name: PRope);
|
procedure genSetInfo(m: BModule; typ: PType; name: PRope);
|
||||||
|
|
@ -772,8 +849,7 @@ var
|
||||||
begin
|
begin
|
||||||
assert(typ.sons[0] <> nil);
|
assert(typ.sons[0] <> nil);
|
||||||
genTypeInfoAux(m, typ, name);
|
genTypeInfoAux(m, typ, name);
|
||||||
tmp := getTempName();
|
tmp := getNimNode(m);
|
||||||
appf(m.s[cfsTypeInit1], 'static TNimNode $1;$n', [tmp]);
|
|
||||||
appf(m.s[cfsTypeInit3],
|
appf(m.s[cfsTypeInit3],
|
||||||
'$1.len = $2; $1.kind = 0;$n' +
|
'$1.len = $2; $1.kind = 0;$n' +
|
||||||
'$3->node = &$1;$n', [tmp, toRope(firstOrd(typ)), name]);
|
'$3->node = &$1;$n', [tmp, toRope(firstOrd(typ)), name]);
|
||||||
|
|
@ -784,28 +860,96 @@ begin
|
||||||
genTypeInfoAuxBase(m, typ, name, genTypeInfo(m, typ.sons[1]));
|
genTypeInfoAuxBase(m, typ, name, genTypeInfo(m, typ.sons[1]));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
gToTypeInfoId: TIiTable;
|
||||||
|
|
||||||
|
(* // this does not work any longer thanks to separate compilation:
|
||||||
|
function getTypeInfoName(t: PType): PRope;
|
||||||
|
begin
|
||||||
|
result := ropef('NTI$1', [toRope(t.id)]);
|
||||||
|
end;*)
|
||||||
|
|
||||||
function genTypeInfo(m: BModule; typ: PType): PRope;
|
function genTypeInfo(m: BModule; typ: PType): PRope;
|
||||||
var
|
var
|
||||||
t: PType;
|
t: PType;
|
||||||
|
id: int;
|
||||||
|
dataGen: bool;
|
||||||
begin
|
begin
|
||||||
t := getUniqueType(typ);
|
t := getUniqueType(typ);
|
||||||
result := ropef('NTI$1', [toRope(t.id)]);
|
id := IiTableGet(gToTypeInfoId, t.id);
|
||||||
|
if id = invalidKey then begin
|
||||||
|
dataGen := false;
|
||||||
|
case t.kind of
|
||||||
|
tyEnum, tyBool: begin
|
||||||
|
id := t.id;
|
||||||
|
dataGen := true
|
||||||
|
end;
|
||||||
|
tyObject: begin
|
||||||
|
if sfPure in t.sym.flags then
|
||||||
|
id := getID()
|
||||||
|
else begin
|
||||||
|
id := t.id;
|
||||||
|
dataGen := true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
id := getID();
|
||||||
|
end;
|
||||||
|
IiTablePut(gToTypeInfoId, t.id, id);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
dataGen := true;
|
||||||
|
result := ropef('NTI$1', [toRope(id)]);
|
||||||
if not IntSetContainsOrIncl(m.typeInfoMarker, t.id) then begin
|
if not IntSetContainsOrIncl(m.typeInfoMarker, t.id) then begin
|
||||||
// declare type information structures:
|
// declare type information structures:
|
||||||
useMagic(m, 'TNimType');
|
useMagic(m, 'TNimType');
|
||||||
useMagic(m, 'TNimNode');
|
useMagic(m, 'TNimNode');
|
||||||
appf(m.s[cfsVars], 'extern TNimType* $1;$n', [result]);
|
if dataGen then
|
||||||
|
appf(m.s[cfsVars], 'extern TNimType* $1; /* $2 */$n',
|
||||||
|
[result, toRope(typeToString(t))]);
|
||||||
end;
|
end;
|
||||||
if IntSetContainsOrIncl(gTypeInfoGenerated, t.id) then exit;
|
if dataGen then exit;
|
||||||
case t.kind of
|
case t.kind of
|
||||||
tyPointer, tyProc, tyBool, tyChar, tyCString, tyString, tyInt..tyFloat128:
|
tyPointer, tyProc, tyBool, tyChar, tyCString, tyString,
|
||||||
|
tyInt..tyFloat128, tyVar:
|
||||||
genTypeInfoAuxBase(m, t, result, toRope('0'+''));
|
genTypeInfoAuxBase(m, t, result, toRope('0'+''));
|
||||||
tyRef, tyPtr, tySequence, tyRange: genTypeInfoAux(m, t, result);
|
tyRef, tyPtr, tySequence, tyRange: genTypeInfoAux(m, t, result);
|
||||||
tyArrayConstr, tyArray: genArrayInfo(m, t, result);
|
tyArrayConstr, tyArray: genArrayInfo(m, t, result);
|
||||||
tySet: genSetInfo(m, t, result);
|
tySet: genSetInfo(m, t, result);
|
||||||
tyEnum: genEnumInfo(m, t, result);
|
tyEnum: genEnumInfo(m, t, result);
|
||||||
tyObject, tyTuple: genObjectInfo(m, t, result);
|
tyObject, tyTuple: genObjectInfo(m, t, result);
|
||||||
tyVar: result := genTypeInfo(m, typ.sons[0]);
|
|
||||||
else InternalError('genTypeInfo(' + typekindToStr[t.kind] + ')');
|
else InternalError('genTypeInfo(' + typekindToStr[t.kind] + ')');
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure genTypeSection(m: BModule; n: PNode);
|
||||||
|
var
|
||||||
|
i: int;
|
||||||
|
a: PNode;
|
||||||
|
t: PType;
|
||||||
|
begin
|
||||||
|
for i := 0 to sonsLen(n)-1 do begin
|
||||||
|
a := n.sons[i];
|
||||||
|
if a.kind = nkCommentStmt then continue;
|
||||||
|
if (a.sons[0].kind <> nkSym) then InternalError(a.info, 'genTypeSection');
|
||||||
|
t := a.sons[0].sym.typ;
|
||||||
|
if (a.sons[2] = nil)
|
||||||
|
or not (a.sons[2].kind in [nkSym, nkIdent, nkAccQuoted]) then
|
||||||
|
if t <> nil then
|
||||||
|
case t.kind of
|
||||||
|
tyEnum, tyBool: begin
|
||||||
|
useMagic(m, 'TNimType');
|
||||||
|
useMagic(m, 'TNimNode');
|
||||||
|
genEnumInfo(m, t, ropef('NTI$1', [toRope(t.id)]));
|
||||||
|
end;
|
||||||
|
tyObject: begin
|
||||||
|
if not (sfPure in t.sym.flags) then begin
|
||||||
|
useMagic(m, 'TNimType');
|
||||||
|
useMagic(m, 'TNimNode');
|
||||||
|
genObjectInfo(m, t, ropef('NTI$1', [toRope(t.id)]));
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else begin end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@
|
||||||
// See the file "copying.txt", included in this
|
// See the file "copying.txt", included in this
|
||||||
// distribution, for details about the copyright.
|
// distribution, for details about the copyright.
|
||||||
//
|
//
|
||||||
|
|
||||||
unit ccgutils;
|
unit ccgutils;
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
@ -35,21 +34,28 @@ var
|
||||||
t: PType;
|
t: PType;
|
||||||
h: THash;
|
h: THash;
|
||||||
begin
|
begin
|
||||||
|
// this was a hotspot in the compiler!
|
||||||
result := key;
|
result := key;
|
||||||
if key = nil then exit;
|
if key = nil then exit;
|
||||||
assert(key.kind <> tyForward);
|
case key.Kind of
|
||||||
if key.kind = tyGenericInst then begin
|
tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString,
|
||||||
result := GetUniqueType(lastSon(key));
|
tyInt..tyFloat128, tyProc, tyEnum, tyObject, tyAnyEnum: begin end;
|
||||||
exit
|
tyNone, tyForward:
|
||||||
end;
|
InternalError('GetUniqueType: ' + typeToString(key));
|
||||||
if IdTableHasObjectAsKey(gTypeTable, key) then exit;
|
tyGenericParam, tyGeneric, tySequence,
|
||||||
|
tyOpenArray, tySet, tyVar, tyRef, tyPtr, tyArrayConstr,
|
||||||
|
tyArray, tyTuple, tyRange: begin
|
||||||
// we have to do a slow linear search because types may need
|
// we have to do a slow linear search because types may need
|
||||||
// to be compared by their structure:
|
// to be compared by their structure:
|
||||||
|
if IdTableHasObjectAsKey(gTypeTable, key) then exit;
|
||||||
for h := 0 to high(gTypeTable.data) do begin
|
for h := 0 to high(gTypeTable.data) do begin
|
||||||
t := PType(gTypeTable.data[h].key);
|
t := PType(gTypeTable.data[h].key);
|
||||||
if (t <> nil) and sameType(t, key) then begin result := t; exit end
|
if (t <> nil) and sameType(t, key) then begin result := t; exit end
|
||||||
end;
|
end;
|
||||||
IdTablePut(gTypeTable, key, key);
|
IdTablePut(gTypeTable, key, key);
|
||||||
|
end;
|
||||||
|
tyGenericInst: result := GetUniqueType(lastSon(key));
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TableGetType(const tab: TIdTable; key: PType): PObject;
|
function TableGetType(const tab: TIdTable; key: PType): PObject;
|
||||||
|
|
@ -102,7 +108,7 @@ begin
|
||||||
end;
|
end;
|
||||||
res := res +{&} toCChar(s[i]);
|
res := res +{&} toCChar(s[i]);
|
||||||
end;
|
end;
|
||||||
res := res +{&} '"'+'';
|
addChar(res, '"');
|
||||||
app(result, toRope(res));
|
app(result, toRope(res));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
|
||||||
243
nim/cgen.pas
243
nim/cgen.pas
|
|
@ -6,7 +6,6 @@
|
||||||
// See the file "copying.txt", included in this
|
// See the file "copying.txt", included in this
|
||||||
// distribution, for details about the copyright.
|
// distribution, for details about the copyright.
|
||||||
//
|
//
|
||||||
|
|
||||||
unit cgen;
|
unit cgen;
|
||||||
|
|
||||||
// This is the new C code generator; much cleaner and faster
|
// This is the new C code generator; much cleaner and faster
|
||||||
|
|
@ -19,10 +18,10 @@ interface
|
||||||
uses
|
uses
|
||||||
nsystem, ast, astalgo, strutils, hashes, trees, platform, magicsys,
|
nsystem, ast, astalgo, strutils, hashes, trees, platform, magicsys,
|
||||||
extccomp, options, nversion, nimsets, msgs, crc, bitsets, idents,
|
extccomp, options, nversion, nimsets, msgs, crc, bitsets, idents,
|
||||||
lists, types, ccgutils, nos, ntime, ropes, nmath, backends,
|
lists, types, ccgutils, nos, ntime, ropes, nmath, passes, rodread,
|
||||||
wordrecg, rnimsyn;
|
wordrecg, rnimsyn, treetab;
|
||||||
|
|
||||||
function CBackend(b: PBackend; module: PSym; const filename: string): PBackend;
|
function cgenPass(): TPass;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
|
@ -95,7 +94,6 @@ type
|
||||||
// (the vars must be volatile then)
|
// (the vars must be volatile then)
|
||||||
labels: Natural; // for generating unique labels in the C proc
|
labels: Natural; // for generating unique labels in the C proc
|
||||||
blocks: array of TBlock; // nested blocks
|
blocks: array of TBlock; // nested blocks
|
||||||
locals: array of TLoc; // locNone means slot is free again
|
|
||||||
options: TOptions; // options that should be used for code
|
options: TOptions; // options that should be used for code
|
||||||
// generation; this is the same as prc.options
|
// generation; this is the same as prc.options
|
||||||
// unless prc == nil
|
// unless prc == nil
|
||||||
|
|
@ -105,7 +103,9 @@ type
|
||||||
module: BModule; // used to prevent excessive parameter passing
|
module: BModule; // used to prevent excessive parameter passing
|
||||||
end;
|
end;
|
||||||
TTypeSeq = array of PType;
|
TTypeSeq = array of PType;
|
||||||
TCGen = object(TBackend) // represents a C source file
|
TCGen = object(TPassContext) // represents a C source file
|
||||||
|
module: PSym;
|
||||||
|
filename: string;
|
||||||
s: TCFileSections; // sections of the C file
|
s: TCFileSections; // sections of the C file
|
||||||
cfilename: string; // filename of the module (including path,
|
cfilename: string; // filename of the module (including path,
|
||||||
// without extension)
|
// without extension)
|
||||||
|
|
@ -114,18 +114,21 @@ type
|
||||||
declaredThings: TIntSet; // things we have declared in this .c file
|
declaredThings: TIntSet; // things we have declared in this .c file
|
||||||
debugDeclared: TIntSet; // for debugging purposes
|
debugDeclared: TIntSet; // for debugging purposes
|
||||||
headerFiles: TLinkedList; // needed headers to include
|
headerFiles: TLinkedList; // needed headers to include
|
||||||
//unique: Natural; // for generating unique names
|
|
||||||
typeInfoMarker: TIntSet; // needed for generating type information
|
typeInfoMarker: TIntSet; // needed for generating type information
|
||||||
initProc: BProc; // code for init procedure
|
initProc: BProc; // code for init procedure
|
||||||
typeStack: TTypeSeq; // used for type generation
|
typeStack: TTypeSeq; // used for type generation
|
||||||
|
dataCache: TNodeTable;
|
||||||
|
typeNodes, nimTypes: int;// used for type info generation
|
||||||
|
typeNodesName, nimTypesName: PRope; // used for type info generation
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
gUnique: Natural;
|
|
||||||
mainModProcs, mainModInit: PRope; // parts of the main module
|
mainModProcs, mainModInit: PRope; // parts of the main module
|
||||||
gMapping: PRope; // the generated mapping file (if requested)
|
gMapping: PRope; // the generated mapping file (if requested)
|
||||||
|
gProcProfile: Natural; // proc profile counter
|
||||||
|
|
||||||
function initLoc(k: TLocKind; typ: PType; s: TStorageLoc): TLoc;
|
|
||||||
|
procedure initLoc(var result: TLoc; k: TLocKind; typ: PType; s: TStorageLoc);
|
||||||
begin
|
begin
|
||||||
result.k := k;
|
result.k := k;
|
||||||
result.s := s;
|
result.s := s;
|
||||||
|
|
@ -162,11 +165,8 @@ begin
|
||||||
result.options := gOptions;
|
result.options := gOptions;
|
||||||
{@ignore}
|
{@ignore}
|
||||||
setLength(result.blocks, 0);
|
setLength(result.blocks, 0);
|
||||||
setLength(result.locals, 0);
|
|
||||||
{@emit
|
{@emit
|
||||||
result.blocks := [];}
|
result.blocks := @[];}
|
||||||
{@emit
|
|
||||||
result.locals := [];}
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function isSimpleConst(typ: PType): bool;
|
function isSimpleConst(typ: PType): bool;
|
||||||
|
|
@ -179,15 +179,12 @@ procedure useHeader(m: BModule; sym: PSym);
|
||||||
begin
|
begin
|
||||||
if lfHeader in sym.loc.Flags then begin
|
if lfHeader in sym.loc.Flags then begin
|
||||||
assert(sym.annex <> nil);
|
assert(sym.annex <> nil);
|
||||||
{@discard} lists.IncludeStr(m.headerFiles, PLib(sym.annex).path)
|
{@discard} lists.IncludeStr(m.headerFiles, sym.annex.path)
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure UseMagic(m: BModule; const name: string); forward;
|
procedure UseMagic(m: BModule; const name: string); forward;
|
||||||
|
|
||||||
// ----------------------------- name mangling
|
|
||||||
// +++++++++++++++++++++++++++++ type generation
|
|
||||||
// +++++++++++++++++++++++++++++ type info generation
|
|
||||||
{$include 'ccgtypes.pas'}
|
{$include 'ccgtypes.pas'}
|
||||||
|
|
||||||
// ------------------------------ Manager of temporaries ------------------
|
// ------------------------------ Manager of temporaries ------------------
|
||||||
|
|
@ -198,41 +195,20 @@ begin
|
||||||
result := sameType(skipGenericRange(a), skipGenericRange(b))
|
result := sameType(skipGenericRange(a), skipGenericRange(b))
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function getTemp(p: BProc; t: PType): TLoc;
|
procedure getTemp(p: BProc; t: PType; var result: TLoc);
|
||||||
var
|
begin
|
||||||
i, index: int;
|
inc(p.labels);
|
||||||
name: PRope;
|
result.r := con('LOC', toRope(p.labels));
|
||||||
begin (*
|
appf(p.s[cpsLocals], '$1 $2;$n', [getTypeDesc(p.module, t), result.r]);
|
||||||
for i := 0 to high(p.locals) do begin
|
result.k := locTemp;
|
||||||
assert(i = p.locals[i].a);
|
result.a := -1;
|
||||||
if (p.locals[i].k = locNone) and beEqualTypes(p.locals[i].t, t) then begin
|
result.t := getUniqueType(t);
|
||||||
// free slot of the appropriate type?
|
result.s := OnStack;
|
||||||
p.locals[i].k := locTemp; // is filled again
|
result.flags := {@set}[];
|
||||||
result := p.locals[i];
|
|
||||||
exit
|
|
||||||
end
|
|
||||||
end; *)
|
|
||||||
// not found:
|
|
||||||
index := length(p.locals);
|
|
||||||
setLength(p.locals, index+1);
|
|
||||||
// declare the new temporary:
|
|
||||||
name := con('Loc', toRope(index));
|
|
||||||
appf(p.s[cpsLocals], '$1 $2; /* temporary */$n',
|
|
||||||
[getTypeDesc(p.module, t), name]);
|
|
||||||
p.locals[index].k := locTemp;
|
|
||||||
p.locals[index].a := index;
|
|
||||||
p.locals[index].r := name;
|
|
||||||
p.locals[index].t := getUniqueType(t);
|
|
||||||
p.locals[index].s := OnStack;
|
|
||||||
p.locals[index].flags := {@set}[];
|
|
||||||
result := p.locals[index] // BUGFIX!
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure freeTemp(p: BProc; const temp: TLoc);
|
procedure freeTemp(p: BProc; const temp: TLoc);
|
||||||
begin (*
|
begin
|
||||||
if (temp.a >= 0) and (temp.a < length(p.locals)) and
|
|
||||||
(p.locals[temp.a].k = locTemp) then
|
|
||||||
p.locals[temp.a].k := locNone *)
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// -------------------------- Variable manager ----------------------------
|
// -------------------------- Variable manager ----------------------------
|
||||||
|
|
@ -245,6 +221,8 @@ begin
|
||||||
app(m.s[cfsVars], ' register');
|
app(m.s[cfsVars], ' register');
|
||||||
if sfVolatile in s.flags then
|
if sfVolatile in s.flags then
|
||||||
app(m.s[cfsVars], ' volatile');
|
app(m.s[cfsVars], ' volatile');
|
||||||
|
if sfThreadVar in s.flags then
|
||||||
|
app(m.s[cfsVars], ' NIM_THREADVAR');
|
||||||
appf(m.s[cfsVars], ' $1;$n', [s.loc.r])
|
appf(m.s[cfsVars], ' $1;$n', [s.loc.r])
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
@ -314,7 +292,7 @@ end;
|
||||||
function getLabel(p: BProc): TLabel;
|
function getLabel(p: BProc): TLabel;
|
||||||
begin
|
begin
|
||||||
inc(p.labels);
|
inc(p.labels);
|
||||||
result := con('L'+'', toRope(p.labels))
|
result := con('LA', toRope(p.labels))
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure fixLabel(p: BProc; labl: TLabel);
|
procedure fixLabel(p: BProc; labl: TLabel);
|
||||||
|
|
@ -344,10 +322,11 @@ begin
|
||||||
lib.kind := libDynamicGenerated;
|
lib.kind := libDynamicGenerated;
|
||||||
useMagic(m, 'nimLoadLibrary');
|
useMagic(m, 'nimLoadLibrary');
|
||||||
useMagic(m, 'nimUnloadLibrary');
|
useMagic(m, 'nimUnloadLibrary');
|
||||||
|
useMagic(m, 'NimStringDesc');
|
||||||
tmp := getTempName();
|
tmp := getTempName();
|
||||||
appf(m.s[cfsVars], 'static void* $1;$n', [tmp]);
|
appf(m.s[cfsVars], 'static void* $1;$n', [tmp]);
|
||||||
appf(m.s[cfsDynLibInit],
|
appf(m.s[cfsDynLibInit],
|
||||||
'$1 = nimLoadLibrary((string) &$2);$n',
|
'$1 = nimLoadLibrary((NimStringDesc*) &$2);$n',
|
||||||
[tmp, getStrLit(m, lib.path)]);
|
[tmp, getStrLit(m, lib.path)]);
|
||||||
appf(m.s[cfsDynLibDeinit],
|
appf(m.s[cfsDynLibDeinit],
|
||||||
'if ($1 != NIM_NIL) nimUnloadLibrary($1);$n', [tmp]);
|
'if ($1 != NIM_NIL) nimUnloadLibrary($1);$n', [tmp]);
|
||||||
|
|
@ -361,7 +340,7 @@ var
|
||||||
lib: PLib;
|
lib: PLib;
|
||||||
extname, tmp: PRope;
|
extname, tmp: PRope;
|
||||||
begin
|
begin
|
||||||
lib := PLib(sym.annex);
|
lib := sym.annex;
|
||||||
extname := sym.loc.r;
|
extname := sym.loc.r;
|
||||||
loadDynamicLib(m, lib);
|
loadDynamicLib(m, lib);
|
||||||
useMagic(m, 'nimGetProcAddr');
|
useMagic(m, 'nimGetProcAddr');
|
||||||
|
|
@ -434,7 +413,7 @@ procedure genProc(m: BModule; prc: PSym);
|
||||||
var
|
var
|
||||||
p: BProc;
|
p: BProc;
|
||||||
generatedProc, header, returnStmt: PRope;
|
generatedProc, header, returnStmt: PRope;
|
||||||
i: int;
|
i, profileId: int;
|
||||||
res, param: PSym;
|
res, param: PSym;
|
||||||
begin
|
begin
|
||||||
useHeader(m, prc);
|
useHeader(m, prc);
|
||||||
|
|
@ -454,21 +433,20 @@ begin
|
||||||
returnStmt := nil;
|
returnStmt := nil;
|
||||||
assert(prc.ast <> nil);
|
assert(prc.ast <> nil);
|
||||||
|
|
||||||
if not (sfPure in prc.flags) then begin
|
if not (sfPure in prc.flags) and (prc.typ.sons[0] <> nil) then begin
|
||||||
if not isInvalidReturnType(prc.typ.sons[0]) then begin
|
|
||||||
res := prc.ast.sons[resultPos].sym; // get result symbol
|
res := prc.ast.sons[resultPos].sym; // get result symbol
|
||||||
|
if not isInvalidReturnType(prc.typ.sons[0]) then begin
|
||||||
// declare the result symbol:
|
// declare the result symbol:
|
||||||
assignLocalVar(p, res);
|
assignLocalVar(p, res);
|
||||||
assert(res.loc.r <> nil);
|
assert(res.loc.r <> nil);
|
||||||
initVariable(p, res);
|
|
||||||
genObjectInit(p, res);
|
|
||||||
returnStmt := ropef('return $1;$n', [rdLoc(res.loc)]);
|
returnStmt := ropef('return $1;$n', [rdLoc(res.loc)]);
|
||||||
end
|
end
|
||||||
else if (prc.typ.sons[0] <> nil) then begin
|
else begin
|
||||||
res := prc.ast.sons[resultPos].sym; // get result symbol
|
|
||||||
fillResult(res);
|
fillResult(res);
|
||||||
assignParam(p, res)
|
assignParam(p, res);
|
||||||
end
|
end;
|
||||||
|
initVariable(p, res);
|
||||||
|
genObjectInit(p, res.typ, res.loc, true);
|
||||||
end;
|
end;
|
||||||
for i := 1 to sonsLen(prc.typ.n)-1 do begin
|
for i := 1 to sonsLen(prc.typ.n)-1 do begin
|
||||||
param := prc.typ.n.sons[i].sym;
|
param := prc.typ.n.sons[i].sym;
|
||||||
|
|
@ -492,16 +470,31 @@ begin
|
||||||
[makeCString(prc.owner.name.s +{&} '.' +{&} prc.name.s),
|
[makeCString(prc.owner.name.s +{&} '.' +{&} prc.name.s),
|
||||||
makeCString(toFilename(prc.info))]));
|
makeCString(toFilename(prc.info))]));
|
||||||
end;
|
end;
|
||||||
|
if optProfiler in prc.options then begin
|
||||||
|
if gProcProfile >= 64*1024 then // XXX: hard coded value!
|
||||||
|
InternalError(prc.info, 'too many procedures for profiling');
|
||||||
|
useMagic(m, 'profileData');
|
||||||
|
app(p.s[cpsLocals], 'ticks NIM_profilingStart;'+tnl);
|
||||||
|
if prc.loc.a < 0 then begin
|
||||||
|
appf(m.s[cfsDebugInit], 'profileData[$1].procname = $2;$n',
|
||||||
|
[toRope(gProcProfile),
|
||||||
|
makeCString(prc.owner.name.s +{&} '.' +{&} prc.name.s)]);
|
||||||
|
prc.loc.a := gProcProfile;
|
||||||
|
inc(gProcProfile);
|
||||||
|
end;
|
||||||
|
prepend(p.s[cpsInit], toRope('NIM_profilingStart = getticks();' + tnl));
|
||||||
|
end;
|
||||||
app(generatedProc, con(p.s));
|
app(generatedProc, con(p.s));
|
||||||
if p.beforeRetNeeded then
|
if p.beforeRetNeeded then
|
||||||
app(generatedProc, 'BeforeRet: ;' + tnl);
|
app(generatedProc, 'BeforeRet: ;' + tnl);
|
||||||
if optStackTrace in prc.options then
|
if optStackTrace in prc.options then
|
||||||
app(generatedProc, 'framePtr = framePtr->prev;' + tnl);
|
app(generatedProc, 'framePtr = framePtr->prev;' + tnl);
|
||||||
|
if optProfiler in prc.options then
|
||||||
|
appf(generatedProc,
|
||||||
|
'profileData[$1].total += elapsed(getticks(), NIM_profilingStart);$n',
|
||||||
|
[toRope(prc.loc.a)]);
|
||||||
app(generatedProc, returnStmt);
|
app(generatedProc, returnStmt);
|
||||||
app(generatedProc, '}' + tnl);
|
app(generatedProc, '}' + tnl);
|
||||||
// only now we can free the syntax tree:
|
|
||||||
//if prc.typ.callConv <> ccInline then
|
|
||||||
// prc.ast.sons[codePos] := nil;
|
|
||||||
end;
|
end;
|
||||||
app(m.s[cfsProcs], generatedProc);
|
app(m.s[cfsProcs], generatedProc);
|
||||||
end
|
end
|
||||||
|
|
@ -524,6 +517,8 @@ begin
|
||||||
app(m.s[cfsVars], ' register');
|
app(m.s[cfsVars], ' register');
|
||||||
if sfVolatile in sym.flags then
|
if sfVolatile in sym.flags then
|
||||||
app(m.s[cfsVars], ' volatile');
|
app(m.s[cfsVars], ' volatile');
|
||||||
|
if sfThreadVar in sym.flags then
|
||||||
|
app(m.s[cfsVars], ' NIM_THREADVAR');
|
||||||
appf(m.s[cfsVars], ' $1;$n', [sym.loc.r])
|
appf(m.s[cfsVars], ' $1;$n', [sym.loc.r])
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
@ -572,6 +567,12 @@ end;
|
||||||
|
|
||||||
function getFileHeader(const cfilenoext: string): PRope;
|
function getFileHeader(const cfilenoext: string): PRope;
|
||||||
begin
|
begin
|
||||||
|
if optCompileOnly in gGlobalOptions then
|
||||||
|
result := ropef(
|
||||||
|
'/* Generated by the Nimrod Compiler v$1 */$n' +
|
||||||
|
'/* (c) 2008 Andreas Rumpf */$n',
|
||||||
|
[toRope(versionAsString)])
|
||||||
|
else
|
||||||
result := ropef(
|
result := ropef(
|
||||||
'/* Generated by the Nimrod Compiler v$1 */$n' +
|
'/* Generated by the Nimrod Compiler v$1 */$n' +
|
||||||
'/* (c) 2008 Andreas Rumpf */$n' +
|
'/* (c) 2008 Andreas Rumpf */$n' +
|
||||||
|
|
@ -645,18 +646,43 @@ begin
|
||||||
appf(m.s[cfsProcs], frmt, [gBreakpoints, mainModInit])
|
appf(m.s[cfsProcs], frmt, [gBreakpoints, mainModInit])
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function getInitName(m: PSym): PRope;
|
||||||
|
begin
|
||||||
|
result := con(m.name.s, toRope('Init'));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure registerModuleToMain(m: PSym);
|
||||||
|
var
|
||||||
|
initname: PRope;
|
||||||
|
begin
|
||||||
|
initname := getInitName(m);
|
||||||
|
appf(mainModProcs, 'N_NOINLINE(void, $1)(void);$n',
|
||||||
|
[initname]);
|
||||||
|
if not (sfSystemModule in m.flags) then
|
||||||
|
appf(mainModInit, '$1();$n', [initname]);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure genInitCode(m: BModule);
|
procedure genInitCode(m: BModule);
|
||||||
var
|
var
|
||||||
initname, prc: PRope;
|
initname, prc: PRope;
|
||||||
begin
|
begin
|
||||||
initname := con(m.module.name.s, toRope('Init'));
|
if optProfiler in m.initProc.options then begin
|
||||||
appf(mainModProcs, 'N_NIMCALL(void, $1)(void);$n',
|
// This does not really belong here, but there is no good place for this
|
||||||
[initname]);
|
// code. I don't want to put this to the proc generation as the
|
||||||
if not (sfSystemModule in m.module.flags) then
|
// ``IncludeStr`` call is quite slow.
|
||||||
appf(mainModInit, '$1();$n', [initname]);
|
{@discard} lists.IncludeStr(m.headerFiles, '<cycle.h>');
|
||||||
prc := ropef('N_NIMCALL(void, $1)(void) {$n', [initname]);
|
end;
|
||||||
|
initname := getInitName(m.module);
|
||||||
|
registerModuleToMain(m.module);
|
||||||
|
prc := ropef('N_NOINLINE(void, $1)(void) {$n', [initname]);
|
||||||
|
if m.typeNodes > 0 then
|
||||||
|
appf(m.s[cfsTypeInit1], 'static TNimNode $1[$2];$n',
|
||||||
|
[m.typeNodesName, toRope(m.typeNodes)]);
|
||||||
|
if m.nimTypes > 0 then
|
||||||
|
appf(m.s[cfsTypeInit1], 'static TNimType $1[$2];$n',
|
||||||
|
[m.nimTypesName, toRope(m.nimTypes)]);
|
||||||
if optStackTrace in m.initProc.options then begin
|
if optStackTrace in m.initProc.options then begin
|
||||||
prepend(m.initProc.s[cpsLocals], toRope('volatile TFrame F;' + tnl));
|
getFrameDecl(m.initProc);
|
||||||
app(prc, m.initProc.s[cpsLocals]);
|
app(prc, m.initProc.s[cpsLocals]);
|
||||||
app(prc, m.s[cfsTypeInit1]);
|
app(prc, m.s[cfsTypeInit1]);
|
||||||
appf(prc,
|
appf(prc,
|
||||||
|
|
@ -704,13 +730,42 @@ begin
|
||||||
intSetInit(result.declaredThings);
|
intSetInit(result.declaredThings);
|
||||||
intSetInit(result.debugDeclared);
|
intSetInit(result.debugDeclared);
|
||||||
result.cfilename := filename;
|
result.cfilename := filename;
|
||||||
|
result.filename := filename;
|
||||||
initIdTable(result.typeCache);
|
initIdTable(result.typeCache);
|
||||||
initIdTable(result.forwTypeCache);
|
initIdTable(result.forwTypeCache);
|
||||||
result.module := module;
|
result.module := module;
|
||||||
intSetInit(result.typeInfoMarker);
|
intSetInit(result.typeInfoMarker);
|
||||||
result.initProc := newProc(nil, result);
|
result.initProc := newProc(nil, result);
|
||||||
result.initProc.options := gOptions;
|
result.initProc.options := gOptions;
|
||||||
{@emit result.typeStack := [];}
|
initNodeTable(result.dataCache);
|
||||||
|
{@emit result.typeStack := @[];}
|
||||||
|
result.typeNodesName := getTempName();
|
||||||
|
result.nimTypesName := getTempName();
|
||||||
|
end;
|
||||||
|
|
||||||
|
function myOpen(module: PSym; const filename: string): PPassContext;
|
||||||
|
begin
|
||||||
|
result := newModule(module, filename);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function myOpenCached(module: PSym; const filename: string;
|
||||||
|
rd: PRodReader): PPassContext;
|
||||||
|
var
|
||||||
|
cfile, cfilenoext, objFile: string;
|
||||||
|
begin
|
||||||
|
//MessageOut('cgen.myOpenCached has been called ' + filename);
|
||||||
|
cfile := changeFileExt(completeCFilePath(filename), cExt);
|
||||||
|
cfilenoext := changeFileExt(cfile, '');
|
||||||
|
(*
|
||||||
|
objFile := toObjFile(cfilenoext);
|
||||||
|
if ExistsFile(objFile) and nos.FileNewer(objFile, cfile) then begin
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
addFileToCompile(cfilenoext); // is to compile
|
||||||
|
end; *)
|
||||||
|
addFileToLink(cfilenoext);
|
||||||
|
registerModuleToMain(module);
|
||||||
|
result := nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function shouldRecompile(code: PRope; const cfile, cfilenoext: string): bool;
|
function shouldRecompile(code: PRope; const cfile, cfilenoext: string): bool;
|
||||||
|
|
@ -718,7 +773,7 @@ var
|
||||||
objFile: string;
|
objFile: string;
|
||||||
begin
|
begin
|
||||||
result := true;
|
result := true;
|
||||||
if optCFileCache in gGlobalOptions then begin
|
if not (optForceFullMake in gGlobalOptions) then begin
|
||||||
objFile := toObjFile(cfilenoext);
|
objFile := toObjFile(cfilenoext);
|
||||||
if writeRopeIfNotEqual(code, cfile) then exit;
|
if writeRopeIfNotEqual(code, cfile) then exit;
|
||||||
if ExistsFile(objFile) and nos.FileNewer(objFile, cfile) then
|
if ExistsFile(objFile) and nos.FileNewer(objFile, cfile) then
|
||||||
|
|
@ -728,47 +783,57 @@ begin
|
||||||
writeRope(code, cfile);
|
writeRope(code, cfile);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure finishModule(b: PBackend; n: PNode);
|
function myProcess(b: PPassContext; n: PNode): PNode;
|
||||||
|
var
|
||||||
|
m: BModule;
|
||||||
|
begin
|
||||||
|
result := n;
|
||||||
|
if b = nil then exit;
|
||||||
|
m := BModule(b);
|
||||||
|
m.initProc.options := gOptions;
|
||||||
|
genStmts(m.initProc, n);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function myClose(b: PPassContext; n: PNode): PNode;
|
||||||
var
|
var
|
||||||
cfile, cfilenoext: string;
|
cfile, cfilenoext: string;
|
||||||
m: BModule;
|
m: BModule;
|
||||||
code: PRope;
|
code: PRope;
|
||||||
begin
|
begin
|
||||||
|
result := n;
|
||||||
|
if b = nil then exit;
|
||||||
m := BModule(b);
|
m := BModule(b);
|
||||||
|
if n <> nil then begin
|
||||||
m.initProc.options := gOptions;
|
m.initProc.options := gOptions;
|
||||||
genStmts(m.initProc, n);
|
genStmts(m.initProc, n);
|
||||||
|
end;
|
||||||
// generate code for the init statements of the module:
|
// generate code for the init statements of the module:
|
||||||
genInitCode(m);
|
genInitCode(m);
|
||||||
finishTypeDescriptions(m);
|
finishTypeDescriptions(m);
|
||||||
|
cfile := completeCFilePath(m.cfilename);
|
||||||
|
cfilenoext := changeFileExt(cfile, '');
|
||||||
if sfMainModule in m.module.flags then begin
|
if sfMainModule in m.module.flags then begin
|
||||||
// generate mapping file (if requested):
|
|
||||||
if gMapping <> nil then
|
|
||||||
WriteRope(gMapping, ChangeFileExt(cfile + '_map', 'txt'));
|
|
||||||
|
|
||||||
// generate main file:
|
// generate main file:
|
||||||
app(m.s[cfsProcHeaders], mainModProcs);
|
app(m.s[cfsProcHeaders], mainModProcs);
|
||||||
genMainProc(m);
|
genMainProc(m);
|
||||||
end;
|
end;
|
||||||
cfile := completeCFilePath(m.cfilename);
|
|
||||||
cfilenoext := changeFileExt(cfile, '');
|
|
||||||
code := genModule(m, cfilenoext);
|
code := genModule(m, cfilenoext);
|
||||||
if shouldRecompile(code, changeFileExt(cfile, cExt), cfilenoext) then begin
|
if shouldRecompile(code, changeFileExt(cfile, cExt), cfilenoext) then begin
|
||||||
addFileToCompile(cfilenoext); // is to compile
|
addFileToCompile(cfilenoext); // is to compile
|
||||||
end;
|
end;
|
||||||
addFileToLink(cfilenoext);
|
addFileToLink(cfilenoext);
|
||||||
|
if sfMainModule in m.module.flags then writeMapping(cfile, gMapping);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function CBackend(b: PBackend; module: PSym; const filename: string): PBackend;
|
function cgenPass(): TPass;
|
||||||
var
|
|
||||||
g: BModule;
|
|
||||||
begin
|
begin
|
||||||
g := newModule(module, filename);
|
initPass(result);
|
||||||
g.backendCreator := CBackend;
|
result.open := myOpen;
|
||||||
g.eventMask := {@set}[eAfterModule];
|
result.openCached := myOpenCached;
|
||||||
g.afterModuleEvent := finishModule;
|
result.process := myProcess;
|
||||||
result := g;
|
result.close := myClose;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
intSetInit(gTypeInfoGenerated);
|
InitIiTable(gToTypeInfoId);
|
||||||
end.
|
end.
|
||||||
|
|
|
||||||
177
nim/commands.pas
177
nim/commands.pas
|
|
@ -16,7 +16,8 @@ interface
|
||||||
{$include 'config.inc'}
|
{$include 'config.inc'}
|
||||||
|
|
||||||
uses
|
uses
|
||||||
nsystem, charsets, msgs;
|
nsystem, charsets, nos, msgs, options, nversion, condsyms, strutils, extccomp,
|
||||||
|
platform, lists, wordrecg;
|
||||||
|
|
||||||
procedure writeCommandLineUsage;
|
procedure writeCommandLineUsage;
|
||||||
|
|
||||||
|
|
@ -33,10 +34,6 @@ procedure processSwitch(const switch, arg: string; pass: TCmdlinePass;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
|
||||||
options, nversion, condsyms, strutils, extccomp, platform, nos, lists,
|
|
||||||
wordrecg;
|
|
||||||
|
|
||||||
{@ignore}
|
{@ignore}
|
||||||
const
|
const
|
||||||
{$ifdef fpc}
|
{$ifdef fpc}
|
||||||
|
|
@ -54,19 +51,18 @@ const
|
||||||
const
|
const
|
||||||
Usage = ''
|
Usage = ''
|
||||||
//[[[cog
|
//[[[cog
|
||||||
//def f(x): return "+{&} '" + x.replace("'", "''")[:-1] + "' +{&} nl"
|
//from string import replace
|
||||||
//for line in file("data/basicopt.txt"):
|
//def f(x): return "+{&} '" + replace(x, "'", "''")[:-1] + "' +{&} nl"
|
||||||
|
//for line in open("data/basicopt.txt").readlines():
|
||||||
// cog.outl(f(line))
|
// cog.outl(f(line))
|
||||||
//]]]
|
//]]]
|
||||||
+{&} 'Usage::' +{&} nl
|
+{&} 'Usage::' +{&} nl
|
||||||
+{&} ' nimrod command [options] inputfile [arguments]' +{&} nl
|
+{&} ' nimrod command [options] inputfile [arguments]' +{&} nl
|
||||||
+{&} 'Command::' +{&} nl
|
+{&} 'Command::' +{&} nl
|
||||||
+{&} ' compile compile project with default code generator (C)' +{&} nl
|
+{&} ' compile, c compile project with default code generator (C)' +{&} nl
|
||||||
+{&} ' compile_to_c compile project with C code generator' +{&} nl
|
+{&} ' compile_to_c, cc compile project with C code generator' +{&} nl
|
||||||
+{&} ' compile_to_cpp compile project with C++ code generator' +{&} nl
|
+{&} ' doc generate the documentation for inputfile' +{&} nl
|
||||||
+{&} ' compile_to_ecmascript compile project to ECMAScript code (experimental)' +{&} nl
|
+{&} ' rst2html converts a reStructuredText file to HTML' +{&} nl
|
||||||
+{&} ' doc generate the documentation for inputfile;' +{&} nl
|
|
||||||
+{&} ' with --run switch opens it with $BROWSER' +{&} nl
|
|
||||||
+{&} 'Arguments:' +{&} nl
|
+{&} 'Arguments:' +{&} nl
|
||||||
+{&} ' arguments are passed to the program being run (if --run option is selected)' +{&} nl
|
+{&} ' arguments are passed to the program being run (if --run option is selected)' +{&} nl
|
||||||
+{&} 'Options:' +{&} nl
|
+{&} 'Options:' +{&} nl
|
||||||
|
|
@ -74,7 +70,8 @@ const
|
||||||
+{&} ' -o, --out:FILE set the output filename' +{&} nl
|
+{&} ' -o, --out:FILE set the output filename' +{&} nl
|
||||||
+{&} ' -d, --define:SYMBOL define a conditional symbol' +{&} nl
|
+{&} ' -d, --define:SYMBOL define a conditional symbol' +{&} nl
|
||||||
+{&} ' -u, --undef:SYMBOL undefine a conditional symbol' +{&} nl
|
+{&} ' -u, --undef:SYMBOL undefine a conditional symbol' +{&} nl
|
||||||
+{&} ' -b, --force_build force rebuilding of all modules' +{&} nl
|
+{&} ' -f, --force_build force rebuilding of all modules' +{&} nl
|
||||||
|
+{&} ' --symbol_files:on|off use symbol files to speed up compilation (buggy!)' +{&} nl
|
||||||
+{&} ' --stack_trace:on|off code generation for stack trace ON|OFF' +{&} nl
|
+{&} ' --stack_trace:on|off code generation for stack trace ON|OFF' +{&} nl
|
||||||
+{&} ' --line_trace:on|off code generation for line trace ON|OFF' +{&} nl
|
+{&} ' --line_trace:on|off code generation for line trace ON|OFF' +{&} nl
|
||||||
+{&} ' --debugger:on|off turn Embedded Nimrod Debugger ON|OFF' +{&} nl
|
+{&} ' --debugger:on|off turn Embedded Nimrod Debugger ON|OFF' +{&} nl
|
||||||
|
|
@ -95,7 +92,7 @@ const
|
||||||
|
|
||||||
AdvancedUsage = ''
|
AdvancedUsage = ''
|
||||||
//[[[cog
|
//[[[cog
|
||||||
//for line in file("data/advopt.txt"):
|
//for line in open("data/advopt.txt").readlines():
|
||||||
// cog.outl(f(line))
|
// cog.outl(f(line))
|
||||||
//]]]
|
//]]]
|
||||||
+{&} 'Advanced commands::' +{&} nl
|
+{&} 'Advanced commands::' +{&} nl
|
||||||
|
|
@ -104,21 +101,17 @@ const
|
||||||
+{&} ' gen_depend generate a DOT file containing the' +{&} nl
|
+{&} ' gen_depend generate a DOT file containing the' +{&} nl
|
||||||
+{&} ' module dependency graph' +{&} nl
|
+{&} ' module dependency graph' +{&} nl
|
||||||
+{&} ' list_def list all defined conditionals and exit' +{&} nl
|
+{&} ' list_def list all defined conditionals and exit' +{&} nl
|
||||||
+{&} ' rst2html converts a reStructuredText file to HTML' +{&} nl
|
|
||||||
+{&} ' check checks the project for syntax and semantic' +{&} nl
|
+{&} ' check checks the project for syntax and semantic' +{&} nl
|
||||||
+{&} ' parse parses a single file (for debugging Nimrod)' +{&} nl
|
+{&} ' parse parses a single file (for debugging Nimrod)' +{&} nl
|
||||||
+{&} ' scan tokenizes a single file (for debugging Nimrod)' +{&} nl
|
|
||||||
+{&} ' debugtrans for debugging the transformation pass' +{&} nl
|
|
||||||
+{&} 'Advanced options:' +{&} nl
|
+{&} 'Advanced options:' +{&} nl
|
||||||
+{&} ' -w, --warnings:on|off warnings ON|OFF' +{&} nl
|
+{&} ' -w, --warnings:on|off warnings ON|OFF' +{&} nl
|
||||||
+{&} ' --warning[X]:on|off specific warning X ON|OFF' +{&} nl
|
+{&} ' --warning[X]:on|off specific warning X ON|OFF' +{&} nl
|
||||||
+{&} ' --hints:on|off hints ON|OFF' +{&} nl
|
+{&} ' --hints:on|off hints ON|OFF' +{&} nl
|
||||||
+{&} ' --hint[X]:on|off specific hint X ON|OFF' +{&} nl
|
+{&} ' --hint[X]:on|off specific hint X ON|OFF' +{&} nl
|
||||||
+{&} ' --cc:C_COMPILER set the C/C++ compiler to use' +{&} nl
|
|
||||||
+{&} ' --lib:PATH set the system library path' +{&} nl
|
+{&} ' --lib:PATH set the system library path' +{&} nl
|
||||||
+{&} ' -c, --compile_only compile only; do not assemble or link' +{&} nl
|
+{&} ' -c, --compile_only compile only; do not assemble or link' +{&} nl
|
||||||
+{&} ' --no_linking compile but do not link' +{&} nl
|
+{&} ' --no_linking compile but do not link' +{&} nl
|
||||||
+{&} ' --gen_script generate a compile script (in the ''rod_gen''' +{&} nl
|
+{&} ' --gen_script generate a compile script (in the ''nimcache''' +{&} nl
|
||||||
+{&} ' subdirectory named ''compile_$project$scriptext'')' +{&} nl
|
+{&} ' subdirectory named ''compile_$project$scriptext'')' +{&} nl
|
||||||
+{&} ' --os:SYMBOL set the target operating system (cross-compilation)' +{&} nl
|
+{&} ' --os:SYMBOL set the target operating system (cross-compilation)' +{&} nl
|
||||||
+{&} ' --cpu:SYMBOL set the target processor (cross-compilation)' +{&} nl
|
+{&} ' --cpu:SYMBOL set the target processor (cross-compilation)' +{&} nl
|
||||||
|
|
@ -127,50 +120,16 @@ const
|
||||||
+{&} ' -l, --passl:OPTION pass an option to the linker' +{&} nl
|
+{&} ' -l, --passl:OPTION pass an option to the linker' +{&} nl
|
||||||
+{&} ' --gen_mapping generate a mapping file containing' +{&} nl
|
+{&} ' --gen_mapping generate a mapping file containing' +{&} nl
|
||||||
+{&} ' (Nimrod, mangled) identifier pairs' +{&} nl
|
+{&} ' (Nimrod, mangled) identifier pairs' +{&} nl
|
||||||
+{&} ' --merge_output generate only one C output file' +{&} nl
|
|
||||||
+{&} ' --line_dir:on|off generation of #line directive ON|OFF' +{&} nl
|
+{&} ' --line_dir:on|off generation of #line directive ON|OFF' +{&} nl
|
||||||
+{&} ' --checkpoints:on|off turn on|off checkpoints; for debugging Nimrod' +{&} nl
|
+{&} ' --checkpoints:on|off turn on|off checkpoints; for debugging Nimrod' +{&} nl
|
||||||
+{&} ' --skip_cfg do not read the general configuration file' +{&} nl
|
+{&} ' --skip_cfg do not read the general configuration file' +{&} nl
|
||||||
+{&} ' --skip_proj_cfg do not read the project''s configuration file' +{&} nl
|
+{&} ' --skip_proj_cfg do not read the project''s configuration file' +{&} nl
|
||||||
+{&} ' --import:MODULE_FILE import the given module implicitly for each module' +{&} nl
|
+{&} ' --import:MODULE_FILE import the given module implicitly for each module' +{&} nl
|
||||||
+{&} ' --maxerr:NUMBER stop compilation after NUMBER errors; broken!' +{&} nl
|
|
||||||
+{&} ' --ast_cache:on|off caching of ASTs ON|OFF (default: OFF)' +{&} nl
|
|
||||||
+{&} ' --c_file_cache:on|off caching of generated C files ON|OFF (default: OFF)' +{&} nl
|
|
||||||
+{&} ' --index:FILE use FILE to generate a documenation index file' +{&} nl
|
+{&} ' --index:FILE use FILE to generate a documenation index file' +{&} nl
|
||||||
+{&} ' --putenv:key=value set an environment variable' +{&} nl
|
+{&} ' --putenv:key=value set an environment variable' +{&} nl
|
||||||
+{&} ' --list_cmd list the commands used to execute external programs' +{&} nl
|
+{&} ' --list_cmd list the commands used to execute external programs' +{&} nl
|
||||||
+{&} ' -v, --verbose show what Nimrod is doing' +{&} nl
|
+{&} ' --verbosity:0|1|2|3 set Nimrod''s verbosity level (0 is default)' +{&} nl
|
||||||
+{&} ' --version show detailed version information' +{&} nl
|
+{&} ' -v, --version show detailed version information' +{&} nl
|
||||||
//[[[end]]]
|
|
||||||
;
|
|
||||||
|
|
||||||
VersionInformation = ''
|
|
||||||
//[[[cog
|
|
||||||
//for line in file("data/changes.txt"):
|
|
||||||
// cog.outl(f(line))
|
|
||||||
//]]]
|
|
||||||
+{&} '0.1.0' +{&} nl
|
|
||||||
+{&} '* new config system' +{&} nl
|
|
||||||
+{&} '* new build system' +{&} nl
|
|
||||||
+{&} '* source renderer' +{&} nl
|
|
||||||
+{&} '* pas2nim integrated' +{&} nl
|
|
||||||
+{&} '* support for C++' +{&} nl
|
|
||||||
+{&} '* local variables are always initialized' +{&} nl
|
|
||||||
+{&} '* Rod file reader and writer' +{&} nl
|
|
||||||
+{&} '* new --out, -o command line options' +{&} nl
|
|
||||||
+{&} '* fixed bug in nimconf.pas: we now have several' +{&} nl
|
|
||||||
+{&} ' string token types' +{&} nl
|
|
||||||
+{&} '* changed nkIdentDef to nkIdentDefs' +{&} nl
|
|
||||||
+{&} '* added type(expr) in the parser and the grammer' +{&} nl
|
|
||||||
+{&} '* added template' +{&} nl
|
|
||||||
+{&} '* added command calls' +{&} nl
|
|
||||||
+{&} '* added case in records/objects' +{&} nl
|
|
||||||
+{&} '* added --skip_proj_cfg switch for nim.dpr' +{&} nl
|
|
||||||
+{&} '* added missing features to pasparse' +{&} nl
|
|
||||||
+{&} '* rewrote the source generator' +{&} nl
|
|
||||||
+{&} '* ``addr`` and ``cast`` are now keywords; grammar updated' +{&} nl
|
|
||||||
+{&} '* implemented ` notation; grammar updated' +{&} nl
|
|
||||||
+{&} '* specification replaced by a manual' +{&} nl
|
|
||||||
//[[[end]]]
|
//[[[end]]]
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -212,7 +171,7 @@ begin
|
||||||
versionWritten := true;
|
versionWritten := true;
|
||||||
helpWritten := true;
|
helpWritten := true;
|
||||||
messageOut(format(HelpMessage, [VersionAsString, platform.os[hostOS].name,
|
messageOut(format(HelpMessage, [VersionAsString, platform.os[hostOS].name,
|
||||||
cpu[hostCPU].name]) +{&} VersionInformation)
|
cpu[hostCPU].name]))
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -378,14 +337,10 @@ begin
|
||||||
if pass in {@set}[passCmd2, passPP] then
|
if pass in {@set}[passCmd2, passPP] then
|
||||||
addFileToLink(arg);
|
addFileToLink(arg);
|
||||||
end;
|
end;
|
||||||
wDebuginfo:
|
wDebuginfo: include(gGlobalOptions, optCDebug);
|
||||||
include(gGlobalOptions, optCDebug);
|
wCompileOnly, wC: include(gGlobalOptions, optCompileOnly);
|
||||||
wCompileOnly, wC:
|
wNoLinking: include(gGlobalOptions, optNoLinking);
|
||||||
include(gGlobalOptions, optCompileOnly);
|
wForceBuild, wF: include(gGlobalOptions, optForceFullMake);
|
||||||
wNoLinking:
|
|
||||||
include(gGlobalOptions, optNoLinking);
|
|
||||||
wForceBuild, wF:
|
|
||||||
include(gGlobalOptions, optForceFullMake);
|
|
||||||
wGC: begin
|
wGC: begin
|
||||||
case whichKeyword(arg) of
|
case whichKeyword(arg) of
|
||||||
wBoehm: begin
|
wBoehm: begin
|
||||||
|
|
@ -406,20 +361,13 @@ begin
|
||||||
liMessage(info, errNoneBoehmRefcExpectedButXFound, arg)
|
liMessage(info, errNoneBoehmRefcExpectedButXFound, arg)
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
wWarnings, wW:
|
wWarnings, wW: ProcessOnOffSwitch({@set}[optWarns], arg, pass, info);
|
||||||
ProcessOnOffSwitch({@set}[optWarns], arg, pass, info);
|
wWarning: ProcessSpecificNote(arg, wWarning, pass, info);
|
||||||
wWarning:
|
wHint: ProcessSpecificNote(arg, wHint, pass, info);
|
||||||
ProcessSpecificNote(arg, wWarning, pass, info);
|
wHints: ProcessOnOffSwitch({@set}[optHints], arg, pass, info);
|
||||||
wHint:
|
wCheckpoints: ProcessOnOffSwitch({@set}[optCheckpoints], arg, pass, info);
|
||||||
ProcessSpecificNote(arg, wHint, pass, info);
|
wStackTrace: ProcessOnOffSwitch({@set}[optStackTrace], arg, pass, info);
|
||||||
wHints:
|
wLineTrace: ProcessOnOffSwitch({@set}[optLineTrace], arg, pass, info);
|
||||||
ProcessOnOffSwitch({@set}[optHints], arg, pass, info);
|
|
||||||
wCheckpoints:
|
|
||||||
ProcessOnOffSwitch({@set}[optCheckpoints], arg, pass, info);
|
|
||||||
wStackTrace:
|
|
||||||
ProcessOnOffSwitch({@set}[optStackTrace], arg, pass, info);
|
|
||||||
wLineTrace:
|
|
||||||
ProcessOnOffSwitch({@set}[optLineTrace], arg, pass, info);
|
|
||||||
wDebugger: begin
|
wDebugger: begin
|
||||||
ProcessOnOffSwitch({@set}[optEndb], arg, pass, info);
|
ProcessOnOffSwitch({@set}[optEndb], arg, pass, info);
|
||||||
if optEndb in gOptions then
|
if optEndb in gOptions then
|
||||||
|
|
@ -427,26 +375,19 @@ begin
|
||||||
else
|
else
|
||||||
UndefSymbol('endb')
|
UndefSymbol('endb')
|
||||||
end;
|
end;
|
||||||
wChecks, wX:
|
wProfiler: begin
|
||||||
ProcessOnOffSwitch(checksOptions, arg, pass, info);
|
ProcessOnOffSwitch({@set}[optProfiler], arg, pass, info);
|
||||||
wObjChecks:
|
if optProfiler in gOptions then DefineSymbol('profiler')
|
||||||
ProcessOnOffSwitch({@set}[optObjCheck], arg, pass, info);
|
else UndefSymbol('profiler')
|
||||||
wFieldChecks:
|
end;
|
||||||
ProcessOnOffSwitch({@set}[optFieldCheck], arg, pass, info);
|
wChecks, wX: ProcessOnOffSwitch(checksOptions, arg, pass, info);
|
||||||
wRangeChecks:
|
wObjChecks: ProcessOnOffSwitch({@set}[optObjCheck], arg, pass, info);
|
||||||
ProcessOnOffSwitch({@set}[optRangeCheck], arg, pass, info);
|
wFieldChecks: ProcessOnOffSwitch({@set}[optFieldCheck], arg, pass, info);
|
||||||
wBoundChecks:
|
wRangeChecks: ProcessOnOffSwitch({@set}[optRangeCheck], arg, pass, info);
|
||||||
ProcessOnOffSwitch({@set}[optBoundsCheck], arg, pass, info);
|
wBoundChecks: ProcessOnOffSwitch({@set}[optBoundsCheck], arg, pass, info);
|
||||||
wOverflowChecks:
|
wOverflowChecks: ProcessOnOffSwitch({@set}[optOverflowCheck], arg, pass, info);
|
||||||
ProcessOnOffSwitch({@set}[optOverflowCheck], arg, pass, info);
|
wLineDir: ProcessOnOffSwitch({@set}[optLineDir], arg, pass, info);
|
||||||
wLineDir:
|
wAssertions, wA: ProcessOnOffSwitch({@set}[optAssert], arg, pass, info);
|
||||||
ProcessOnOffSwitch({@set}[optLineDir], arg, pass, info);
|
|
||||||
wAssertions, wA:
|
|
||||||
ProcessOnOffSwitch({@set}[optAssert], arg, pass, info);
|
|
||||||
wCFileCache:
|
|
||||||
ProcessOnOffSwitchG({@set}[optCFileCache], arg, pass, info);
|
|
||||||
wAstCache:
|
|
||||||
ProcessOnOffSwitchG({@set}[optAstCache], arg, pass, info);
|
|
||||||
wOpt: begin
|
wOpt: begin
|
||||||
case whichKeyword(arg) of
|
case whichKeyword(arg) of
|
||||||
wSpeed: begin
|
wSpeed: begin
|
||||||
|
|
@ -505,10 +446,8 @@ begin
|
||||||
expectArg(switch, arg, pass, info);
|
expectArg(switch, arg, pass, info);
|
||||||
options.addImplicitMod(arg);
|
options.addImplicitMod(arg);
|
||||||
end;
|
end;
|
||||||
wListCmd:
|
wListCmd: include(gGlobalOptions, optListCmd);
|
||||||
include(gGlobalOptions, optListCmd);
|
wGenMapping: include(gGlobalOptions, optGenMapping);
|
||||||
wGenMapping:
|
|
||||||
include(gGlobalOptions, optGenMapping);
|
|
||||||
wOS: begin
|
wOS: begin
|
||||||
if (pass = passCmd1) then begin
|
if (pass = passCmd1) then begin
|
||||||
theOS := platform.NameToOS(arg);
|
theOS := platform.NameToOS(arg);
|
||||||
|
|
@ -533,26 +472,18 @@ begin
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
wRun, wR:
|
wRun, wR: include(gGlobalOptions, optRun);
|
||||||
include(gGlobalOptions, optRun);
|
wVerbosity: begin
|
||||||
wVerbose, wV:
|
expectArg(switch, arg, pass, info);
|
||||||
include(gGlobalOptions, optVerbose);
|
gVerbosity := parseInt(arg);
|
||||||
wMergeOutput:
|
end;
|
||||||
include(gGlobalOptions, optMergeOutput);
|
wVersion, wV: writeVersionInfo(pass);
|
||||||
wVersion:
|
wAdvanced: writeAdvancedUsage(pass);
|
||||||
writeVersionInfo(pass);
|
wHelp, wH: helpOnError(pass);
|
||||||
wAdvanced:
|
wSymbolFiles: ProcessOnOffSwitchG({@set}[optSymbolFiles], arg, pass, info);
|
||||||
writeAdvancedUsage(pass);
|
wSkipCfg: include(gGlobalOptions, optSkipConfigFile);
|
||||||
wHelp, wH:
|
wSkipProjCfg: include(gGlobalOptions, optSkipProjConfigFile);
|
||||||
helpOnError(pass);
|
wGenScript: include(gGlobalOptions, optGenScript);
|
||||||
wCompileSys:
|
|
||||||
include(gGlobalOptions, optCompileSys);
|
|
||||||
wSkipCfg:
|
|
||||||
include(gGlobalOptions, optSkipConfigFile);
|
|
||||||
wSkipProjCfg:
|
|
||||||
include(gGlobalOptions, optSkipProjConfigFile);
|
|
||||||
wGenScript:
|
|
||||||
include(gGlobalOptions, optGenScript);
|
|
||||||
wLib: begin
|
wLib: begin
|
||||||
expectArg(switch, arg, pass, info);
|
expectArg(switch, arg, pass, info);
|
||||||
libpath := processPath(arg)
|
libpath := processPath(arg)
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@
|
||||||
// See the file "copying.txt", included in this
|
// See the file "copying.txt", included in this
|
||||||
// distribution, for details about the copyright.
|
// distribution, for details about the copyright.
|
||||||
//
|
//
|
||||||
|
|
||||||
unit condsyms;
|
unit condsyms;
|
||||||
|
|
||||||
// This module handles the conditional symbols.
|
// This module handles the conditional symbols.
|
||||||
|
|
@ -16,7 +15,7 @@ unit condsyms;
|
||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
ast, astalgo, msgs, hashes, platform, strutils, idents;
|
nsystem, ast, astalgo, msgs, hashes, platform, strutils, idents;
|
||||||
|
|
||||||
var
|
var
|
||||||
gSymbols: TStrTable;
|
gSymbols: TStrTable;
|
||||||
|
|
@ -29,6 +28,8 @@ procedure UndefSymbol(const symbol: string);
|
||||||
function isDefined(symbol: PIdent): Boolean;
|
function isDefined(symbol: PIdent): Boolean;
|
||||||
procedure ListSymbols;
|
procedure ListSymbols;
|
||||||
|
|
||||||
|
function countDefinedSymbols: int;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
procedure DefineSymbol(const symbol: string);
|
procedure DefineSymbol(const symbol: string);
|
||||||
|
|
@ -39,7 +40,12 @@ begin
|
||||||
i := getIdent(symbol);
|
i := getIdent(symbol);
|
||||||
sym := StrTableGet(gSymbols, i);
|
sym := StrTableGet(gSymbols, i);
|
||||||
if sym = nil then begin
|
if sym = nil then begin
|
||||||
sym := NewSym(skConditional, i, nil);
|
new(sym); // circumvent the ID mechanism
|
||||||
|
{@ignore}
|
||||||
|
fillChar(sym^, sizeof(sym^), 0);
|
||||||
|
{@emit}
|
||||||
|
sym.kind := skConditional;
|
||||||
|
sym.name := i;
|
||||||
StrTableAdd(gSymbols, sym);
|
StrTableAdd(gSymbols, sym);
|
||||||
end;
|
end;
|
||||||
sym.position := 1;
|
sym.position := 1;
|
||||||
|
|
@ -75,6 +81,19 @@ begin
|
||||||
MessageOut('-- End of list --');
|
MessageOut('-- End of list --');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function countDefinedSymbols: int;
|
||||||
|
var
|
||||||
|
it: TTabIter;
|
||||||
|
s: PSym;
|
||||||
|
begin
|
||||||
|
s := InitTabIter(it, gSymbols);
|
||||||
|
result := 0;
|
||||||
|
while s <> nil do begin
|
||||||
|
if s.position = 1 then inc(result);
|
||||||
|
s := nextIter(it, gSymbols);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure InitDefines;
|
procedure InitDefines;
|
||||||
begin
|
begin
|
||||||
initStrTable(gSymbols);
|
initStrTable(gSymbols);
|
||||||
|
|
@ -92,7 +111,7 @@ begin
|
||||||
DefineSymbol('win32');
|
DefineSymbol('win32');
|
||||||
end;
|
end;
|
||||||
osLinux, osMorphOS, osSkyOS, osIrix, osPalmOS, osQNX,
|
osLinux, osMorphOS, osSkyOS, osIrix, osPalmOS, osQNX,
|
||||||
osAtari: begin
|
osAtari, osAix: begin
|
||||||
// these are all 'unix-like'
|
// these are all 'unix-like'
|
||||||
DefineSymbol('unix');
|
DefineSymbol('unix');
|
||||||
DefineSymbol('posix');
|
DefineSymbol('posix');
|
||||||
|
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
=======================================================
|
|
||||||
The Nimrod Compiler
|
|
||||||
Copyright (C) 2004-2008 Andreas Rumpf
|
|
||||||
=======================================================
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; version 2
|
|
||||||
of the License.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
42
nim/crc.pas
42
nim/crc.pas
|
|
@ -21,6 +21,8 @@ type
|
||||||
const
|
const
|
||||||
InitCrc32 = TCrc32(-1);
|
InitCrc32 = TCrc32(-1);
|
||||||
|
|
||||||
|
InitAdler32 = int32(1);
|
||||||
|
|
||||||
function updateCrc32(val: Byte; crc: TCrc32): TCrc32; overload;
|
function updateCrc32(val: Byte; crc: TCrc32): TCrc32; overload;
|
||||||
function updateCrc32(val: Char; crc: TCrc32): TCrc32; overload;
|
function updateCrc32(val: Char; crc: TCrc32): TCrc32; overload;
|
||||||
|
|
||||||
|
|
@ -29,6 +31,9 @@ function strCrc32(const s: string): TCrc32;
|
||||||
|
|
||||||
function crcFromFile(const filename: string): TCrc32;
|
function crcFromFile(const filename: string): TCrc32;
|
||||||
|
|
||||||
|
function updateAdler32(adler: int32; buf: pointer; len: int): int32;
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
{@ignore}
|
{@ignore}
|
||||||
|
|
@ -121,12 +126,12 @@ const
|
||||||
|
|
||||||
function updateCrc32(val: Byte; crc: TCrc32): TCrc32; overload;
|
function updateCrc32(val: Byte; crc: TCrc32): TCrc32; overload;
|
||||||
begin
|
begin
|
||||||
result := crc32Table[(int(crc) xor val) and $ff] xor (crc shr 8);
|
result := crc32Table[(int(crc) xor (int(val) and $ff)) and $ff] xor (int(crc) shr 8);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function updateCrc32(val: Char; crc: TCrc32): TCrc32; overload;
|
function updateCrc32(val: Char; crc: TCrc32): TCrc32; overload;
|
||||||
begin
|
begin
|
||||||
result := updateCrc32(ord(val), crc);
|
result := updateCrc32(byte(ord(val)), crc);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function strCrc32(const s: string): TCrc32;
|
function strCrc32(const s: string): TCrc32;
|
||||||
|
|
@ -173,6 +178,39 @@ begin
|
||||||
CloseFile(bin);
|
CloseFile(bin);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
const
|
||||||
|
base = int32(65521); { largest prime smaller than 65536 }
|
||||||
|
{NMAX = 5552; original code with unsigned 32 bit integer }
|
||||||
|
{ NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 }
|
||||||
|
nmax = 3854; { code with signed 32 bit integer }
|
||||||
|
{ NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^31-1 }
|
||||||
|
{ The penalty is the time loss in the extra MOD-calls. }
|
||||||
|
|
||||||
|
function updateAdler32(adler: int32; buf: pointer; len: int): int32;
|
||||||
|
var
|
||||||
|
s1, s2: int32;
|
||||||
|
L, k, b: int;
|
||||||
|
begin
|
||||||
|
s1 := adler and int32($ffff);
|
||||||
|
s2 := (adler shr int32(16)) and int32($ffff);
|
||||||
|
L := len;
|
||||||
|
b := 0;
|
||||||
|
while (L > 0) do begin
|
||||||
|
if L < nmax then k := L
|
||||||
|
else k := nmax;
|
||||||
|
dec(L, k);
|
||||||
|
while (k > 0) do begin
|
||||||
|
s1 := s1 +{%} int32(({@cast}cstring(buf))[b]);
|
||||||
|
s2 := s2 +{%} s1;
|
||||||
|
inc(b); dec(k);
|
||||||
|
end;
|
||||||
|
s1 := modu(s1, base);
|
||||||
|
s2 := modu(s2, base);
|
||||||
|
end;
|
||||||
|
result := (s2 shl int32(16)) or s1;
|
||||||
|
end;
|
||||||
|
|
||||||
{@ignore}
|
{@ignore}
|
||||||
{$ifdef Q_on}
|
{$ifdef Q_on}
|
||||||
{$undef Q_on}
|
{$undef Q_on}
|
||||||
|
|
|
||||||
|
|
@ -114,11 +114,11 @@ begin
|
||||||
{@ignore}
|
{@ignore}
|
||||||
fillChar(result^, sizeof(result^), 0);
|
fillChar(result^, sizeof(result^), 0);
|
||||||
{@emit
|
{@emit
|
||||||
result.tocPart := [];
|
result.tocPart := @[];
|
||||||
}
|
}
|
||||||
result.filename := filename;
|
result.filename := filename;
|
||||||
result.id := 100;
|
result.id := 100;
|
||||||
result.splitAfter := 25;
|
result.splitAfter := 20;
|
||||||
s := getConfigVar('split.item.toc');
|
s := getConfigVar('split.item.toc');
|
||||||
if s <> '' then
|
if s <> '' then
|
||||||
result.splitAfter := parseInt(s);
|
result.splitAfter := parseInt(s);
|
||||||
|
|
@ -212,19 +212,51 @@ begin
|
||||||
'&': dest := dest + '&';
|
'&': dest := dest + '&';
|
||||||
'<': dest := dest + '<';
|
'<': dest := dest + '<';
|
||||||
'>': dest := dest + '>';
|
'>': dest := dest + '>';
|
||||||
|
'"': dest := dest + '"';
|
||||||
else addChar(dest, c)
|
else addChar(dest, c)
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function toXml(const s: string; splitAfter: int = -1): string;
|
function nextSplitPoint(const s: string; start: int): int;
|
||||||
var
|
var
|
||||||
i: int;
|
i: int;
|
||||||
|
begin
|
||||||
|
result := start;
|
||||||
|
while result < length(s)+strStart do begin
|
||||||
|
case s[result] of
|
||||||
|
'_': exit;
|
||||||
|
'a'..'z': begin
|
||||||
|
if result+1 < length(s)+strStart then
|
||||||
|
if s[result+1] in ['A'..'Z'] then exit;
|
||||||
|
end;
|
||||||
|
else begin end;
|
||||||
|
end;
|
||||||
|
inc(result);
|
||||||
|
end;
|
||||||
|
dec(result); // last valid index
|
||||||
|
end;
|
||||||
|
|
||||||
|
function toXml(const s: string; splitAfter: int = -1): string;
|
||||||
|
var
|
||||||
|
i, j, k, partLen: int;
|
||||||
begin
|
begin
|
||||||
result := '';
|
result := '';
|
||||||
for i := strStart to length(s)+strStart-1 do begin
|
if splitAfter >= 0 then begin
|
||||||
if (splitAfter >= 0) and ((i-strStart+1) mod splitAfter = 0) then
|
partLen := 0;
|
||||||
|
j := strStart;
|
||||||
|
while j < length(s)+strStart do begin
|
||||||
|
k := nextSplitPoint(s, j);
|
||||||
|
if partLen + k - j + 1 > splitAfter then begin
|
||||||
|
partLen := 0;
|
||||||
addChar(result, ' ');
|
addChar(result, ' ');
|
||||||
addXmlChar(result, s[i])
|
end;
|
||||||
|
for i := j to k do addXmlChar(result, s[i]);
|
||||||
|
inc(partLen, k - j + 1);
|
||||||
|
j := k+1;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
for i := strStart to length(s)+strStart-1 do addXmlChar(result, s[i])
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,15 +19,17 @@ interface
|
||||||
uses
|
uses
|
||||||
nsystem, ast, astalgo, strutils, hashes, trees, platform, magicsys,
|
nsystem, ast, astalgo, strutils, hashes, trees, platform, magicsys,
|
||||||
extccomp, options, nversion, nimsets, msgs, crc, bitsets, idents,
|
extccomp, options, nversion, nimsets, msgs, crc, bitsets, idents,
|
||||||
lists, types, nos, ntime, ropes, nmath, backends, ccgutils, wordrecg, rnimsyn;
|
lists, types, nos, ntime, ropes, nmath, passes, ccgutils, wordrecg, rnimsyn,
|
||||||
|
rodread;
|
||||||
|
|
||||||
function EcmasBackend(b: PBackend; module: PSym;
|
function ecmasgenPass(): TPass;
|
||||||
const filename: string): PBackend;
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
type
|
type
|
||||||
TEcmasGen = object(TBackend)
|
TEcmasGen = object(TPassContext)
|
||||||
|
filename: string;
|
||||||
|
module: PSym;
|
||||||
end;
|
end;
|
||||||
BModule = ^TEcmasGen;
|
BModule = ^TEcmasGen;
|
||||||
|
|
||||||
|
|
@ -93,7 +95,7 @@ begin
|
||||||
{@ignore}
|
{@ignore}
|
||||||
fillChar(p, sizeof(p), 0);
|
fillChar(p, sizeof(p), 0);
|
||||||
{@emit
|
{@emit
|
||||||
p.blocks := [];}
|
p.blocks := @[];}
|
||||||
p.options := options;
|
p.options := options;
|
||||||
p.module := module;
|
p.module := module;
|
||||||
p.procDef := procDef;
|
p.procDef := procDef;
|
||||||
|
|
@ -103,8 +105,7 @@ end;
|
||||||
|
|
||||||
const
|
const
|
||||||
MappedToObject = {@set}[tyObject, tyArray, tyArrayConstr, tyTuple,
|
MappedToObject = {@set}[tyObject, tyArray, tyArrayConstr, tyTuple,
|
||||||
tyEmptySet, tyOpenArray, tySet, tyVar,
|
tyOpenArray, tySet, tyVar, tyRef, tyPtr];
|
||||||
tyRef, tyPtr];
|
|
||||||
|
|
||||||
function mapType(typ: PType): TEcmasTypeKind;
|
function mapType(typ: PType): TEcmasTypeKind;
|
||||||
begin
|
begin
|
||||||
|
|
@ -129,10 +130,10 @@ begin
|
||||||
end;
|
end;
|
||||||
tyString, tySequence:
|
tyString, tySequence:
|
||||||
result := etyInt; // little hack to get the right semantics
|
result := etyInt; // little hack to get the right semantics
|
||||||
tyObject, tyArray, tyArrayConstr, tyTuple, tyEmptySet, tyOpenArray:
|
tyObject, tyArray, tyArrayConstr, tyTuple, tyOpenArray:
|
||||||
result := etyObject;
|
result := etyObject;
|
||||||
tyNil: result := etyNull;
|
tyNil: result := etyNull;
|
||||||
tyGenericInst, tyGenericParam, tyGeneric, tyNone, tyForward:
|
tyGenericInst, tyGenericParam, tyGeneric, tyNone, tyForward, tyEmpty:
|
||||||
result := etyNone;
|
result := etyNone;
|
||||||
tyProc: result := etyProc;
|
tyProc: result := etyProc;
|
||||||
tyCString: result := etyString;
|
tyCString: result := etyString;
|
||||||
|
|
@ -1832,38 +1833,56 @@ begin
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure finishModule(b: PBackend; n: PNode);
|
function myProcess(b: PPassContext; n: PNode): PNode;
|
||||||
var
|
var
|
||||||
m: BModule;
|
m: BModule;
|
||||||
outfile: string;
|
|
||||||
p: TProc;
|
p: TProc;
|
||||||
r: TCompRes;
|
r: TCompRes;
|
||||||
code: PRope;
|
|
||||||
begin
|
begin
|
||||||
|
result := n;
|
||||||
m := BModule(b);
|
m := BModule(b);
|
||||||
if m.module = nil then InternalError(n.info, 'finishModule');
|
if m.module = nil then InternalError(n.info, 'myProcess');
|
||||||
initProc(p, globals, m, nil, m.module.options);
|
initProc(p, globals, m, nil, m.module.options);
|
||||||
genModule(p, n, r);
|
genModule(p, n, r);
|
||||||
app(p.globals.code, p.data);
|
app(p.globals.code, p.data);
|
||||||
app(p.globals.code, mergeStmt(r));
|
app(p.globals.code, mergeStmt(r));
|
||||||
if sfMainModule in m.module.flags then begin
|
|
||||||
// write the file:
|
|
||||||
code := con(p.globals.typeInfo, p.globals.code);
|
|
||||||
outfile := changeFileExt(completeCFilePath(m.filename), 'js');
|
|
||||||
{@discard} writeRopeIfNotEqual(con(genHeader(), code), outfile);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function EcmasBackend(b: PBackend; module: PSym;
|
function myClose(b: PPassContext; n: PNode): PNode;
|
||||||
const filename: string): PBackend;
|
|
||||||
var
|
var
|
||||||
g: BModule;
|
m: BModule;
|
||||||
|
code: PRope;
|
||||||
|
outfile: string;
|
||||||
begin
|
begin
|
||||||
g := newModule(module, filename);
|
result := myProcess(b, n);
|
||||||
g.backendCreator := EcmasBackend;
|
m := BModule(b);
|
||||||
g.eventMask := {@set}[eAfterModule];
|
if sfMainModule in m.module.flags then begin
|
||||||
g.afterModuleEvent := finishModule;
|
// write the file:
|
||||||
result := g;
|
code := con(globals.typeInfo, globals.code);
|
||||||
|
outfile := changeFileExt(completeCFilePath(m.filename), 'js');
|
||||||
|
{@discard} writeRopeIfNotEqual(con(genHeader(), code), outfile);
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
function myOpenCached(s: PSym; const filename: string;
|
||||||
|
rd: PRodReader): PPassContext;
|
||||||
|
begin
|
||||||
|
InternalError('symbol files are not possible with the Ecmas code generator');
|
||||||
|
result := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function myOpen(s: PSym; const filename: string): PPassContext;
|
||||||
|
begin
|
||||||
|
result := newModule(s, filename);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ecmasgenPass(): TPass;
|
||||||
|
begin
|
||||||
|
InitPass(result);
|
||||||
|
result.open := myOpen;
|
||||||
|
result.close := myClose;
|
||||||
|
result.openCached := myOpenCached;
|
||||||
|
result.process := myProcess;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
|
||||||
1177
nim/eval.pas
1177
nim/eval.pas
File diff suppressed because it is too large
Load diff
152
nim/extccomp.pas
152
nim/extccomp.pas
|
|
@ -15,7 +15,8 @@ interface
|
||||||
{$include 'config.inc'}
|
{$include 'config.inc'}
|
||||||
|
|
||||||
uses
|
uses
|
||||||
nsystem, nimconf, msgs;
|
nsystem, charsets, lists, ropes, nos, strutils, platform, condsyms, options,
|
||||||
|
msgs;
|
||||||
|
|
||||||
// some things are read in from the configuration file
|
// some things are read in from the configuration file
|
||||||
|
|
||||||
|
|
@ -89,7 +90,7 @@ const
|
||||||
optSpeed: ' -O -p6 ';
|
optSpeed: ' -O -p6 ';
|
||||||
optSize: ' -O -p6 ';
|
optSize: ' -O -p6 ';
|
||||||
compilerExe: 'lcc';
|
compilerExe: 'lcc';
|
||||||
compileTmpl: '-e1 $options $include -Fo$objfile $file';
|
compileTmpl: '$options $include -Fo$objfile $file';
|
||||||
buildGui: ' -subsystem windows';
|
buildGui: ' -subsystem windows';
|
||||||
buildDll: ' -dll';
|
buildDll: ' -dll';
|
||||||
linkerExe: 'lcclnk';
|
linkerExe: 'lcclnk';
|
||||||
|
|
@ -287,13 +288,10 @@ function NameToCC(const name: string): TSystemCC;
|
||||||
procedure initVars;
|
procedure initVars;
|
||||||
|
|
||||||
procedure setCC(const ccname: string);
|
procedure setCC(const ccname: string);
|
||||||
|
procedure writeMapping(const cfile: string; gSymbolMapping: PRope);
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
|
||||||
charsets,
|
|
||||||
lists, options, ropes, nos, strutils, platform, condsyms;
|
|
||||||
|
|
||||||
var
|
var
|
||||||
toLink, toCompile, externalToCompile: TLinkedList;
|
toLink, toCompile, externalToCompile: TLinkedList;
|
||||||
linkOptions: string = '';
|
linkOptions: string = '';
|
||||||
|
|
@ -301,16 +299,31 @@ var
|
||||||
|
|
||||||
ccompilerpath: string = '';
|
ccompilerpath: string = '';
|
||||||
|
|
||||||
procedure initVars;
|
procedure setCC(const ccname: string);
|
||||||
|
var
|
||||||
|
i: TSystemCC;
|
||||||
begin
|
begin
|
||||||
// BUGFIX: '.' forgotten
|
linkOptions := '';
|
||||||
|
ccompiler := nameToCC(ccname);
|
||||||
|
if ccompiler = ccNone then rawMessage(errUnknownCcompiler, ccname);
|
||||||
compileOptions := getConfigVar(CC[ccompiler].name + '.options.always');
|
compileOptions := getConfigVar(CC[ccompiler].name + '.options.always');
|
||||||
// have the variables not been initialized?
|
|
||||||
ccompilerpath := getConfigVar(CC[ccompiler].name + '.path');
|
ccompilerpath := getConfigVar(CC[ccompiler].name + '.path');
|
||||||
|
for i := low(CC) to high(CC) do undefSymbol(CC[i].name);
|
||||||
|
defineSymbol(CC[ccompiler].name);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure initVars;
|
||||||
|
var
|
||||||
|
i: TSystemCC;
|
||||||
|
begin
|
||||||
// we need to define the symbol here, because ``CC`` may have never been set!
|
// we need to define the symbol here, because ``CC`` may have never been set!
|
||||||
setCC(CC[ccompiler].name);
|
for i := low(CC) to high(CC) do undefSymbol(CC[i].name);
|
||||||
|
defineSymbol(CC[ccompiler].name);
|
||||||
if gCmd = cmdCompileToCpp then
|
if gCmd = cmdCompileToCpp then
|
||||||
cExt := '.cpp';
|
cExt := '.cpp';
|
||||||
|
addCompileOption(getConfigVar(CC[ccompiler].name + '.options.always'));
|
||||||
|
if length(ccompilerPath) = 0 then
|
||||||
|
ccompilerpath := getConfigVar(CC[ccompiler].name + '.path');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function completeCFilePath(const cfile: string;
|
function completeCFilePath(const cfile: string;
|
||||||
|
|
@ -331,28 +344,28 @@ begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure setCC(const ccname: string);
|
procedure addStr(var dest: string; const src: string);
|
||||||
var
|
|
||||||
i: TSystemCC;
|
|
||||||
begin
|
begin
|
||||||
ccompiler := nameToCC(ccname);
|
dest := dest +{&} src;
|
||||||
if ccompiler = ccNone then
|
end;
|
||||||
rawMessage(errUnknownCcompiler, ccname);
|
|
||||||
for i := low(CC) to high(CC) do
|
procedure addOpt(var dest: string; const src: string);
|
||||||
undefSymbol(CC[i].name);
|
begin
|
||||||
defineSymbol(CC[ccompiler].name)
|
if (length(dest) = 0) or (dest[length(dest)-1+strStart] <> ' ') then
|
||||||
|
addStr(dest, ' '+'');
|
||||||
|
addStr(dest, src);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure addCompileOption(const option: string);
|
procedure addCompileOption(const option: string);
|
||||||
begin
|
begin
|
||||||
if strutils.findSubStr(option, compileOptions, strStart) < strStart then
|
if strutils.findSubStr(option, compileOptions, strStart) < strStart then
|
||||||
compileOptions := compileOptions + ' ' +{&} option
|
addOpt(compileOptions, option)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure addLinkOption(const option: string);
|
procedure addLinkOption(const option: string);
|
||||||
begin
|
begin
|
||||||
if findSubStr(option, linkOptions, strStart) < strStart then
|
if findSubStr(option, linkOptions, strStart) < strStart then
|
||||||
linkOptions := linkOptions + ' ' +{&} option
|
addOpt(linkOptions, option)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function toObjFile(const filenameWithoutExt: string): string;
|
function toObjFile(const filenameWithoutExt: string): string;
|
||||||
|
|
@ -378,9 +391,9 @@ end;
|
||||||
|
|
||||||
procedure execExternalProgram(const cmd: string);
|
procedure execExternalProgram(const cmd: string);
|
||||||
begin
|
begin
|
||||||
if optListCmd in gGlobalOptions then
|
if (optListCmd in gGlobalOptions) or (gVerbosity > 0) then
|
||||||
MessageOut('Executing: ' +{&} nl +{&} cmd);
|
MessageOut('Executing: ' +{&} nl +{&} cmd);
|
||||||
if ExecuteProcess(cmd) <> 0 then
|
if executeShellCommand(cmd) <> 0 then
|
||||||
rawMessage(errExecutionOfProgramFailed);
|
rawMessage(errExecutionOfProgramFailed);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -391,12 +404,7 @@ begin
|
||||||
splitPath(projectFile, path, scriptname);
|
splitPath(projectFile, path, scriptname);
|
||||||
SplitFilename(scriptname, name, ext);
|
SplitFilename(scriptname, name, ext);
|
||||||
name := appendFileExt('compile_' + name, platform.os[targetOS].scriptExt);
|
name := appendFileExt('compile_' + name, platform.os[targetOS].scriptExt);
|
||||||
WriteRope(script, joinPath([path, genSubDir, name]));
|
WriteRope(script, joinPath(path, name));
|
||||||
end;
|
|
||||||
|
|
||||||
procedure addStr(var dest: string; const src: string);
|
|
||||||
begin
|
|
||||||
dest := dest +{&} src;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function getOptSpeed(c: TSystemCC): string;
|
function getOptSpeed(c: TSystemCC): string;
|
||||||
|
|
@ -420,17 +428,51 @@ begin
|
||||||
result := cc[c].optSize // use default settings from this file
|
result := cc[c].optSize // use default settings from this file
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
const
|
||||||
|
specialFileA = 42;
|
||||||
|
specialFileB = 42;
|
||||||
|
var
|
||||||
|
fileCounter: int;
|
||||||
|
|
||||||
function getCompileCFileCmd(const cfilename: string;
|
function getCompileCFileCmd(const cfilename: string;
|
||||||
isExternal: bool = false): string;
|
isExternal: bool = false): string;
|
||||||
var
|
var
|
||||||
cfile, objfile, options, includeCmd, compilePattern: string;
|
cfile, objfile, options, includeCmd, compilePattern, key, trunk, exe: string;
|
||||||
c: TSystemCC; // an alias to ccompiler
|
c: TSystemCC; // an alias to ccompiler
|
||||||
begin
|
begin
|
||||||
c := ccompiler;
|
c := ccompiler;
|
||||||
options := compileOptions;
|
options := compileOptions;
|
||||||
if optCDebug in gGlobalOptions then addStr(options, ' ' + getDebug(c));
|
trunk := getFileTrunk(cfilename);
|
||||||
if optOptimizeSpeed in gOptions then addStr(options, ' ' + getOptSpeed(c))
|
if optCDebug in gGlobalOptions then begin
|
||||||
else if optOptimizeSize in gOptions then addStr(options, ' ' + getOptSize(c));
|
key := trunk + '.debug';
|
||||||
|
if existsConfigVar(key) then
|
||||||
|
addOpt(options, getConfigVar(key))
|
||||||
|
else
|
||||||
|
addOpt(options, getDebug(c))
|
||||||
|
end;
|
||||||
|
if (optOptimizeSpeed in gOptions) then begin
|
||||||
|
//if ((fileCounter >= specialFileA) and (fileCounter <= specialFileB)) then
|
||||||
|
key := trunk + '.speed';
|
||||||
|
if existsConfigVar(key) then
|
||||||
|
addOpt(options, getConfigVar(key))
|
||||||
|
else
|
||||||
|
addOpt(options, getOptSpeed(c))
|
||||||
|
end
|
||||||
|
else if optOptimizeSize in gOptions then begin
|
||||||
|
key := trunk + '.size';
|
||||||
|
if existsConfigVar(key) then
|
||||||
|
addOpt(options, getConfigVar(key))
|
||||||
|
else
|
||||||
|
addOpt(options, getOptSize(c))
|
||||||
|
end;
|
||||||
|
key := trunk + '.always';
|
||||||
|
if existsConfigVar(key) then
|
||||||
|
addOpt(options, getConfigVar(key));
|
||||||
|
|
||||||
|
exe := cc[c].compilerExe;
|
||||||
|
key := cc[c].name + '.exe';
|
||||||
|
if existsConfigVar(key) then
|
||||||
|
exe := getConfigVar(key);
|
||||||
|
|
||||||
if (optGenDynLib in gGlobalOptions)
|
if (optGenDynLib in gGlobalOptions)
|
||||||
and (ospNeedsPIC in platform.OS[targetOS].props) then
|
and (ospNeedsPIC in platform.OS[targetOS].props) then
|
||||||
|
|
@ -441,8 +483,7 @@ begin
|
||||||
includeCmd := cc[c].includeCmd; // this is more complex than needed, but
|
includeCmd := cc[c].includeCmd; // this is more complex than needed, but
|
||||||
// a workaround of a FPC bug...
|
// a workaround of a FPC bug...
|
||||||
addStr(includeCmd, libpath);
|
addStr(includeCmd, libpath);
|
||||||
compilePattern := quoteIfSpaceExists(
|
compilePattern := quoteIfSpaceExists(JoinPath(ccompilerpath, exe));
|
||||||
JoinPath(ccompilerpath, cc[c].compilerExe));
|
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
includeCmd := '';
|
includeCmd := '';
|
||||||
|
|
@ -458,7 +499,7 @@ begin
|
||||||
else
|
else
|
||||||
objfile := completeCFilePath(toObjFile(cfile));
|
objfile := completeCFilePath(toObjFile(cfile));
|
||||||
|
|
||||||
result := compilePattern +{&} ' ' +{&} format(cc[c].compileTmpl,
|
result := format(compilePattern +{&} ' ' +{&} cc[c].compileTmpl,
|
||||||
['file', AppendFileExt(cfile, cExt),
|
['file', AppendFileExt(cfile, cExt),
|
||||||
'objfile', objfile,
|
'objfile', objfile,
|
||||||
'options', options,
|
'options', options,
|
||||||
|
|
@ -476,6 +517,7 @@ var
|
||||||
begin
|
begin
|
||||||
it := PStrEntry(list.head);
|
it := PStrEntry(list.head);
|
||||||
while it <> nil do begin
|
while it <> nil do begin
|
||||||
|
inc(fileCounter);
|
||||||
// call the C compiler for the .c file:
|
// call the C compiler for the .c file:
|
||||||
compileCmd := getCompileCFileCmd(it.data, isExternal);
|
compileCmd := getCompileCFileCmd(it.data, isExternal);
|
||||||
if not (optCompileOnly in gGlobalOptions) then
|
if not (optCompileOnly in gGlobalOptions) then
|
||||||
|
|
@ -491,16 +533,15 @@ end;
|
||||||
procedure CallCCompiler(const projectfile: string);
|
procedure CallCCompiler(const projectfile: string);
|
||||||
var
|
var
|
||||||
it: PStrEntry;
|
it: PStrEntry;
|
||||||
linkCmd, objfiles, exefile, buildgui, builddll: string;
|
linkCmd, objfiles, exefile, buildgui, builddll, linkerExe: string;
|
||||||
c: TSystemCC; // an alias to ccompiler
|
c: TSystemCC; // an alias to ccompiler
|
||||||
script: PRope;
|
script: PRope;
|
||||||
begin
|
begin
|
||||||
if (gGlobalOptions * [optCompileOnly, optGenScript] = [optCompileOnly]) then
|
if (gGlobalOptions * [optCompileOnly, optGenScript] = [optCompileOnly]) then
|
||||||
exit; // speed up that call if only compiling and no script shall be
|
exit; // speed up that call if only compiling and no script shall be
|
||||||
// generated
|
// generated
|
||||||
initVars();
|
|
||||||
if (toCompile.head = nil) and (externalToCompile.head = nil) then exit;
|
if (toCompile.head = nil) and (externalToCompile.head = nil) then exit;
|
||||||
//initVars();
|
fileCounter := 0;
|
||||||
c := ccompiler;
|
c := ccompiler;
|
||||||
script := nil;
|
script := nil;
|
||||||
CompileCFile(toCompile, script, false);
|
CompileCFile(toCompile, script, false);
|
||||||
|
|
@ -508,10 +549,13 @@ begin
|
||||||
|
|
||||||
if not (optNoLinking in gGlobalOptions) then begin
|
if not (optNoLinking in gGlobalOptions) then begin
|
||||||
// call the linker:
|
// call the linker:
|
||||||
|
linkerExe := getConfigVar(cc[c].name + '.linkerexe');
|
||||||
|
if length(linkerExe) = 0 then linkerExe := cc[c].linkerExe;
|
||||||
|
|
||||||
if (hostOS <> targetOS) then
|
if (hostOS <> targetOS) then
|
||||||
linkCmd := cc[c].linkerExe
|
linkCmd := linkerExe
|
||||||
else
|
else
|
||||||
linkCmd := quoteIfSpaceExists(JoinPath(ccompilerpath, cc[c].linkerExe));
|
linkCmd := quoteIfSpaceExists(JoinPath(ccompilerpath, linkerExe));
|
||||||
|
|
||||||
if optGenDynLib in gGlobalOptions then
|
if optGenDynLib in gGlobalOptions then
|
||||||
buildDll := cc[c].buildDll
|
buildDll := cc[c].buildDll
|
||||||
|
|
@ -546,7 +590,7 @@ begin
|
||||||
it := PStrEntry(it.next);
|
it := PStrEntry(it.next);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
linkCmd := linkCmd +{&} ' ' +{&} format(cc[c].linkTmpl, [
|
linkCmd := format(linkCmd +{&} ' ' +{&} cc[c].linkTmpl, [
|
||||||
'builddll', builddll,
|
'builddll', builddll,
|
||||||
'buildgui', buildgui,
|
'buildgui', buildgui,
|
||||||
'options', linkOptions,
|
'options', linkOptions,
|
||||||
|
|
@ -567,4 +611,28 @@ begin
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function genMappingFiles(const list: TLinkedList): PRope;
|
||||||
|
var
|
||||||
|
it: PStrEntry;
|
||||||
|
begin
|
||||||
|
result := nil;
|
||||||
|
it := PStrEntry(list.head);
|
||||||
|
while it <> nil do begin
|
||||||
|
appf(result, '--file:"$1"$n', [toRope(AppendFileExt(it.data, cExt))]);
|
||||||
|
it := PStrEntry(it.next);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure writeMapping(const cfile: string; gSymbolMapping: PRope);
|
||||||
|
var
|
||||||
|
code: PRope;
|
||||||
|
begin
|
||||||
|
if not (optGenMapping in gGlobalOptions) then exit;
|
||||||
|
code := toRope('[C_Files]'+nl);
|
||||||
|
app(code, genMappingFiles(toCompile));
|
||||||
|
app(code, genMappingFiles(externalToCompile));
|
||||||
|
appf(code, '[Symbols]$n$1', [gSymbolMapping]);
|
||||||
|
WriteRope(code, joinPath(projectPath, 'mapping.txt'));
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
|
||||||
493
nim/gpl.html
493
nim/gpl.html
|
|
@ -1,493 +0,0 @@
|
||||||
<!DOCTYPE html PUBLIC "-//IETF//DTD HTML 2.0//EN">
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>GNU General Public License - GNU Project - Free Software Foundation (FSF)</title>
|
|
||||||
</head>
|
|
||||||
<body bgcolor="#FFFFFF" text="#000000" link="#1F00FF" alink="#FF0000" vlink="#9900DD">
|
|
||||||
<h1>GNU General Public License</h1>
|
|
||||||
<hr>
|
|
||||||
<h2>Table of Contents</h2>
|
|
||||||
<ul>
|
|
||||||
<li><a name="TOC1" href="gpl.html#SEC1">GNU GENERAL PUBLIC LICENSE</a>
|
|
||||||
<ul>
|
|
||||||
<li><a name="TOC2" href="gpl.html#SEC2">Preamble</a>
|
|
||||||
<li><a name="TOC3" href="gpl.html#SEC3">TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</a>
|
|
||||||
<li><a name="TOC4" href="gpl.html#SEC4">How to Apply These Terms to Your New Programs</a>
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h2><a name="SEC1" href="gpl.html#TOC1">GNU GENERAL PUBLIC LICENSE</a></h2>
|
|
||||||
<p>
|
|
||||||
Version 2, June 1991
|
|
||||||
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
|
||||||
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h2><a name="SEC2" href="gpl.html#TOC2">Preamble</a></h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The licenses for most software are designed to take away your
|
|
||||||
freedom to share and change it. By contrast, the GNU General Public
|
|
||||||
License is intended to guarantee your freedom to share and change free
|
|
||||||
software--to make sure the software is free for all its users. This
|
|
||||||
General Public License applies to most of the Free Software
|
|
||||||
Foundation's software and to any other program whose authors commit to
|
|
||||||
using it. (Some other Free Software Foundation software is covered by
|
|
||||||
the GNU Library General Public License instead.) You can apply it to
|
|
||||||
your programs, too.
|
|
||||||
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
|
||||||
have the freedom to distribute copies of free software (and charge for
|
|
||||||
this service if you wish), that you receive source code or can get it
|
|
||||||
if you want it, that you can change the software or use pieces of it
|
|
||||||
in new free programs; and that you know you can do these things.
|
|
||||||
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
To protect your rights, we need to make restrictions that forbid
|
|
||||||
anyone to deny you these rights or to ask you to surrender the rights.
|
|
||||||
These restrictions translate to certain responsibilities for you if you
|
|
||||||
distribute copies of the software, or if you modify it.
|
|
||||||
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
For example, if you distribute copies of such a program, whether
|
|
||||||
gratis or for a fee, you must give the recipients all the rights that
|
|
||||||
you have. You must make sure that they, too, receive or can get the
|
|
||||||
source code. And you must show them these terms so they know their
|
|
||||||
rights.
|
|
||||||
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
We protect your rights with two steps: (1) copyright the software, and
|
|
||||||
(2) offer you this license which gives you legal permission to copy,
|
|
||||||
distribute and/or modify the software.
|
|
||||||
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Also, for each author's protection and ours, we want to make certain
|
|
||||||
that everyone understands that there is no warranty for this free
|
|
||||||
software. If the software is modified by someone else and passed on, we
|
|
||||||
want its recipients to know that what they have is not the original, so
|
|
||||||
that any problems introduced by others will not reflect on the original
|
|
||||||
authors' reputations.
|
|
||||||
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Finally, any free program is threatened constantly by software
|
|
||||||
patents. We wish to avoid the danger that redistributors of a free
|
|
||||||
program will individually obtain patent licenses, in effect making the
|
|
||||||
program proprietary. To prevent this, we have made it clear that any
|
|
||||||
patent must be licensed for everyone's free use or not licensed at all.
|
|
||||||
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
|
||||||
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
<h2><a name="SEC3" href="gpl.html#TOC3">TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</a></h2>
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
|
|
||||||
<strong>0.</strong>
|
|
||||||
This License applies to any program or other work which contains
|
|
||||||
a notice placed by the copyright holder saying it may be distributed
|
|
||||||
under the terms of this General Public License. The "Program", below,
|
|
||||||
refers to any such program or work, and a "work based on the Program"
|
|
||||||
means either the Program or any derivative work under copyright law:
|
|
||||||
that is to say, a work containing the Program or a portion of it,
|
|
||||||
either verbatim or with modifications and/or translated into another
|
|
||||||
language. (Hereinafter, translation is included without limitation in
|
|
||||||
the term "modification".) Each licensee is addressed as "you".
|
|
||||||
<p>
|
|
||||||
|
|
||||||
Activities other than copying, distribution and modification are not
|
|
||||||
covered by this License; they are outside its scope. The act of
|
|
||||||
running the Program is not restricted, and the output from the Program
|
|
||||||
is covered only if its contents constitute a work based on the
|
|
||||||
Program (independent of having been made by running the Program).
|
|
||||||
Whether that is true depends on what the Program does.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
|
|
||||||
<strong>1.</strong>
|
|
||||||
You may copy and distribute verbatim copies of the Program's
|
|
||||||
source code as you receive it, in any medium, provided that you
|
|
||||||
conspicuously and appropriately publish on each copy an appropriate
|
|
||||||
copyright notice and disclaimer of warranty; keep intact all the
|
|
||||||
notices that refer to this License and to the absence of any warranty;
|
|
||||||
and give any other recipients of the Program a copy of this License
|
|
||||||
along with the Program.
|
|
||||||
<p>
|
|
||||||
|
|
||||||
You may charge a fee for the physical act of transferring a copy, and
|
|
||||||
you may at your option offer warranty protection in exchange for a fee.
|
|
||||||
<p>
|
|
||||||
|
|
||||||
<strong>2.</strong>
|
|
||||||
You may modify your copy or copies of the Program or any portion
|
|
||||||
of it, thus forming a work based on the Program, and copy and
|
|
||||||
distribute such modifications or work under the terms of Section 1
|
|
||||||
above, provided that you also meet all of these conditions:
|
|
||||||
<p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
|
|
||||||
<li><strong>a)</strong>
|
|
||||||
You must cause the modified files to carry prominent notices
|
|
||||||
stating that you changed the files and the date of any change.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<li><strong>b)</strong>
|
|
||||||
You must cause any work that you distribute or publish, that in
|
|
||||||
whole or in part contains or is derived from the Program or any
|
|
||||||
part thereof, to be licensed as a whole at no charge to all third
|
|
||||||
parties under the terms of this License.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<li><strong>c)</strong>
|
|
||||||
If the modified program normally reads commands interactively
|
|
||||||
when run, you must cause it, when started running for such
|
|
||||||
interactive use in the most ordinary way, to print or display an
|
|
||||||
announcement including an appropriate copyright notice and a
|
|
||||||
notice that there is no warranty (or else, saying that you provide
|
|
||||||
a warranty) and that users may redistribute the program under
|
|
||||||
these conditions, and telling the user how to view a copy of this
|
|
||||||
License. (Exception: if the Program itself is interactive but
|
|
||||||
does not normally print such an announcement, your work based on
|
|
||||||
the Program is not required to print an announcement.)
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
These requirements apply to the modified work as a whole. If
|
|
||||||
identifiable sections of that work are not derived from the Program,
|
|
||||||
and can be reasonably considered independent and separate works in
|
|
||||||
themselves, then this License, and its terms, do not apply to those
|
|
||||||
sections when you distribute them as separate works. But when you
|
|
||||||
distribute the same sections as part of a whole which is a work based
|
|
||||||
on the Program, the distribution of the whole must be on the terms of
|
|
||||||
this License, whose permissions for other licensees extend to the
|
|
||||||
entire whole, and thus to each and every part regardless of who wrote it.
|
|
||||||
<p>
|
|
||||||
|
|
||||||
Thus, it is not the intent of this section to claim rights or contest
|
|
||||||
your rights to work written entirely by you; rather, the intent is to
|
|
||||||
exercise the right to control the distribution of derivative or
|
|
||||||
collective works based on the Program.
|
|
||||||
<p>
|
|
||||||
|
|
||||||
In addition, mere aggregation of another work not based on the Program
|
|
||||||
with the Program (or with a work based on the Program) on a volume of
|
|
||||||
a storage or distribution medium does not bring the other work under
|
|
||||||
the scope of this License.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
|
|
||||||
<strong>3.</strong>
|
|
||||||
You may copy and distribute the Program (or a work based on it,
|
|
||||||
under Section 2) in object code or executable form under the terms of
|
|
||||||
Sections 1 and 2 above provided that you also do one of the following:
|
|
||||||
|
|
||||||
|
|
||||||
<!-- we use this doubled UL to get the sub-sections indented, -->
|
|
||||||
<!-- while making the bullets as unobvious as possible. -->
|
|
||||||
<ul>
|
|
||||||
|
|
||||||
<li><strong>a)</strong>
|
|
||||||
Accompany it with the complete corresponding machine-readable
|
|
||||||
source code, which must be distributed under the terms of Sections
|
|
||||||
1 and 2 above on a medium customarily used for software interchange; or,
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<li><strong>b)</strong>
|
|
||||||
Accompany it with a written offer, valid for at least three
|
|
||||||
years, to give any third party, for a charge no more than your
|
|
||||||
cost of physically performing source distribution, a complete
|
|
||||||
machine-readable copy of the corresponding source code, to be
|
|
||||||
distributed under the terms of Sections 1 and 2 above on a medium
|
|
||||||
customarily used for software interchange; or,
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<li><strong>c)</strong>
|
|
||||||
Accompany it with the information you received as to the offer
|
|
||||||
to distribute corresponding source code. (This alternative is
|
|
||||||
allowed only for noncommercial distribution and only if you
|
|
||||||
received the program in object code or executable form with such
|
|
||||||
an offer, in accord with Subsection b above.)
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
The source code for a work means the preferred form of the work for
|
|
||||||
making modifications to it. For an executable work, complete source
|
|
||||||
code means all the source code for all modules it contains, plus any
|
|
||||||
associated interface definition files, plus the scripts used to
|
|
||||||
control compilation and installation of the executable. However, as a
|
|
||||||
special exception, the source code distributed need not include
|
|
||||||
anything that is normally distributed (in either source or binary
|
|
||||||
form) with the major components (compiler, kernel, and so on) of the
|
|
||||||
operating system on which the executable runs, unless that component
|
|
||||||
itself accompanies the executable.
|
|
||||||
<p>
|
|
||||||
|
|
||||||
If distribution of executable or object code is made by offering
|
|
||||||
access to copy from a designated place, then offering equivalent
|
|
||||||
access to copy the source code from the same place counts as
|
|
||||||
distribution of the source code, even though third parties are not
|
|
||||||
compelled to copy the source along with the object code.
|
|
||||||
<p>
|
|
||||||
|
|
||||||
<strong>4.</strong>
|
|
||||||
You may not copy, modify, sublicense, or distribute the Program
|
|
||||||
except as expressly provided under this License. Any attempt
|
|
||||||
otherwise to copy, modify, sublicense or distribute the Program is
|
|
||||||
void, and will automatically terminate your rights under this License.
|
|
||||||
However, parties who have received copies, or rights, from you under
|
|
||||||
this License will not have their licenses terminated so long as such
|
|
||||||
parties remain in full compliance.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
|
|
||||||
<strong>5.</strong>
|
|
||||||
You are not required to accept this License, since you have not
|
|
||||||
signed it. However, nothing else grants you permission to modify or
|
|
||||||
distribute the Program or its derivative works. These actions are
|
|
||||||
prohibited by law if you do not accept this License. Therefore, by
|
|
||||||
modifying or distributing the Program (or any work based on the
|
|
||||||
Program), you indicate your acceptance of this License to do so, and
|
|
||||||
all its terms and conditions for copying, distributing or modifying
|
|
||||||
the Program or works based on it.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
|
|
||||||
<strong>6.</strong>
|
|
||||||
Each time you redistribute the Program (or any work based on the
|
|
||||||
Program), the recipient automatically receives a license from the
|
|
||||||
original licensor to copy, distribute or modify the Program subject to
|
|
||||||
these terms and conditions. You may not impose any further
|
|
||||||
restrictions on the recipients' exercise of the rights granted herein.
|
|
||||||
You are not responsible for enforcing compliance by third parties to
|
|
||||||
this License.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
|
|
||||||
<strong>7.</strong>
|
|
||||||
If, as a consequence of a court judgment or allegation of patent
|
|
||||||
infringement or for any other reason (not limited to patent issues),
|
|
||||||
conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot
|
|
||||||
distribute so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you
|
|
||||||
may not distribute the Program at all. For example, if a patent
|
|
||||||
license would not permit royalty-free redistribution of the Program by
|
|
||||||
all those who receive copies directly or indirectly through you, then
|
|
||||||
the only way you could satisfy both it and this License would be to
|
|
||||||
refrain entirely from distribution of the Program.
|
|
||||||
<p>
|
|
||||||
|
|
||||||
If any portion of this section is held invalid or unenforceable under
|
|
||||||
any particular circumstance, the balance of the section is intended to
|
|
||||||
apply and the section as a whole is intended to apply in other
|
|
||||||
circumstances.
|
|
||||||
<p>
|
|
||||||
|
|
||||||
It is not the purpose of this section to induce you to infringe any
|
|
||||||
patents or other property right claims or to contest validity of any
|
|
||||||
such claims; this section has the sole purpose of protecting the
|
|
||||||
integrity of the free software distribution system, which is
|
|
||||||
implemented by public license practices. Many people have made
|
|
||||||
generous contributions to the wide range of software distributed
|
|
||||||
through that system in reliance on consistent application of that
|
|
||||||
system; it is up to the author/donor to decide if he or she is willing
|
|
||||||
to distribute software through any other system and a licensee cannot
|
|
||||||
impose that choice.
|
|
||||||
<p>
|
|
||||||
|
|
||||||
This section is intended to make thoroughly clear what is believed to
|
|
||||||
be a consequence of the rest of this License.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
|
|
||||||
<strong>8.</strong>
|
|
||||||
If the distribution and/or use of the Program is restricted in
|
|
||||||
certain countries either by patents or by copyrighted interfaces, the
|
|
||||||
original copyright holder who places the Program under this License
|
|
||||||
may add an explicit geographical distribution limitation excluding
|
|
||||||
those countries, so that distribution is permitted only in or among
|
|
||||||
countries not thus excluded. In such case, this License incorporates
|
|
||||||
the limitation as if written in the body of this License.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
|
|
||||||
<strong>9.</strong>
|
|
||||||
The Free Software Foundation may publish revised and/or new versions
|
|
||||||
of the General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
<p>
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Program
|
|
||||||
specifies a version number of this License which applies to it and "any
|
|
||||||
later version", you have the option of following the terms and conditions
|
|
||||||
either of that version or of any later version published by the Free
|
|
||||||
Software Foundation. If the Program does not specify a version number of
|
|
||||||
this License, you may choose any version ever published by the Free Software
|
|
||||||
Foundation.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
|
|
||||||
|
|
||||||
<strong>10.</strong>
|
|
||||||
If you wish to incorporate parts of the Program into other free
|
|
||||||
programs whose distribution conditions are different, write to the author
|
|
||||||
to ask for permission. For software which is copyrighted by the Free
|
|
||||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
|
||||||
make exceptions for this. Our decision will be guided by the two goals
|
|
||||||
of preserving the free status of all derivatives of our free software and
|
|
||||||
of promoting the sharing and reuse of software generally.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<p><strong>NO WARRANTY</strong></p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
|
|
||||||
<strong>11.</strong>
|
|
||||||
BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
|
||||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
|
||||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
|
||||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
|
||||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
|
||||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
|
||||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
|
||||||
REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
|
|
||||||
<strong>12.</strong>
|
|
||||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
|
||||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
|
||||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
|
||||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
|
||||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
|
||||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
|
||||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
|
||||||
POSSIBILITY OF SUCH DAMAGES.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
|
|
||||||
|
|
||||||
<h2>END OF TERMS AND CONDITIONS</h2>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h2><a name="SEC4" href="gpl.html#TOC4">How to Apply These Terms to Your New Programs</a></h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these terms.
|
|
||||||
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
convey the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
<var>one line to give the program's name and an idea of what it does.</var>
|
|
||||||
Copyright (C) <var>yyyy</var> <var>name of author</var>
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
If the program is interactive, make it output a short notice like this
|
|
||||||
when it starts in an interactive mode:
|
|
||||||
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
Gnomovision version 69, Copyright (C) <var>year</var> <var>name of author</var>
|
|
||||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
|
|
||||||
type `show w'. This is free software, and you are welcome
|
|
||||||
to redistribute it under certain conditions; type `show c'
|
|
||||||
for details.
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The hypothetical commands <samp>`show w'</samp> and <samp>`show c'</samp> should show
|
|
||||||
the appropriate parts of the General Public License. Of course, the
|
|
||||||
commands you use may be called something other than <samp>`show w'</samp> and
|
|
||||||
<samp>`show c'</samp>; they could even be mouse-clicks or menu items--whatever
|
|
||||||
suits your program.
|
|
||||||
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
You should also get your employer (if you work as a programmer) or your
|
|
||||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
|
||||||
necessary. Here is a sample; alter the names:
|
|
||||||
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
Yoyodyne, Inc., hereby disclaims all copyright
|
|
||||||
interest in the program `Gnomovision'
|
|
||||||
(which makes passes at compilers) written
|
|
||||||
by James Hacker.
|
|
||||||
|
|
||||||
<var>signature of Ty Coon</var>, 1 April 1989
|
|
||||||
Ty Coon, President of Vice
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This General Public License does not permit incorporating your program into
|
|
||||||
proprietary programs. If your program is a subroutine library, you may
|
|
||||||
consider it more useful to permit linking proprietary applications with the
|
|
||||||
library. If this is what you want to do, use the GNU Library General
|
|
||||||
Public License instead of this License.
|
|
||||||
</body></html>
|
|
||||||
|
|
@ -8,6 +8,8 @@
|
||||||
//
|
//
|
||||||
unit hashes;
|
unit hashes;
|
||||||
|
|
||||||
|
{$include 'config.inc'}
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
|
|
|
||||||
|
|
@ -358,7 +358,7 @@ begin
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
g.len := pos - g.pos;
|
g.len := pos - g.pos;
|
||||||
assert((g.kind = gtEof) or (g.len > 0));
|
if (g.kind <> gtEof) and (g.len <= 0) then InternalError('nimNextToken');
|
||||||
g.pos := pos;
|
g.pos := pos;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -633,7 +633,7 @@ begin
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
g.len := pos - g.pos;
|
g.len := pos - g.pos;
|
||||||
assert((g.kind = gtEof) or (g.len > 0));
|
if (g.kind <> gtEof) and (g.len <= 0) then InternalError('clikeNextToken');
|
||||||
g.pos := pos;
|
g.pos := pos;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -711,7 +711,7 @@ begin
|
||||||
langCsharp: csharpNextToken(g);
|
langCsharp: csharpNextToken(g);
|
||||||
langC: cNextToken(g);
|
langC: cNextToken(g);
|
||||||
langJava: javaNextToken(g);
|
langJava: javaNextToken(g);
|
||||||
else assert(false);
|
else InternalError('getNextToken');
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ type
|
||||||
s: string;
|
s: string;
|
||||||
next: PIdent; // for hash-table chaining
|
next: PIdent; // for hash-table chaining
|
||||||
h: THash; // hash value of s
|
h: THash; // hash value of s
|
||||||
end;
|
end {@acyclic};
|
||||||
|
|
||||||
function getIdent(const identifier: string): PIdent; overload;
|
function getIdent(const identifier: string): PIdent; overload;
|
||||||
function getIdent(const identifier: string; h: THash): PIdent; overload;
|
function getIdent(const identifier: string; h: THash): PIdent; overload;
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,26 @@
|
||||||
// See the file "copying.txt", included in this
|
// See the file "copying.txt", included in this
|
||||||
// distribution, for details about the copyright.
|
// distribution, for details about the copyright.
|
||||||
//
|
//
|
||||||
|
unit importer;
|
||||||
|
|
||||||
// This module implements the symbol importing mechanism.
|
// This module implements the symbol importing mechanism.
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
{$include 'config.inc'}
|
||||||
|
|
||||||
|
uses
|
||||||
|
nsystem, charsets, strutils, nos,
|
||||||
|
ast, astalgo, msgs, options, idents, rodread, lookups, semdata, passes;
|
||||||
|
|
||||||
|
function evalImport(c: PContext; n: PNode): PNode;
|
||||||
|
function evalFrom(c: PContext; n: PNode): PNode;
|
||||||
|
procedure importAllSymbols(c: PContext; fromMod: PSym);
|
||||||
|
|
||||||
|
function getModuleFile(n: PNode): string;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
function findModule(const info: TLineInfo; const modulename: string): string;
|
function findModule(const info: TLineInfo; const modulename: string): string;
|
||||||
// returns path to module
|
// returns path to module
|
||||||
begin
|
begin
|
||||||
|
|
@ -41,32 +58,45 @@ var
|
||||||
check, copy, e: PSym;
|
check, copy, e: PSym;
|
||||||
j: int;
|
j: int;
|
||||||
etyp: PType; // enumeration type
|
etyp: PType; // enumeration type
|
||||||
|
it: TIdentIter;
|
||||||
begin
|
begin
|
||||||
//copy := copySym(s, true);
|
// This does not handle stubs, because otherwise loading on demand would be
|
||||||
//copy.ast := s.ast;
|
// basically pointless. So importing stubs is fine here!
|
||||||
copy := s; // do not copy symbols when importing!
|
copy := s; // do not copy symbols when importing!
|
||||||
// check if we have already a symbol of the same name:
|
// check if we have already a symbol of the same name:
|
||||||
check := StrTableGet(c.tab.stack[importTablePos], s.name);
|
check := StrTableGet(c.tab.stack[importTablePos], s.name);
|
||||||
if check <> nil then begin
|
if (check <> nil) and (check.id <> copy.id) then begin
|
||||||
if not (s.kind in OverloadableSyms) then begin
|
if not (s.kind in OverloadableSyms) then begin
|
||||||
{@discard} StrTableIncl(c.AmbigiousSymbols, copy);
|
// s and check need to be qualified:
|
||||||
{@discard} StrTableIncl(c.AmbigiousSymbols, check);
|
IntSetIncl(c.AmbigiousSymbols, copy.id);
|
||||||
// s and check need to be qualified
|
IntSetIncl(c.AmbigiousSymbols, check.id);
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
StrTableAdd(c.tab.stack[importTablePos], copy);
|
StrTableAdd(c.tab.stack[importTablePos], copy);
|
||||||
if s.kind = skType then begin
|
if s.kind = skType then begin
|
||||||
etyp := s.typ;
|
etyp := s.typ;
|
||||||
if etyp.kind = tyEnum then begin
|
if etyp.kind in [tyBool, tyEnum] then begin
|
||||||
for j := 0 to sonsLen(etyp.n)-1 do begin
|
for j := 0 to sonsLen(etyp.n)-1 do begin
|
||||||
e := etyp.n.sons[j].sym;
|
e := etyp.n.sons[j].sym;
|
||||||
if (e.Kind = skEnumField) then rawImportSymbol(c, e)
|
if (e.Kind <> skEnumField) then
|
||||||
else InternalError(s.info, 'rawImportSymbol');
|
InternalError(s.info, 'rawImportSymbol');
|
||||||
|
// BUGFIX: because of aliases for enums the symbol may already
|
||||||
|
// have been put into the symbol table
|
||||||
|
// BUGFIX: but only iff they are the same symbols!
|
||||||
|
check := InitIdentIter(it, c.tab.stack[importTablePos], e.name);
|
||||||
|
while check <> nil do begin
|
||||||
|
if check.id = e.id then begin e := nil; break end;
|
||||||
|
check := NextIdentIter(it, c.tab.stack[importTablePos]);
|
||||||
|
end;
|
||||||
|
if e <> nil then rawImportSymbol(c, e);
|
||||||
|
//check := StrTableGet(c.tab.stack[importTablePos], e.name);
|
||||||
|
//if (check = nil) or (check.id <> e.id) then
|
||||||
|
// rawImportSymbol(c, e)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else if s.kind = skConverter then
|
else if s.kind = skConverter then
|
||||||
addConverter(c, s);
|
addConverter(c, s); // rodgen assures that converters are no stubs
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure importSymbol(c: PContext; ident: PNode; fromMod: PSym);
|
procedure importSymbol(c: PContext; ident: PNode; fromMod: PSym);
|
||||||
|
|
@ -78,6 +108,7 @@ begin
|
||||||
s := StrTableGet(fromMod.tab, ident.ident);
|
s := StrTableGet(fromMod.tab, ident.ident);
|
||||||
if s = nil then
|
if s = nil then
|
||||||
liMessage(ident.info, errUndeclaredIdentifier, ident.ident.s);
|
liMessage(ident.info, errUndeclaredIdentifier, ident.ident.s);
|
||||||
|
if s.kind = skStub then loadStub(s);
|
||||||
if not (s.Kind in ExportableSymKinds) then
|
if not (s.Kind in ExportableSymKinds) then
|
||||||
InternalError(ident.info, 'importSymbol: 2');
|
InternalError(ident.info, 'importSymbol: 2');
|
||||||
// for an enumeration we have to add all identifiers
|
// for an enumeration we have to add all identifiers
|
||||||
|
|
@ -106,7 +137,7 @@ begin
|
||||||
if s.kind <> skModule then begin
|
if s.kind <> skModule then begin
|
||||||
if s.kind <> skEnumField then begin
|
if s.kind <> skEnumField then begin
|
||||||
if not (s.Kind in ExportableSymKinds) then
|
if not (s.Kind in ExportableSymKinds) then
|
||||||
InternalError(s.info, 'importAllSymbols');
|
InternalError(s.info, 'importAllSymbols: ' + symKindToStr[s.kind]);
|
||||||
rawImportSymbol(c, s); // this is correct!
|
rawImportSymbol(c, s); // this is correct!
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
@ -118,14 +149,15 @@ function evalImport(c: PContext; n: PNode): PNode;
|
||||||
var
|
var
|
||||||
m: PSym;
|
m: PSym;
|
||||||
i: int;
|
i: int;
|
||||||
|
f: string;
|
||||||
begin
|
begin
|
||||||
result := copyNode(n);
|
result := n;
|
||||||
for i := 0 to sonsLen(n)-1 do begin
|
for i := 0 to sonsLen(n)-1 do begin
|
||||||
m := c.ImportModule(getModuleFile(n.sons[i]), c.b);
|
f := getModuleFile(n.sons[i]);
|
||||||
|
m := gImportModule(f);
|
||||||
// ``addDecl`` needs to be done before ``importAllSymbols``!
|
// ``addDecl`` needs to be done before ``importAllSymbols``!
|
||||||
addDecl(c, m); // add symbol to symbol table of module
|
addDecl(c, m); // add symbol to symbol table of module
|
||||||
importAllSymbols(c, m);
|
importAllSymbols(c, m);
|
||||||
addSon(result, newSymNode(m));
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -133,24 +165,15 @@ function evalFrom(c: PContext; n: PNode): PNode;
|
||||||
var
|
var
|
||||||
m: PSym;
|
m: PSym;
|
||||||
i: int;
|
i: int;
|
||||||
|
f: string;
|
||||||
begin
|
begin
|
||||||
result := n;
|
result := n;
|
||||||
checkMinSonsLen(n, 2);
|
checkMinSonsLen(n, 2);
|
||||||
m := c.ImportModule(getModuleFile(n.sons[0]), c.b);
|
f := getModuleFile(n.sons[0]);
|
||||||
|
m := gImportModule(f);
|
||||||
n.sons[0] := newSymNode(m);
|
n.sons[0] := newSymNode(m);
|
||||||
addDecl(c, m); // add symbol to symbol table of module
|
addDecl(c, m); // add symbol to symbol table of module
|
||||||
for i := 1 to sonsLen(n)-1 do importSymbol(c, n.sons[i], m);
|
for i := 1 to sonsLen(n)-1 do importSymbol(c, n.sons[i], m);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function evalInclude(c: PContext; n: PNode): PNode;
|
end.
|
||||||
var
|
|
||||||
i: int;
|
|
||||||
x: PNode;
|
|
||||||
begin
|
|
||||||
result := newNodeI(nkStmtList, n.info);
|
|
||||||
for i := 0 to sonsLen(n)-1 do begin
|
|
||||||
x := c.includeFile(getModuleFile(n.sons[i]));
|
|
||||||
x := semStmt(c, x);
|
|
||||||
addSon(result, x);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
|
||||||
267
nim/instgen.pas
267
nim/instgen.pas
|
|
@ -1,267 +0,0 @@
|
||||||
//
|
|
||||||
//
|
|
||||||
// The Nimrod Compiler
|
|
||||||
// (c) Copyright 2008 Andreas Rumpf
|
|
||||||
//
|
|
||||||
// See the file "copying.txt", included in this
|
|
||||||
// distribution, for details about the copyright.
|
|
||||||
//
|
|
||||||
|
|
||||||
// This module does the instantiation of generic procs and types.
|
|
||||||
|
|
||||||
function generateInstance(c: PContext; fn: PSym; const pt: TIdTable;
|
|
||||||
const instantiator: TLineInfo): PSym; forward;
|
|
||||||
// generates an instantiated proc
|
|
||||||
|
|
||||||
type
|
|
||||||
TInstantiateClosure = object(NObject)
|
|
||||||
mapping: TIdTable; // map {ptype, psym} to {ptype, psym}
|
|
||||||
fn: PSym;
|
|
||||||
module: PSym;
|
|
||||||
newOwner: PSym;
|
|
||||||
instantiator: TLineInfo;
|
|
||||||
end;
|
|
||||||
PInstantiateClosure = ^TInstantiateClosure;
|
|
||||||
PInstClosure = PInstantiateClosure;
|
|
||||||
|
|
||||||
function instantiateTree(c: PInstantiateClosure; t: PNode): PNode; forward;
|
|
||||||
function instantiateSym(c: PInstantiateClosure; sym: PSym): PSym; forward;
|
|
||||||
function instantiateType(c: PInstantiateClosure; typ: PType): PType; forward;
|
|
||||||
|
|
||||||
function containsGenericTypeIter(t: PType; closure: PObject): bool;
|
|
||||||
begin
|
|
||||||
result := t.kind in GenericTypes;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function containsGenericType(t: PType): bool;
|
|
||||||
begin
|
|
||||||
result := iterOverType(t, containsGenericTypeIter, nil);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function instTypeNode(c: PInstantiateClosure; n: PNode): PNode;
|
|
||||||
var
|
|
||||||
i: int;
|
|
||||||
begin
|
|
||||||
result := nil;
|
|
||||||
if n <> nil then begin
|
|
||||||
result := copyNode(n);
|
|
||||||
result.typ := instantiateType(c, n.typ);
|
|
||||||
case n.kind of
|
|
||||||
nkNone..nkNilLit: begin // a leaf
|
|
||||||
end;
|
|
||||||
else begin
|
|
||||||
for i := 0 to sonsLen(n)-1 do
|
|
||||||
addSon(result, instTypeNode(c, n.sons[i]));
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end;
|
|
||||||
|
|
||||||
function instantiateType(c: PInstantiateClosure; typ: PType): PType;
|
|
||||||
var
|
|
||||||
i: int;
|
|
||||||
begin
|
|
||||||
result := PType(idTableGet(c.mapping, typ));
|
|
||||||
if result <> nil then exit;
|
|
||||||
if containsGenericType(typ) then begin
|
|
||||||
result := copyType(typ, c.newOwner);
|
|
||||||
idTablePut(c.mapping, typ, result); // to avoid cycles
|
|
||||||
for i := 0 to sonsLen(result)-1 do
|
|
||||||
result.sons[i] := instantiateType(c, result.sons[i]);
|
|
||||||
if result.n <> nil then
|
|
||||||
result.n := instTypeNode(c, result.n);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
result := typ;
|
|
||||||
if result.Kind in GenericTypes then begin
|
|
||||||
liMessage(c.instantiator, errCannotInstantiateX,
|
|
||||||
TypeToString(typ, preferName));
|
|
||||||
end
|
|
||||||
else if result.kind = tyVar then begin
|
|
||||||
if result.sons[0].kind = tyVar then
|
|
||||||
liMessage(c.instantiator, errVarVarTypeNotAllowed);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function instantiateSym(c: PInstantiateClosure; sym: PSym): PSym;
|
|
||||||
begin
|
|
||||||
if sym = nil then begin result := nil; exit end; // BUGFIX
|
|
||||||
result := PSym(idTableGet(c.mapping, sym));
|
|
||||||
if (result = nil) then begin
|
|
||||||
if (sym.owner.id = c.fn.id) or (sym.id = c.fn.id) then begin
|
|
||||||
result := copySym(sym);
|
|
||||||
if sym.id = c.fn.id then c.newOwner := result;
|
|
||||||
include(result.flags, sfIsCopy);
|
|
||||||
idTablePut(c.mapping, sym, result); // BUGFIX
|
|
||||||
result.typ := instantiateType(c, sym.typ);
|
|
||||||
if (result.owner <> nil) and (result.owner.kind = skModule) then
|
|
||||||
result.owner := c.module // BUGFIX
|
|
||||||
else
|
|
||||||
result.owner := instantiateSym(c, result.owner);
|
|
||||||
if sym.ast <> nil then begin
|
|
||||||
result.ast := instantiateTree(c, sym.ast);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
result := sym // do not copy t!
|
|
||||||
end
|
|
||||||
end;
|
|
||||||
|
|
||||||
function instantiateTree(c: PInstantiateClosure; t: PNode): PNode;
|
|
||||||
var
|
|
||||||
len, i: int;
|
|
||||||
begin
|
|
||||||
if t = nil then begin result := nil; exit end;
|
|
||||||
result := copyNode(t);
|
|
||||||
if result.typ <> nil then result.typ := instantiateType(c, result.typ);
|
|
||||||
case t.kind of
|
|
||||||
nkNone..pred(nkSym), succ(nkSym)..nkNilLit: begin end;
|
|
||||||
nkSym: begin
|
|
||||||
if result.sym <> nil then result.sym := instantiateSym(c, result.sym);
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
len := sonsLen(t);
|
|
||||||
if len > 0 then begin
|
|
||||||
newSons(result, len);
|
|
||||||
for i := 0 to len-1 do
|
|
||||||
result.sons[i] := instantiateTree(c, t.sons[i]);
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure instantiateGenericParamList(c: PContext; n: PNode;
|
|
||||||
const pt: TIdTable);
|
|
||||||
var
|
|
||||||
i: int;
|
|
||||||
s, q: PSym;
|
|
||||||
t: PType;
|
|
||||||
begin
|
|
||||||
assert(n.kind = nkGenericParams);
|
|
||||||
for i := 0 to sonsLen(n)-1 do begin
|
|
||||||
if n.sons[i].kind = nkDefaultTypeParam then begin
|
|
||||||
internalError(n.sons[i].info,
|
|
||||||
'instantiateGenericParamList() to implement');
|
|
||||||
// XXX
|
|
||||||
end;
|
|
||||||
assert(n.sons[i].kind = nkSym);
|
|
||||||
q := n.sons[i].sym;
|
|
||||||
s := newSym(skType, q.name, getCurrOwner(c));
|
|
||||||
t := PType(IdTableGet(pt, q.typ));
|
|
||||||
if t = nil then
|
|
||||||
liMessage(n.sons[i].info, errCannotInstantiateX, s.name.s);
|
|
||||||
assert(t.kind <> tyGenericParam);
|
|
||||||
s.typ := t;
|
|
||||||
addDecl(c, s);
|
|
||||||
end
|
|
||||||
end;
|
|
||||||
|
|
||||||
function GenericCacheGet(c: PContext; genericSym, instSym: PSym): PSym;
|
|
||||||
var
|
|
||||||
i: int;
|
|
||||||
a, b: PSym;
|
|
||||||
begin
|
|
||||||
result := nil;
|
|
||||||
for i := 0 to sonsLen(c.generics)-1 do begin
|
|
||||||
if c.generics.sons[i].kind <> nkExprEqExpr then
|
|
||||||
InternalError(genericSym.info, 'GenericCacheGet');
|
|
||||||
a := c.generics.sons[i].sons[0].sym;
|
|
||||||
if genericSym.id = a.id then begin
|
|
||||||
b := c.generics.sons[i].sons[1].sym;
|
|
||||||
if equalParams(b.typ.n, instSym.typ.n) = paramsEqual then begin
|
|
||||||
result := b; exit
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure GenericCacheAdd(c: PContext; genericSym, instSym: PSym);
|
|
||||||
var
|
|
||||||
n: PNode;
|
|
||||||
begin
|
|
||||||
n := newNode(nkExprEqExpr);
|
|
||||||
addSon(n, newSymNode(genericSym));
|
|
||||||
addSon(n, newSymNode(instSym));
|
|
||||||
addSon(c.generics, n);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure semParamList(c: PContext; n: PNode; s: PSym); forward;
|
|
||||||
procedure addParams(c: PContext; n: PNode); forward;
|
|
||||||
procedure addResult(c: PContext; t: PType; const info: TLineInfo); forward;
|
|
||||||
procedure addResultNode(c: PContext; n: PNode); forward;
|
|
||||||
|
|
||||||
function generateInstance(c: PContext; fn: PSym; const pt: TIdTable;
|
|
||||||
const instantiator: TLineInfo): PSym;
|
|
||||||
// generates an instantiated proc
|
|
||||||
var
|
|
||||||
oldPrc: PSym;
|
|
||||||
oldP: PProcCon;
|
|
||||||
n: PNode;
|
|
||||||
begin
|
|
||||||
oldP := c.p; // restore later
|
|
||||||
result := copySym(fn);
|
|
||||||
result.owner := getCurrOwner(c);
|
|
||||||
n := copyTree(fn.ast);
|
|
||||||
result.ast := n;
|
|
||||||
pushOwner(c, result);
|
|
||||||
openScope(c.tab);
|
|
||||||
assert(n.sons[genericParamsPos] <> nil);
|
|
||||||
n.sons[namePos] := newSymNode(result);
|
|
||||||
pushInfoContext(instantiator);
|
|
||||||
|
|
||||||
instantiateGenericParamList(c, n.sons[genericParamsPos], pt);
|
|
||||||
n.sons[genericParamsPos] := nil;
|
|
||||||
// semantic checking for the parameters:
|
|
||||||
if n.sons[paramsPos] <> nil then begin
|
|
||||||
semParamList(c, n.sons[ParamsPos], result);
|
|
||||||
addParams(c, result.typ.n);
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
result.typ := newTypeS(tyProc, c);
|
|
||||||
addSon(result.typ, nil);
|
|
||||||
end;
|
|
||||||
|
|
||||||
// now check if we have already such a proc generated
|
|
||||||
oldPrc := GenericCacheGet(c, fn, result);
|
|
||||||
if oldPrc = nil then begin
|
|
||||||
// add it here, so that recursive generic procs are possible:
|
|
||||||
addDecl(c, result);
|
|
||||||
if n.sons[codePos] <> nil then begin
|
|
||||||
c.p := newProcCon(result);
|
|
||||||
if result.kind in [skProc, skConverter] then begin
|
|
||||||
addResult(c, result.typ.sons[0], n.info);
|
|
||||||
addResultNode(c, n);
|
|
||||||
end;
|
|
||||||
n.sons[codePos] := semStmtScope(c, n.sons[codePos]);
|
|
||||||
end;
|
|
||||||
GenericCacheAdd(c, fn, result);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
result := oldPrc;
|
|
||||||
popInfoContext();
|
|
||||||
closeScope(c.tab); // close scope for parameters
|
|
||||||
popOwner(c);
|
|
||||||
c.p := oldP; // restore
|
|
||||||
end;
|
|
||||||
|
|
||||||
function generateTypeInstance(p: PContext; const pt: TIdTable;
|
|
||||||
const instantiator: TLineInfo; t: PType): PType;
|
|
||||||
var
|
|
||||||
c: PInstantiateClosure;
|
|
||||||
begin
|
|
||||||
new(c);
|
|
||||||
{@ignore}
|
|
||||||
fillChar(c^, sizeof(c^), 0);
|
|
||||||
{@emit}
|
|
||||||
c.mapping := pt; // making a copy is not necessary
|
|
||||||
c.fn := nil;
|
|
||||||
c.instantiator := instantiator;
|
|
||||||
c.module := p.module;
|
|
||||||
c.newOwner := getCurrOwner(p);
|
|
||||||
result := instantiateType(c, t);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function partialSpecialization(c: PContext; n: PNode; s: PSym): PNode;
|
|
||||||
begin
|
|
||||||
result := n;
|
|
||||||
end;
|
|
||||||
|
|
@ -16,7 +16,7 @@ unit lexbase;
|
||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
nsystem, charsets, strutils;
|
nsystem, llstream, charsets, strutils;
|
||||||
|
|
||||||
{@emit
|
{@emit
|
||||||
const
|
const
|
||||||
|
|
@ -44,25 +44,21 @@ const
|
||||||
type
|
type
|
||||||
TBaseLexer = object(NObject)
|
TBaseLexer = object(NObject)
|
||||||
bufpos: int;
|
bufpos: int;
|
||||||
buf: PChar; // NOT zero terminated!
|
buf: PChar;
|
||||||
bufLen: int; // length of buffer in characters
|
bufLen: int; // length of buffer in characters
|
||||||
f: TBinaryFile; // we use a binary file here for efficiency
|
stream: PLLStream; // we read from this stream
|
||||||
LineNumber: int; // the current line number
|
LineNumber: int; // the current line number
|
||||||
// private data:
|
// private data:
|
||||||
sentinel: int;
|
sentinel: int;
|
||||||
lineStart: int; // index of last line start in buffer
|
lineStart: int; // index of last line start in buffer
|
||||||
fileOpened: boolean;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function initBaseLexer(out L: TBaseLexer;
|
procedure openBaseLexer(out L: TBaseLexer;
|
||||||
const filename: string;
|
inputstream: PLLStream;
|
||||||
bufLen: int = 8192): boolean;
|
bufLen: int = 8192);
|
||||||
// 8K is a reasonable buffer size
|
// 8K is a reasonable buffer size
|
||||||
|
|
||||||
procedure initBaseLexerFromBuffer(out L: TBaseLexer;
|
procedure closeBaseLexer(var L: TBaseLexer);
|
||||||
const buffer: string);
|
|
||||||
|
|
||||||
procedure deinitBaseLexer(var L: TBaseLexer);
|
|
||||||
|
|
||||||
function getCurrentLine(const L: TBaseLexer; marker: boolean = true): string;
|
function getCurrentLine(const L: TBaseLexer; marker: boolean = true): string;
|
||||||
function getColNumber(const L: TBaseLexer; pos: int): int;
|
function getColNumber(const L: TBaseLexer; pos: int): int;
|
||||||
|
|
@ -82,10 +78,10 @@ implementation
|
||||||
const
|
const
|
||||||
chrSize = sizeof(char);
|
chrSize = sizeof(char);
|
||||||
|
|
||||||
procedure deinitBaseLexer(var L: TBaseLexer);
|
procedure closeBaseLexer(var L: TBaseLexer);
|
||||||
begin
|
begin
|
||||||
dealloc(L.buf);
|
dealloc(L.buf);
|
||||||
if L.fileOpened then closeFile(L.f);
|
LLStreamClose(L.stream);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@ignore}
|
{@ignore}
|
||||||
|
|
@ -119,8 +115,8 @@ begin
|
||||||
if toCopy > 0 then
|
if toCopy > 0 then
|
||||||
MoveMem(L.buf, addr(L.buf[L.sentinel+1]), toCopy * chrSize);
|
MoveMem(L.buf, addr(L.buf[L.sentinel+1]), toCopy * chrSize);
|
||||||
// "moveMem" handles overlapping regions
|
// "moveMem" handles overlapping regions
|
||||||
charsRead := ReadBuffer(L.f, addr(L.buf[toCopy]), (L.sentinel+1) * chrSize)
|
charsRead := LLStreamRead(L.stream, addr(L.buf[toCopy]),
|
||||||
div chrSize;
|
(L.sentinel+1) * chrSize) div chrSize;
|
||||||
s := toCopy + charsRead;
|
s := toCopy + charsRead;
|
||||||
if charsRead < L.sentinel+1 then begin
|
if charsRead < L.sentinel+1 then begin
|
||||||
L.buf[s] := EndOfFile; // set end marker
|
L.buf[s] := EndOfFile; // set end marker
|
||||||
|
|
@ -144,8 +140,8 @@ begin
|
||||||
L.bufLen := L.BufLen * 2;
|
L.bufLen := L.BufLen * 2;
|
||||||
L.buf := {@cast}PChar(realloc(L.buf, L.bufLen*chrSize));
|
L.buf := {@cast}PChar(realloc(L.buf, L.bufLen*chrSize));
|
||||||
assert(L.bufLen - oldBuflen = oldBufLen);
|
assert(L.bufLen - oldBuflen = oldBufLen);
|
||||||
charsRead := ReadBuffer(L.f, addr(L.buf[oldBufLen]), oldBufLen*chrSize)
|
charsRead := LLStreamRead(L.stream, addr(L.buf[oldBufLen]),
|
||||||
div chrSize;
|
oldBufLen*chrSize) div chrSize;
|
||||||
if charsRead < oldBufLen then begin
|
if charsRead < oldBufLen then begin
|
||||||
L.buf[oldBufLen+charsRead] := EndOfFile;
|
L.buf[oldBufLen+charsRead] := EndOfFile;
|
||||||
L.sentinel := oldBufLen+charsRead;
|
L.sentinel := oldBufLen+charsRead;
|
||||||
|
|
@ -198,8 +194,8 @@ begin
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function initBaseLexer(out L: TBaseLexer; const filename: string;
|
procedure openBaseLexer(out L: TBaseLexer; inputstream: PLLStream;
|
||||||
bufLen: int = 8192): boolean;
|
bufLen: int = 8192);
|
||||||
begin
|
begin
|
||||||
assert(bufLen > 0);
|
assert(bufLen > 0);
|
||||||
L.bufpos := 0;
|
L.bufpos := 0;
|
||||||
|
|
@ -208,30 +204,8 @@ begin
|
||||||
L.sentinel := bufLen-1;
|
L.sentinel := bufLen-1;
|
||||||
L.lineStart := 0;
|
L.lineStart := 0;
|
||||||
L.linenumber := 1; // lines start at 1
|
L.linenumber := 1; // lines start at 1
|
||||||
L.fileOpened := openFile(L.f, filename);
|
L.stream := inputstream;
|
||||||
result := L.fileOpened;
|
|
||||||
if result then begin
|
|
||||||
fillBuffer(L);
|
fillBuffer(L);
|
||||||
skip_UTF_8_BOM(L)
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure initBaseLexerFromBuffer(out L: TBaseLexer;
|
|
||||||
const buffer: string);
|
|
||||||
begin
|
|
||||||
L.bufpos := 0;
|
|
||||||
L.bufLen := length(buffer)+1;
|
|
||||||
L.buf := {@cast}PChar(alloc(L.bufLen * chrSize));
|
|
||||||
L.sentinel := L.bufLen-1;
|
|
||||||
L.lineStart := 0;
|
|
||||||
L.linenumber := 1; // lines start at 1
|
|
||||||
L.fileOpened := false;
|
|
||||||
if L.bufLen > 0 then begin
|
|
||||||
copyMem(L.buf, {@cast}pointer(buffer), L.bufLen);
|
|
||||||
L.buf[L.bufLen-1] := EndOfFile;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
L.buf[0] := EndOfFile;
|
|
||||||
skip_UTF_8_BOM(L);
|
skip_UTF_8_BOM(L);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue