Initial import
This commit is contained in:
commit
405b86068e
324 changed files with 163599 additions and 0 deletions
39
lib/amd64.asm.in
Executable file
39
lib/amd64.asm.in
Executable file
|
|
@ -0,0 +1,39 @@
|
|||
; This contains the CPU-dependant variants of some routines.
|
||||
; (C) 2005 Andreas Rumpf
|
||||
; This code was inspired by the Freepascal compiler's sources
|
||||
; All routines here have the _cdecl calling convention because
|
||||
; that is the only convention any C compiler supports.
|
||||
|
||||
\python{
|
||||
# as usual I use my own preprocessor :-)
|
||||
import os
|
||||
|
||||
def c(name):
|
||||
if os.name == 'posix':
|
||||
return name
|
||||
else:
|
||||
return "_" + name
|
||||
|
||||
def arg:
|
||||
if os.name == 'posix':
|
||||
return 'rdi'
|
||||
else:
|
||||
return 'rcx' # on win64 uses its own calling convention; this sucks!
|
||||
}
|
||||
|
||||
segment code
|
||||
|
||||
global \c{cpu_inc_locked}
|
||||
global \c{cpu_dec_locked}
|
||||
|
||||
\c{cpu_dec_locked}:
|
||||
lock
|
||||
dec [\arg]
|
||||
setz al
|
||||
ret
|
||||
|
||||
\c{cpu_inc_locked}:
|
||||
lock
|
||||
inc [\arg]
|
||||
setz al
|
||||
ret
|
||||
84
lib/ansi_c.nim
Executable file
84
lib/ansi_c.nim
Executable file
|
|
@ -0,0 +1,84 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
# This include file contains headers of Ansi C procs
|
||||
# and definitions of Ansi C types in Nimrod syntax
|
||||
# All symbols are prefixed with 'c_' to avoid ambiguities
|
||||
|
||||
proc c_strcmp(a, b: CString): cint {.nodecl, importc: "strcmp".}
|
||||
proc c_memcmp(a, b: CString, size: cint): cint {.nodecl, importc: "memcmp".}
|
||||
proc c_memcpy(a, b: CString, size: cint) {.nodecl, importc: "memcpy".}
|
||||
proc c_strlen(a: CString): cint {.nodecl, importc: "strlen".}
|
||||
|
||||
type
|
||||
C_TextFile {.importc: "FILE", nodecl.} = record # empty record for
|
||||
# data hiding
|
||||
C_BinaryFile {.importc: "FILE", nodecl.} = record
|
||||
C_TextFileStar = ptr CTextFile
|
||||
C_BinaryFileStar = ptr CBinaryFile
|
||||
|
||||
C_JmpBuf {.importc: "jmp_buf".} = array[0..31, int]
|
||||
|
||||
var
|
||||
c_stdin {.importc: "stdin", noDecl.}: C_TextFileStar
|
||||
c_stdout {.importc: "stdout", noDecl.}: C_TextFileStar
|
||||
c_stderr {.importc: "stderr", noDecl.}: C_TextFileStar
|
||||
|
||||
var # constants faked as variables:
|
||||
SIGINT {.importc: "SIGINT", nodecl.}: cint
|
||||
SIGSEGV {.importc: "SIGSEGV", nodecl.}: cint
|
||||
SIGABRT {.importc: "SIGABRT", nodecl.}: cint
|
||||
SIGFPE {.importc: "SIGFPE", nodecl.}: cint
|
||||
SIGILL {.importc: "SIGILL", nodecl.}: cint
|
||||
|
||||
when defined(macosx):
|
||||
var
|
||||
SIGBUS {.importc: "SIGBUS", nodecl.}: cint
|
||||
# hopefully this does not lead to new bugs
|
||||
else:
|
||||
var
|
||||
SIGBUS {.importc: "SIGSEGV", nodecl.}: cint
|
||||
# only Mac OS X has this shit
|
||||
|
||||
proc c_longjmp(jmpb: C_JmpBuf, retval: cint) {.nodecl, importc: "longjmp".}
|
||||
proc c_setjmp(jmpb: var C_JmpBuf) {.nodecl, importc: "setjmp".}
|
||||
|
||||
proc c_signal(sig: cint, handler: proc (a: cint) {.noconv.}) {.
|
||||
importc: "signal", header: "<signal.h>".}
|
||||
proc c_raise(sig: cint) {.importc: "raise", header: "<signal.h>".}
|
||||
|
||||
proc c_fputs(c: cstring, f: C_TextFileStar) {.importc: "fputs", noDecl.}
|
||||
proc c_fgets(c: cstring, n: int, f: C_TextFileStar): cstring {.
|
||||
importc: "fgets", noDecl.}
|
||||
proc c_fgetc(stream: C_TextFileStar): int {.importc: "fgetc", nodecl.}
|
||||
proc c_ungetc(c: int, f: C_TextFileStar) {.importc: "ungetc", nodecl.}
|
||||
proc c_putc(c: Char, stream: C_TextFileStar) {.importc: "putc", nodecl.}
|
||||
proc c_fprintf(f: C_TextFileStar, frmt: CString) {.
|
||||
importc: "fprintf", nodecl, varargs.}
|
||||
|
||||
proc c_fopen(filename, mode: cstring): C_TextFileStar {.
|
||||
importc: "fopen", nodecl.}
|
||||
proc c_fclose(f: C_TextFileStar) {.importc: "fclose", nodecl.}
|
||||
|
||||
proc c_sprintf(buf, frmt: CString) {.nodecl, importc: "sprintf", varargs.}
|
||||
# we use it only in a way that cannot lead to security issues
|
||||
|
||||
proc c_fread(buf: Pointer, size, n: int, f: C_BinaryFileStar): int {.
|
||||
importc: "fread", noDecl.}
|
||||
proc c_fseek(f: C_BinaryFileStar, offset: clong, whence: int): int {.
|
||||
importc: "fseek", noDecl.}
|
||||
|
||||
proc c_fwrite(buf: Pointer, size, n: int, f: C_BinaryFileStar): int {.
|
||||
importc: "fwrite", noDecl.}
|
||||
|
||||
proc c_exit(errorcode: cint) {.importc: "exit", nodecl.}
|
||||
proc c_ferror(stream: C_TextFileStar): bool {.importc: "ferror", nodecl.}
|
||||
proc c_fflush(stream: C_TextFileStar) {.importc: "fflush", nodecl.}
|
||||
proc c_abort() {.importc: "abort", nodecl.}
|
||||
proc c_feof(stream: C_TextFileStar): bool {.importc: "feof", nodecl.}
|
||||
347
lib/arithm.nim
Executable file
347
lib/arithm.nim
Executable file
|
|
@ -0,0 +1,347 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
|
||||
# simple integer arithmetic with overflow checking
|
||||
|
||||
proc raiseOverflow {.exportc: "raiseOverflow".} =
|
||||
# a single proc to reduce code size to a minimum
|
||||
raise newException(EOverflow, "over- or underflow")
|
||||
|
||||
proc raiseDivByZero {.exportc: "raiseDivByZero".} =
|
||||
raise newException(EDivByZero, "divison by zero")
|
||||
|
||||
proc addInt64(a, b: int64): int64 {.compilerProc, inline.} =
|
||||
result = a + b
|
||||
if (result xor a) >= int64(0) or (result xor b) >= int64(0):
|
||||
return result
|
||||
raiseOverflow()
|
||||
|
||||
proc subInt64(a, b: int64): int64 {.compilerProc, inline.} =
|
||||
result = a - b
|
||||
if (result xor a) >= int64(0) or (result xor not b) >= int64(0):
|
||||
return result
|
||||
raiseOverflow()
|
||||
|
||||
proc negInt64(a: int64): int64 {.compilerProc, inline.} =
|
||||
if a != low(int64): return -a
|
||||
raiseOverflow()
|
||||
|
||||
proc absInt64(a: int64): int64 {.compilerProc, inline.} =
|
||||
if a != low(int64):
|
||||
if a >= 0: return a
|
||||
else: return -a
|
||||
raiseOverflow()
|
||||
|
||||
proc divInt64(a, b: int64): int64 {.compilerProc, inline.} =
|
||||
if b == int64(0):
|
||||
raiseDivByZero()
|
||||
if a == low(int64) and b == int64(-1):
|
||||
raiseOverflow()
|
||||
return a div b
|
||||
|
||||
proc modInt64(a, b: int64): int64 {.compilerProc, inline.} =
|
||||
if b == int64(0):
|
||||
raiseDivByZero()
|
||||
return a mod b
|
||||
|
||||
#
|
||||
# This code has been inspired by Python's source code.
|
||||
# The native int product x*y is either exactly right or *way* off, being
|
||||
# just the last n bits of the true product, where n is the number of bits
|
||||
# in an int (the delivered product is the true product plus i*2**n for
|
||||
# some integer i).
|
||||
#
|
||||
# The native float64 product x*y is subject to three
|
||||
# rounding errors: on a sizeof(int)==8 box, each cast to double can lose
|
||||
# info, and even on a sizeof(int)==4 box, the multiplication can lose info.
|
||||
# But, unlike the native int product, it's not in *range* trouble: even
|
||||
# if sizeof(int)==32 (256-bit ints), the product easily fits in the
|
||||
# dynamic range of a float64. So the leading 50 (or so) bits of the float64
|
||||
# product are correct.
|
||||
#
|
||||
# We check these two ways against each other, and declare victory if they're
|
||||
# approximately the same. Else, because the native int product is the only
|
||||
# one that can lose catastrophic amounts of information, it's the native int
|
||||
# product that must have overflowed.
|
||||
#
|
||||
proc mulInt64(a, b: int64): int64 {.compilerproc.} =
|
||||
var
|
||||
resAsFloat, floatProd: float64
|
||||
result = a * b
|
||||
floatProd = float64(a) # conversion
|
||||
floatProd = floatProd * float64(b)
|
||||
resAsFloat = float64(result)
|
||||
|
||||
# Fast path for normal case: small multiplicands, and no info
|
||||
# is lost in either method.
|
||||
if resAsFloat == floatProd: return result
|
||||
|
||||
# Somebody somewhere lost info. Close enough, or way off? Note
|
||||
# that a != 0 and b != 0 (else resAsFloat == floatProd == 0).
|
||||
# The difference either is or isn't significant compared to the
|
||||
# true value (of which floatProd is a good approximation).
|
||||
|
||||
# abs(diff)/abs(prod) <= 1/32 iff
|
||||
# 32 * abs(diff) <= abs(prod) -- 5 good bits is "close enough"
|
||||
if 32.0 * abs(resAsFloat - floatProd) <= abs(floatProd):
|
||||
return result
|
||||
raiseOverflow()
|
||||
|
||||
|
||||
proc absInt(a: int): int {.compilerProc, inline.} =
|
||||
if a != low(int):
|
||||
if a >= 0: return a
|
||||
else: return -a
|
||||
raiseOverflow()
|
||||
|
||||
when defined(I386) and (defined(vcc) or defined(wcc) or defined(dmc)):
|
||||
# or defined(gcc)):
|
||||
{.define: asmVersion.}
|
||||
# my Version of Borland C++Builder does not have
|
||||
# tasm32, which is needed for assembler blocks
|
||||
# this is why Borland is not included in the 'when'
|
||||
else:
|
||||
{.define: useInline.}
|
||||
|
||||
when defined(asmVersion) and defined(gcc):
|
||||
proc addInt(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 divInt(a, b: int): int {.compilerProc, pure, inline.}
|
||||
proc modInt(a, b: int): int {.compilerProc, pure, inline.}
|
||||
proc negInt(a: int): int {.compilerProc, pure, inline.}
|
||||
|
||||
elif defined(asmVersion):
|
||||
proc addInt(a, b: int): int {.compilerProc, pure.}
|
||||
proc subInt(a, b: int): int {.compilerProc, pure.}
|
||||
proc mulInt(a, b: int): int {.compilerProc, pure.}
|
||||
proc divInt(a, b: int): int {.compilerProc, pure.}
|
||||
proc modInt(a, b: int): int {.compilerProc, pure.}
|
||||
proc negInt(a: int): int {.compilerProc, pure.}
|
||||
|
||||
elif defined(useInline):
|
||||
proc addInt(a, b: int): int {.compilerProc, inline.}
|
||||
proc subInt(a, b: int): int {.compilerProc, inline.}
|
||||
proc mulInt(a, b: int): int {.compilerProc.}
|
||||
# mulInt is to large for inlining?
|
||||
proc divInt(a, b: int): int {.compilerProc, inline.}
|
||||
proc modInt(a, b: int): int {.compilerProc, inline.}
|
||||
proc negInt(a: int): int {.compilerProc, inline.}
|
||||
|
||||
else:
|
||||
proc addInt(a, b: int): int {.compilerProc.}
|
||||
proc subInt(a, b: int): int {.compilerProc.}
|
||||
proc mulInt(a, b: int): int {.compilerProc.}
|
||||
proc divInt(a, b: int): int {.compilerProc.}
|
||||
proc modInt(a, b: int): int {.compilerProc.}
|
||||
proc negInt(a: int): int {.compilerProc.}
|
||||
|
||||
# implementation:
|
||||
|
||||
when defined(asmVersion) and not defined(gcc):
|
||||
# assembler optimized versions for compilers that
|
||||
# have an intel syntax assembler:
|
||||
proc addInt(a, b: int): int =
|
||||
# a in eax, and b in edx
|
||||
asm """
|
||||
mov eax, `a`
|
||||
add eax, `b`
|
||||
jno theEnd
|
||||
call raiseOverflow
|
||||
theEnd:
|
||||
"""
|
||||
|
||||
proc subInt(a, b: int): int =
|
||||
asm """
|
||||
mov eax, `a`
|
||||
sub eax, `b`
|
||||
jno theEnd
|
||||
call raiseOverflow
|
||||
theEnd:
|
||||
"""
|
||||
|
||||
proc negInt(a: int): int =
|
||||
asm """
|
||||
mov eax, `a`
|
||||
neg eax
|
||||
jno theEnd
|
||||
call raiseOverflow
|
||||
theEnd:
|
||||
"""
|
||||
|
||||
proc divInt(a, b: int): int =
|
||||
asm """
|
||||
mov eax, `a`
|
||||
mov ecx, `b`
|
||||
xor edx, edx
|
||||
idiv ecx
|
||||
jno theEnd
|
||||
call raiseOverflow
|
||||
theEnd:
|
||||
"""
|
||||
|
||||
proc modInt(a, b: int): int =
|
||||
asm """
|
||||
mov eax, `a`
|
||||
mov ecx, `b`
|
||||
xor edx, edx
|
||||
idiv ecx
|
||||
jno theEnd
|
||||
call raiseOverflow
|
||||
theEnd:
|
||||
mov eax, edx
|
||||
"""
|
||||
|
||||
proc mulInt(a, b: int): int =
|
||||
asm """
|
||||
mov eax, `a`
|
||||
mov ecx, `b`
|
||||
xor edx, edx
|
||||
imul ecx
|
||||
jno theEnd
|
||||
call raiseOverflow
|
||||
theEnd:
|
||||
"""
|
||||
|
||||
elif defined(asmVersion) and defined(gcc):
|
||||
proc addInt(a, b: int): int =
|
||||
asm """ "addl %1,%%eax\n"
|
||||
"jno 1\n"
|
||||
"call _raiseOverflow\n"
|
||||
"1: \n"
|
||||
:"=a"(`a`)
|
||||
:"a"(`a`), "r"(`b`)
|
||||
"""
|
||||
|
||||
proc subInt(a, b: int): int =
|
||||
asm """ "subl %1,%%eax\n"
|
||||
"jno 1\n"
|
||||
"call _raiseOverflow\n"
|
||||
"1: \n"
|
||||
:"=a"(`a`)
|
||||
:"a"(`a`), "r"(`b`)
|
||||
"""
|
||||
|
||||
proc negInt(a: int): int =
|
||||
asm """ "negl %%eax\n"
|
||||
"jno 1\n"
|
||||
"call _raiseOverflow\n"
|
||||
"1: \n"
|
||||
:"=a"(`a`)
|
||||
:"a"(`a`)
|
||||
"""
|
||||
|
||||
proc divInt(a, b: int): int =
|
||||
asm """ "xorl %%edx, %%edx\n"
|
||||
"idivl %%ecx\n"
|
||||
"jno 1\n"
|
||||
"call _raiseOverflow\n"
|
||||
"1: \n"
|
||||
:"=a"(`a`)
|
||||
:"a"(`a`), "c"(`b`)
|
||||
:"%edx"
|
||||
"""
|
||||
|
||||
proc modInt(a, b: int): int =
|
||||
asm """ "xorl %%edx, %%edx\n"
|
||||
"idivl %%ecx\n"
|
||||
"jno 1\n"
|
||||
"call _raiseOverflow\n"
|
||||
"1: \n"
|
||||
"movl %%edx, %%eax"
|
||||
:"=a"(`a`)
|
||||
:"a"(`a`), "c"(`b`)
|
||||
:"%edx"
|
||||
"""
|
||||
|
||||
proc mulInt(a, b: int): int =
|
||||
asm """ "xorl %%edx, %%edx\n"
|
||||
"imull %%ecx\n"
|
||||
"jno 1\n"
|
||||
"call _raiseOverflow\n"
|
||||
"1: \n"
|
||||
:"=a"(`a`)
|
||||
:"a"(`a`), "c"(`b`)
|
||||
:"%edx"
|
||||
"""
|
||||
|
||||
else:
|
||||
# Platform independant versions of the above (slower!)
|
||||
|
||||
proc addInt(a, b: int): int =
|
||||
result = a + b
|
||||
if (result xor a) >= 0 or (result xor b) >= 0:
|
||||
return result
|
||||
raiseOverflow()
|
||||
|
||||
proc subInt(a, b: int): int =
|
||||
result = a - b
|
||||
if (result xor a) >= 0 or (result xor not b) >= 0:
|
||||
return result
|
||||
raiseOverflow()
|
||||
|
||||
proc negInt(a: int): int =
|
||||
if a != low(int): return -a
|
||||
raiseOverflow()
|
||||
|
||||
proc divInt(a, b: int): int =
|
||||
if b == 0:
|
||||
raiseDivByZero()
|
||||
if a == low(int) and b == -1:
|
||||
raiseOverflow()
|
||||
return a div b
|
||||
|
||||
proc modInt(a, b: int): int =
|
||||
if b == 0:
|
||||
raiseDivByZero()
|
||||
return a mod b
|
||||
|
||||
#
|
||||
# This code has been inspired by Python's source code.
|
||||
# The native int product x*y is either exactly right or *way* off, being
|
||||
# just the last n bits of the true product, where n is the number of bits
|
||||
# in an int (the delivered product is the true product plus i*2**n for
|
||||
# some integer i).
|
||||
#
|
||||
# The native float64 product x*y is subject to three
|
||||
# rounding errors: on a sizeof(int)==8 box, each cast to double can lose
|
||||
# info, and even on a sizeof(int)==4 box, the multiplication can lose info.
|
||||
# But, unlike the native int product, it's not in *range* trouble: even
|
||||
# if sizeof(int)==32 (256-bit ints), the product easily fits in the
|
||||
# dynamic range of a float64. So the leading 50 (or so) bits of the float64
|
||||
# product are correct.
|
||||
#
|
||||
# We check these two ways against each other, and declare victory if
|
||||
# they're approximately the same. Else, because the native int product is
|
||||
# the only one that can lose catastrophic amounts of information, it's the
|
||||
# native int product that must have overflowed.
|
||||
#
|
||||
proc mulInt(a, b: int): int =
|
||||
var
|
||||
resAsFloat, floatProd: float
|
||||
|
||||
result = a * b
|
||||
floatProd = toFloat(a) * toFloat(b)
|
||||
resAsFloat = toFloat(result)
|
||||
|
||||
# Fast path for normal case: small multiplicands, and no info
|
||||
# is lost in either method.
|
||||
if resAsFloat == floatProd: return result
|
||||
|
||||
# Somebody somewhere lost info. Close enough, or way off? Note
|
||||
# that a != 0 and b != 0 (else resAsFloat == floatProd == 0).
|
||||
# The difference either is or isn't significant compared to the
|
||||
# true value (of which floatProd is a good approximation).
|
||||
|
||||
# abs(diff)/abs(prod) <= 1/32 iff
|
||||
# 32 * abs(diff) <= abs(prod) -- 5 good bits is "close enough"
|
||||
if 32.0 * abs(resAsFloat - floatProd) <= abs(floatProd):
|
||||
return result
|
||||
raiseOverflow()
|
||||
118
lib/assign.nim
Executable file
118
lib/assign.nim
Executable file
|
|
@ -0,0 +1,118 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
#when defined(debugGC):
|
||||
# {.define: logAssign.}
|
||||
proc genericAssign(dest, src: Pointer, mt: PNimType) {.compilerProc.}
|
||||
proc genericAssignAux(dest, src: Pointer, n: ptr TNimNode) =
|
||||
var
|
||||
d = cast[TAddress](dest)
|
||||
s = cast[TAddress](src)
|
||||
case n.kind
|
||||
of nkNone: assert(false)
|
||||
of nkSlot:
|
||||
genericAssign(cast[pointer](d +% n.offset), cast[pointer](s +% n.offset),
|
||||
n.typ)
|
||||
of nkList:
|
||||
for i in 0..n.len-1:
|
||||
genericAssignAux(dest, src, n.sons[i])
|
||||
of nkCase:
|
||||
copyMem(cast[pointer](d +% n.offset), cast[pointer](s +% n.offset),
|
||||
n.typ.size)
|
||||
var m = selectBranch(src, n)
|
||||
if m != nil: genericAssignAux(dest, src, m)
|
||||
|
||||
proc genericAssign(dest, src: Pointer, mt: PNimType) =
|
||||
var
|
||||
d = cast[TAddress](dest)
|
||||
s = cast[TAddress](src)
|
||||
|
||||
assert(mt != nil)
|
||||
case mt.Kind
|
||||
of tySequence:
|
||||
var s2 = cast[ppointer](src)^
|
||||
var seq = cast[PGenericSeq](s2)
|
||||
if s2 == nil: # this can happen! nil sequences are allowed
|
||||
var x = cast[ppointer](dest)
|
||||
x^ = nil
|
||||
return
|
||||
assert(dest != nil)
|
||||
unsureAsgnRef(cast[ppointer](dest),
|
||||
newObj(mt, seq.len * mt.base.size + GenericSeqSize))
|
||||
var dst = cast[taddress](cast[ppointer](dest)^)
|
||||
for i in 0..seq.len-1:
|
||||
genericAssign(
|
||||
cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize),
|
||||
cast[pointer](cast[taddress](s2) +% i *% mt.base.size +%
|
||||
GenericSeqSize),
|
||||
mt.Base)
|
||||
var dstseq = cast[PGenericSeq](dst)
|
||||
dstseq.len = seq.len
|
||||
dstseq.space = seq.len
|
||||
of tyRecord, tyObject, tyTuple:
|
||||
genericAssignAux(dest, src, mt.node)
|
||||
of tyArray, tyArrayConstr:
|
||||
for i in 0..(mt.size div mt.base.size)-1:
|
||||
genericAssign(cast[pointer](d +% i*% mt.base.size),
|
||||
cast[pointer](s +% i*% mt.base.size), mt.base)
|
||||
of tyString: # a leaf
|
||||
var s2 = cast[ppointer](s)^
|
||||
if s2 != nil: # nil strings are possible!
|
||||
unsureAsgnRef(cast[ppointer](dest), copyString(cast[mstring](s2)))
|
||||
else:
|
||||
var x = cast[ppointer](dest)
|
||||
x^ = nil
|
||||
return
|
||||
of tyRef: # BUGFIX: a long time this has been forgotten!
|
||||
unsureAsgnRef(cast[ppointer](dest), cast[ppointer](s)^)
|
||||
else:
|
||||
copyMem(dest, src, mt.size) # copy raw bits
|
||||
|
||||
proc genericSeqAssign(dest, src: Pointer, mt: PNimType) {.compilerProc.} =
|
||||
genericAssign(dest, addr(src), mt)
|
||||
|
||||
proc genericAssignOpenArray(dest, src: pointer, len: int,
|
||||
mt: PNimType) {.compilerproc.} =
|
||||
var
|
||||
d = cast[TAddress](dest)
|
||||
s = cast[TAddress](src)
|
||||
for i in 0..len-1:
|
||||
genericAssign(cast[pointer](d +% i*% mt.base.size),
|
||||
cast[pointer](s +% i*% mt.base.size), mt.base)
|
||||
|
||||
proc objectInit(dest: Pointer, typ: PNimType) {.compilerProc.}
|
||||
proc objectInitAux(dest: Pointer, n: ptr TNimNode) =
|
||||
var d = cast[TAddress](dest)
|
||||
case n.kind
|
||||
of nkNone: assert(false)
|
||||
of nkSLot: objectInit(cast[pointer](d +% n.offset), n.typ)
|
||||
of nkList:
|
||||
for i in 0..n.len-1:
|
||||
objectInitAux(dest, n.sons[i])
|
||||
of nkCase:
|
||||
var m = selectBranch(dest, n)
|
||||
if m != nil: objectInitAux(dest, m)
|
||||
|
||||
proc objectInit(dest: Pointer, typ: PNimType) =
|
||||
# the generic init proc that takes care of initialization of complex
|
||||
# objects on the stack or heap
|
||||
var d = cast[TAddress](dest)
|
||||
case typ.kind
|
||||
of tyObject:
|
||||
# iterate over any structural type
|
||||
# here we have to init the type field:
|
||||
var pint = cast[ptr PNimType](dest)
|
||||
pint^ = typ
|
||||
objectInitAux(dest, typ.node)
|
||||
of tyRecord:
|
||||
objectInitAux(dest, typ.node)
|
||||
of tyArray, tyArrayConstr:
|
||||
for i in 0..(typ.size div typ.base.size)-1:
|
||||
objectInit(cast[pointer](d +% i * typ.base.size), typ.base)
|
||||
else: nil # nothing to do
|
||||
698
lib/base/cairo/cairo.nim
Normal file
698
lib/base/cairo/cairo.nim
Normal file
|
|
@ -0,0 +1,698 @@
|
|||
|
||||
#* cairo - a vector graphics library with display and print output
|
||||
# *
|
||||
# * Copyright © 2002 University of Southern California
|
||||
# * Copyright © 2005 Red Hat, Inc.
|
||||
# *
|
||||
# * This library is free software; you can redistribute it and/or
|
||||
# * modify it either under the terms of the GNU Lesser General Public
|
||||
# * License version 2.1 as published by the Free Software Foundation
|
||||
# * (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
# * Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
# * notice, a recipient may use your version of this file under either
|
||||
# * the MPL or the LGPL.
|
||||
# *
|
||||
# * You should have received a copy of the LGPL along with this library
|
||||
# * in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# * You should have received a copy of the MPL along with this library
|
||||
# * in the file COPYING-MPL-1.1
|
||||
# *
|
||||
# * The contents of this file are subject to the Mozilla Public License
|
||||
# * Version 1.1 (the "License"); you may not use this file except in
|
||||
# * compliance with the License. You may obtain a copy of the License at
|
||||
# * http://www.mozilla.org/MPL/
|
||||
# *
|
||||
# * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
# * OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
# * the specific language governing rights and limitations.
|
||||
# *
|
||||
# * The Original Code is the cairo graphics library.
|
||||
# *
|
||||
# * The Initial Developer of the Original Code is University of Southern
|
||||
# * California.
|
||||
# *
|
||||
# * Contributor(s):
|
||||
# * Carl D. Worth <cworth@cworth.org>
|
||||
# #*
|
||||
# * This FreePascal binding generated August 26, 2005
|
||||
# * by Jeffrey Pohlmeyer <yetanothergeek@yahoo.com>
|
||||
#
|
||||
|
||||
#
|
||||
# - Updated to cairo version 1.4
|
||||
# - Grouped OS specific fuctions in separated units
|
||||
# - Organized the functions by group and ordered exactly as the c header
|
||||
# - Cleared parameter list syntax according to pascal standard
|
||||
#
|
||||
# By Luiz Américo Pereira Câmara
|
||||
# October 2007
|
||||
#
|
||||
|
||||
when defined(windows):
|
||||
const
|
||||
LIB_CAIRO* = "cairo.dll"
|
||||
else:
|
||||
const
|
||||
LIB_CAIRO* = "libcairo.so"
|
||||
|
||||
type
|
||||
PByte = cstring
|
||||
cairo_status_t* = enum
|
||||
CAIRO_STATUS_SUCCESS = 0, CAIRO_STATUS_NO_MEMORY,
|
||||
CAIRO_STATUS_INVALID_RESTORE, CAIRO_STATUS_INVALID_POP_GROUP,
|
||||
CAIRO_STATUS_NO_CURRENT_POINT, CAIRO_STATUS_INVALID_MATRIX,
|
||||
CAIRO_STATUS_INVALID_STATUS, CAIRO_STATUS_NULL_POINTER,
|
||||
CAIRO_STATUS_INVALID_STRING, CAIRO_STATUS_INVALID_PATH_DATA,
|
||||
CAIRO_STATUS_READ_ERROR, CAIRO_STATUS_WRITE_ERROR,
|
||||
CAIRO_STATUS_SURFACE_FINISHED, CAIRO_STATUS_SURFACE_TYPE_MISMATCH,
|
||||
CAIRO_STATUS_PATTERN_TYPE_MISMATCH, CAIRO_STATUS_INVALID_CONTENT,
|
||||
CAIRO_STATUS_INVALID_FORMAT, CAIRO_STATUS_INVALID_VISUAL,
|
||||
CAIRO_STATUS_FILE_NOT_FOUND, CAIRO_STATUS_INVALID_DASH
|
||||
cairo_operator_t* = enum
|
||||
CAIRO_OPERATOR_CLEAR, CAIRO_OPERATOR_SOURCE, CAIRO_OPERATOR_OVER,
|
||||
CAIRO_OPERATOR_IN, CAIRO_OPERATOR_OUT, CAIRO_OPERATOR_ATOP,
|
||||
CAIRO_OPERATOR_DEST, CAIRO_OPERATOR_DEST_OVER, CAIRO_OPERATOR_DEST_IN,
|
||||
CAIRO_OPERATOR_DEST_OUT, CAIRO_OPERATOR_DEST_ATOP, CAIRO_OPERATOR_XOR,
|
||||
CAIRO_OPERATOR_ADD, CAIRO_OPERATOR_SATURATE
|
||||
cairo_antialias_t* = enum
|
||||
CAIRO_ANTIALIAS_DEFAULT, CAIRO_ANTIALIAS_NONE, CAIRO_ANTIALIAS_GRAY,
|
||||
CAIRO_ANTIALIAS_SUBPIXEL
|
||||
cairo_fill_rule_t* = enum
|
||||
CAIRO_FILL_RULE_WINDING, CAIRO_FILL_RULE_EVEN_ODD
|
||||
cairo_line_cap_t* = enum
|
||||
CAIRO_LINE_CAP_BUTT, CAIRO_LINE_CAP_ROUND, CAIRO_LINE_CAP_SQUARE
|
||||
cairo_line_join_t* = enum
|
||||
CAIRO_LINE_JOIN_MITER, CAIRO_LINE_JOIN_ROUND, CAIRO_LINE_JOIN_BEVEL
|
||||
cairo_font_slant_t* = enum
|
||||
CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_SLANT_ITALIC, CAIRO_FONT_SLANT_OBLIQUE
|
||||
cairo_font_weight_t* = enum
|
||||
CAIRO_FONT_WEIGHT_NORMAL, CAIRO_FONT_WEIGHT_BOLD
|
||||
cairo_subpixel_order_t* = enum
|
||||
CAIRO_SUBPIXEL_ORDER_DEFAULT, CAIRO_SUBPIXEL_ORDER_RGB,
|
||||
CAIRO_SUBPIXEL_ORDER_BGR, CAIRO_SUBPIXEL_ORDER_VRGB,
|
||||
CAIRO_SUBPIXEL_ORDER_VBGR
|
||||
cairo_hint_style_t* = enum
|
||||
CAIRO_HINT_STYLE_DEFAULT, CAIRO_HINT_STYLE_NONE, CAIRO_HINT_STYLE_SLIGHT,
|
||||
CAIRO_HINT_STYLE_MEDIUM, CAIRO_HINT_STYLE_FULL
|
||||
cairo_hint_metrics_t* = enum
|
||||
CAIRO_HINT_METRICS_DEFAULT, CAIRO_HINT_METRICS_OFF, CAIRO_HINT_METRICS_ON
|
||||
cairo_path_data_type_t* = enum
|
||||
CAIRO_PATH_MOVE_TO, CAIRO_PATH_LINE_TO, CAIRO_PATH_CURVE_TO,
|
||||
CAIRO_PATH_CLOSE_PATH
|
||||
cairo_content_t* = enum
|
||||
CAIRO_CONTENT_COLOR = 0x00001000, CAIRO_CONTENT_ALPHA = 0x00002000,
|
||||
CAIRO_CONTENT_COLOR_ALPHA = 0x00003000
|
||||
cairo_format_t* = enum
|
||||
CAIRO_FORMAT_ARGB32, CAIRO_FORMAT_RGB24, CAIRO_FORMAT_A8, CAIRO_FORMAT_A1
|
||||
cairo_extend_t* = enum
|
||||
CAIRO_EXTEND_NONE, CAIRO_EXTEND_REPEAT, CAIRO_EXTEND_REFLECT,
|
||||
CAIRO_EXTEND_PAD
|
||||
cairo_filter_t* = enum
|
||||
CAIRO_FILTER_FAST, CAIRO_FILTER_GOOD, CAIRO_FILTER_BEST,
|
||||
CAIRO_FILTER_NEAREST, CAIRO_FILTER_BILINEAR, CAIRO_FILTER_GAUSSIAN
|
||||
cairo_font_type_t* = enum
|
||||
CAIRO_FONT_TYPE_TOY, CAIRO_FONT_TYPE_FT, CAIRO_FONT_TYPE_WIN32,
|
||||
CAIRO_FONT_TYPE_ATSUI
|
||||
cairo_pattern_type_t* = enum
|
||||
CAIRO_PATTERN_TYPE_SOLID, CAIRO_PATTERN_TYPE_SURFACE,
|
||||
CAIRO_PATTERN_TYPE_LINEAR, CAIRO_PATTERN_TYPE_RADIAL
|
||||
cairo_surface_type_t* = enum
|
||||
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_QUARTZ, CAIRO_SURFACE_TYPE_WIN32,
|
||||
CAIRO_SURFACE_TYPE_BEOS, CAIRO_SURFACE_TYPE_DIRECTFB,
|
||||
CAIRO_SURFACE_TYPE_SVG, CAIRO_SURFACE_TYPE_OS2
|
||||
cairo_svg_version_t* = enum
|
||||
CAIRO_SVG_VERSION_1_1, CAIRO_SVG_VERSION_1_2
|
||||
Pcairo_surface_t* = ref cairo_surface_t
|
||||
PPcairo_surface_t* = ref Pcairo_surface_t
|
||||
Pcairo_t* = ref cairo_t
|
||||
Pcairo_pattern_t* = ref cairo_pattern_t
|
||||
Pcairo_font_options_t* = ref cairo_font_options_t
|
||||
Pcairo_font_face_t* = ref cairo_font_face_t
|
||||
Pcairo_scaled_font_t* = ref cairo_scaled_font_t
|
||||
Pcairo_bool_t* = ref cairo_bool_t
|
||||
cairo_bool_t* = int32
|
||||
Pcairo_matrix_t* = ref cairo_matrix_t
|
||||
Pcairo_user_data_key_t* = ref cairo_user_data_key_t
|
||||
Pcairo_glyph_t* = ref cairo_glyph_t
|
||||
Pcairo_text_extents_t* = ref cairo_text_extents_t
|
||||
Pcairo_font_extents_t* = ref cairo_font_extents_t
|
||||
Pcairo_path_data_type_t* = ref cairo_path_data_type_t
|
||||
Pcairo_path_data_t* = ref cairo_path_data_t
|
||||
Pcairo_path_t* = ref cairo_path_t
|
||||
Pcairo_rectangle_t* = ref cairo_rectangle_t
|
||||
Pcairo_rectangle_list_t* = ref cairo_rectangle_list_t
|
||||
cairo_destroy_func_t* = proc (data: Pointer){.cdecl.}
|
||||
cairo_write_func_t* = proc (closure: Pointer, data: PByte, len: int32): cairo_status_t{.
|
||||
cdecl.}
|
||||
cairo_read_func_t* = proc (closure: Pointer, data: PByte, len: int32): cairo_status_t{.
|
||||
cdecl.}
|
||||
cairo_t* = record #OPAQUE
|
||||
cairo_surface_t* = record #OPAQUE
|
||||
cairo_pattern_t* = record #OPAQUE
|
||||
cairo_scaled_font_t* = record #OPAQUE
|
||||
cairo_font_face_t* = record #OPAQUE
|
||||
cairo_font_options_t* = record #OPAQUE
|
||||
cairo_matrix_t* = record
|
||||
xx: float64
|
||||
yx: float64
|
||||
xy: float64
|
||||
yy: float64
|
||||
x0: float64
|
||||
y0: float64
|
||||
|
||||
cairo_user_data_key_t* = record
|
||||
unused: int32
|
||||
|
||||
cairo_glyph_t* = record
|
||||
index: int32
|
||||
x: float64
|
||||
y: float64
|
||||
|
||||
cairo_text_extents_t* = record
|
||||
x_bearing: float64
|
||||
y_bearing: float64
|
||||
width: float64
|
||||
height: float64
|
||||
x_advance: float64
|
||||
y_advance: float64
|
||||
|
||||
cairo_font_extents_t* = record
|
||||
ascent: float64
|
||||
descent: float64
|
||||
height: float64
|
||||
max_x_advance: float64
|
||||
max_y_advance: float64
|
||||
|
||||
cairo_path_data_t* = record #* _type : cairo_path_data_type_t;
|
||||
# length : LongInt;
|
||||
# end
|
||||
x: float64
|
||||
y: float64
|
||||
|
||||
cairo_path_t* = record
|
||||
status: cairo_status_t
|
||||
data: Pcairo_path_data_t
|
||||
num_data: int32
|
||||
|
||||
cairo_rectangle_t* = record
|
||||
x, y, width, height: float64
|
||||
|
||||
cairo_rectangle_list_t* = record
|
||||
status: cairo_status_t
|
||||
rectangles: Pcairo_rectangle_t
|
||||
num_rectangles: int32
|
||||
|
||||
|
||||
proc cairo_version*(): int32{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_version_string*(): cstring{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
#Helper function to retrieve decoded version
|
||||
proc cairo_version*(major, minor, micro: var int32)
|
||||
#* Functions for manipulating state objects
|
||||
proc cairo_create*(target: Pcairo_surface_t): Pcairo_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_reference*(cr: Pcairo_t): Pcairo_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_destroy*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_get_reference_count*(cr: Pcairo_t): int32{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_get_user_data*(cr: Pcairo_t, key: Pcairo_user_data_key_t): pointer{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_set_user_data*(cr: PCairo_t, key: Pcairo_user_data_key_t,
|
||||
user_data: Pointer, destroy: cairo_destroy_func_t): cairo_status_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_save*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_restore*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_push_group*(cr: PCairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_push_group_with_content*(cr: PCairo_t, content: cairo_content_t){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_pop_group*(cr: PCairo_t): Pcairo_pattern_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_pop_group_to_source*(cr: PCairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
#* Modify state
|
||||
proc cairo_set_operator*(cr: Pcairo_t, op: cairo_operator_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_set_source*(cr: Pcairo_t, source: Pcairo_pattern_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_set_source_rgb*(cr: Pcairo_t, red, green, blue: float64){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_set_source_rgba*(cr: Pcairo_t, red, green, blue, alpha: float64){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_set_source_surface*(cr: Pcairo_t, surface: Pcairo_surface_t,
|
||||
x, y: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_set_tolerance*(cr: Pcairo_t, tolerance: float64){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_set_antialias*(cr: Pcairo_t, antialias: cairo_antialias_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_set_fill_rule*(cr: Pcairo_t, fill_rule: cairo_fill_rule_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_set_line_width*(cr: Pcairo_t, width: float64){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_set_line_cap*(cr: Pcairo_t, line_cap: cairo_line_cap_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_set_line_join*(cr: Pcairo_t, line_join: cairo_line_join_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_set_dash*(cr: Pcairo_t, dashes: openarray[float64],
|
||||
offset: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_set_miter_limit*(cr: Pcairo_t, limit: float64){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_translate*(cr: Pcairo_t, tx, ty: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_scale*(cr: Pcairo_t, sx, sy: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_rotate*(cr: Pcairo_t, angle: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_transform*(cr: Pcairo_t, matrix: Pcairo_matrix_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_set_matrix*(cr: Pcairo_t, matrix: Pcairo_matrix_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_identity_matrix*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_user_to_device*(cr: Pcairo_t, x, y: var float64){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_user_to_device_distance*(cr: Pcairo_t, dx, dy: var float64){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_device_to_user*(cr: Pcairo_t, x, y: var float64){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_device_to_user_distance*(cr: Pcairo_t, dx, dy: var float64){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
#* Path creation functions
|
||||
proc cairo_new_path*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_move_to*(cr: Pcairo_t, x, y: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_new_sub_path*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_line_to*(cr: Pcairo_t, x, y: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_curve_to*(cr: Pcairo_t, x1, y1, x2, y2, x3, y3: float64){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_arc*(cr: Pcairo_t, xc, yc, radius, angle1, angle2: float64){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_arc_negative*(cr: Pcairo_t, xc, yc, radius, angle1, angle2: float64){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_rel_move_to*(cr: Pcairo_t, 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_curve_to*(cr: Pcairo_t, dx1, dy1, dx2, dy2, dx3, dy3: float64){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_rectangle*(cr: Pcairo_t, x, y, width, height: float64){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_close_path*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
#* Painting functions
|
||||
proc cairo_paint*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_paint_with_alpha*(cr: Pcairo_t, alpha: float64){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_mask*(cr: Pcairo_t, pattern: Pcairo_pattern_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_mask_surface*(cr: Pcairo_t, surface: Pcairo_surface_t,
|
||||
surface_x, surface_y: float64){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_stroke*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_stroke_preserve*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_fill*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_fill_preserve*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_copy_page*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_show_page*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
#* Insideness testing
|
||||
proc cairo_in_stroke*(cr: Pcairo_t, x, y: float64): cairo_bool_t{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_in_fill*(cr: Pcairo_t, x, y: float64): cairo_bool_t{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
#* Rectangular extents
|
||||
proc cairo_stroke_extents*(cr: Pcairo_t, x1, y1, x2, y2: var float64){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_fill_extents*(cr: Pcairo_t, x1, y1, x2, y2: var float64){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
#* Clipping
|
||||
proc cairo_reset_clip*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_clip*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_clip_preserve*(cr: Pcairo_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_clip_extents*(cr: Pcairo_t, x1, y1, x2, y2: var float64){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_copy_clip_rectangle_list*(cr: Pcairo_t): Pcairo_rectangle_list_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_rectangle_list_destroy*(rectangle_list: Pcairo_rectangle_list_t){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
#* Font/Text functions
|
||||
proc cairo_font_options_create*(): Pcairo_font_options_t{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_font_options_copy*(original: Pcairo_font_options_t): Pcairo_font_options_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_font_options_destroy*(options: Pcairo_font_options_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_font_options_status*(options: Pcairo_font_options_t): cairo_status_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_font_options_merge*(options, other: Pcairo_font_options_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_font_options_equal*(options, other: Pcairo_font_options_t): cairo_bool_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_font_options_hash*(options: Pcairo_font_options_t): int32{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_font_options_set_antialias*(options: Pcairo_font_options_t,
|
||||
antialias: cairo_antialias_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_font_options_get_antialias*(options: Pcairo_font_options_t): cairo_antialias_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_font_options_set_subpixel_order*(options: Pcairo_font_options_t,
|
||||
subpixel_order: cairo_subpixel_order_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_font_options_get_subpixel_order*(options: Pcairo_font_options_t): cairo_subpixel_order_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_font_options_set_hint_style*(options: Pcairo_font_options_t,
|
||||
hint_style: cairo_hint_style_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_font_options_get_hint_style*(options: Pcairo_font_options_t): cairo_hint_style_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_font_options_set_hint_metrics*(options: Pcairo_font_options_t,
|
||||
hint_metrics: cairo_hint_metrics_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_font_options_get_hint_metrics*(options: Pcairo_font_options_t): cairo_hint_metrics_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
#* This interface is for dealing with text as text, not caring about the
|
||||
# font object inside the the cairo_t.
|
||||
proc cairo_select_font_face*(cr: Pcairo_t, family: cstring,
|
||||
slant: cairo_font_slant_t,
|
||||
weight: cairo_font_weight_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_set_font_size*(cr: Pcairo_t, size: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_set_font_matrix*(cr: Pcairo_t, matrix: Pcairo_matrix_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_get_font_matrix*(cr: Pcairo_t, matrix: Pcairo_matrix_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_set_font_options*(cr: Pcairo_t, options: Pcairo_font_options_t){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_get_font_options*(cr: Pcairo_t, options: Pcairo_font_options_t){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_set_font_face*(cr: Pcairo_t, font_face: Pcairo_font_face_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_get_font_face*(cr: Pcairo_t): Pcairo_font_face_t{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_set_scaled_font*(cr: PCairo_t, scaled_font: Pcairo_scaled_font_t){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_get_scaled_font*(cr: Pcairo_t): Pcairo_scaled_font_t{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_show_text*(cr: Pcairo_t, utf8: cstring){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_show_glyphs*(cr: Pcairo_t, glyphs: Pcairo_glyph_t, num_glyphs: int32){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_text_path*(cr: Pcairo_t, utf8: cstring){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_glyph_path*(cr: Pcairo_t, glyphs: Pcairo_glyph_t, num_glyphs: int32){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_text_extents*(cr: Pcairo_t, utf8: cstring,
|
||||
extents: Pcairo_text_extents_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_glyph_extents*(cr: Pcairo_t, glyphs: Pcairo_glyph_t,
|
||||
num_glyphs: int32, extents: Pcairo_text_extents_t){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_font_extents*(cr: Pcairo_t, extents: Pcairo_font_extents_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
#* Generic identifier for a font style
|
||||
proc cairo_font_face_reference*(font_face: Pcairo_font_face_t): Pcairo_font_face_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_font_face_destroy*(font_face: Pcairo_font_face_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_font_face_get_reference_count*(font_face: Pcairo_font_face_t): int32{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_font_face_status*(font_face: Pcairo_font_face_t): cairo_status_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_font_face_get_type*(font_face: Pcairo_font_face_t): cairo_font_type_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_font_face_get_user_data*(font_face: Pcairo_font_face_t,
|
||||
key: Pcairo_user_data_key_t): pointer{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_font_face_set_user_data*(font_face: Pcairo_font_face_t,
|
||||
key: Pcairo_user_data_key_t,
|
||||
user_data: pointer,
|
||||
destroy: cairo_destroy_func_t): cairo_status_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
#* Portable interface to general font features
|
||||
proc cairo_scaled_font_create*(font_face: Pcairo_font_face_t,
|
||||
font_matrix: Pcairo_matrix_t,
|
||||
ctm: Pcairo_matrix_t,
|
||||
options: Pcairo_font_options_t): Pcairo_scaled_font_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_scaled_font_reference*(scaled_font: Pcairo_scaled_font_t): Pcairo_scaled_font_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_scaled_font_destroy*(scaled_font: Pcairo_scaled_font_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_scaled_font_get_reference_count*(scaled_font: Pcairo_scaled_font_t): int32{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_scaled_font_status*(scaled_font: Pcairo_scaled_font_t): cairo_status_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_scaled_font_get_type*(scaled_font: Pcairo_scaled_font_t): cairo_font_type_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_scaled_font_get_user_data*(scaled_font: Pcairo_scaled_font_t,
|
||||
key: Pcairo_user_data_key_t): Pointer{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_scaled_font_set_user_data*(scaled_font: Pcairo_scaled_font_t,
|
||||
key: Pcairo_user_data_key_t,
|
||||
user_data: Pointer,
|
||||
destroy: cairo_destroy_func_t): cairo_status_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_scaled_font_extents*(scaled_font: Pcairo_scaled_font_t,
|
||||
extents: Pcairo_font_extents_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_scaled_font_text_extents*(scaled_font: Pcairo_scaled_font_t,
|
||||
utf8: cstring,
|
||||
extents: Pcairo_text_extents_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_scaled_font_glyph_extents*(scaled_font: Pcairo_scaled_font_t,
|
||||
glyphs: Pcairo_glyph_t, num_glyphs: int32,
|
||||
extents: Pcairo_text_extents_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_scaled_font_get_font_face*(scaled_font: Pcairo_scaled_font_t): Pcairo_font_face_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_scaled_font_get_font_matrix*(scaled_font: Pcairo_scaled_font_t,
|
||||
font_matrix: Pcairo_matrix_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_scaled_font_get_ctm*(scaled_font: Pcairo_scaled_font_t,
|
||||
ctm: Pcairo_matrix_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_scaled_font_get_font_options*(scaled_font: Pcairo_scaled_font_t,
|
||||
options: Pcairo_font_options_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
#* Query functions
|
||||
proc cairo_get_operator*(cr: Pcairo_t): cairo_operator_t{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_get_source*(cr: Pcairo_t): Pcairo_pattern_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_get_tolerance*(cr: Pcairo_t): float64{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_get_antialias*(cr: Pcairo_t): cairo_antialias_t{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_get_current_point*(cr: Pcairo_t, x, y: var float64){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_get_fill_rule*(cr: Pcairo_t): cairo_fill_rule_t{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_get_line_width*(cr: Pcairo_t): float64{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_get_line_cap*(cr: Pcairo_t): cairo_line_cap_t{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_get_line_join*(cr: Pcairo_t): cairo_line_join_t{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_get_miter_limit*(cr: Pcairo_t): float64{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_get_dash_count*(cr: Pcairo_t): int32{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_get_dash*(cr: Pcairo_t, dashes, offset: var float64){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_get_matrix*(cr: Pcairo_t, matrix: Pcairo_matrix_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_get_target*(cr: Pcairo_t): Pcairo_surface_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_get_group_target*(cr: Pcairo_t): Pcairo_surface_t{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_copy_path*(cr: Pcairo_t): Pcairo_path_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_copy_path_flat*(cr: Pcairo_t): Pcairo_path_t{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_append_path*(cr: Pcairo_t, path: Pcairo_path_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_path_destroy*(path: Pcairo_path_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
#* Error status queries
|
||||
proc cairo_status*(cr: Pcairo_t): cairo_status_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_status_to_string*(status: cairo_status_t): cstring{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
#* Surface manipulation
|
||||
proc cairo_surface_create_similar*(other: Pcairo_surface_t,
|
||||
content: cairo_content_t,
|
||||
width, height: int32): Pcairo_surface_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_surface_reference*(surface: Pcairo_surface_t): Pcairo_surface_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_surface_finish*(surface: Pcairo_surface_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_surface_destroy*(surface: Pcairo_surface_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_surface_get_reference_count*(surface: Pcairo_surface_t): int32{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_surface_status*(surface: Pcairo_surface_t): cairo_status_t{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_surface_get_type*(surface: Pcairo_surface_t): cairo_surface_type_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_surface_get_content*(surface: Pcairo_surface_t): cairo_content_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_surface_write_to_png*(surface: Pcairo_surface_t, filename: cstring): cairo_status_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_surface_write_to_png_stream*(surface: Pcairo_surface_t,
|
||||
write_func: cairo_write_func_t,
|
||||
closure: pointer): cairo_status_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_surface_get_user_data*(surface: Pcairo_surface_t,
|
||||
key: Pcairo_user_data_key_t): pointer{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_surface_set_user_data*(surface: Pcairo_surface_t,
|
||||
key: Pcairo_user_data_key_t,
|
||||
user_data: pointer,
|
||||
destroy: cairo_destroy_func_t): cairo_status_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_surface_get_font_options*(surface: Pcairo_surface_t,
|
||||
options: Pcairo_font_options_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_surface_flush*(surface: Pcairo_surface_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_surface_mark_dirty*(surface: Pcairo_surface_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_surface_mark_dirty_rectangle*(surface: Pcairo_surface_t,
|
||||
x, y, width, height: int32){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_surface_set_device_offset*(surface: Pcairo_surface_t,
|
||||
x_offset, y_offset: float64){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_surface_get_device_offset*(surface: Pcairo_surface_t,
|
||||
x_offset, y_offset: var float64){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_surface_set_fallback_resolution*(surface: Pcairo_surface_t,
|
||||
x_pixels_per_inch, y_pixels_per_inch: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
#* Image-surface functions
|
||||
proc cairo_image_surface_create*(format: cairo_format_t, width, height: int32): Pcairo_surface_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_image_surface_create_for_data*(data: Pbyte, format: cairo_format_t,
|
||||
width, height, stride: int32): Pcairo_surface_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_image_surface_get_data*(surface: Pcairo_surface_t): cstring{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_image_surface_get_format*(surface: Pcairo_surface_t): cairo_format_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_image_surface_get_width*(surface: Pcairo_surface_t): int32{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_image_surface_get_height*(surface: Pcairo_surface_t): int32{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_image_surface_get_stride*(surface: Pcairo_surface_t): int32{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_image_surface_create_from_png*(filename: cstring): Pcairo_surface_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_image_surface_create_from_png_stream*(read_func: cairo_read_func_t,
|
||||
closure: pointer): Pcairo_surface_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
#* Pattern creation functions
|
||||
proc cairo_pattern_create_rgb*(red, green, blue: float64): Pcairo_pattern_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_pattern_create_rgba*(red, green, blue, alpha: float64): Pcairo_pattern_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_pattern_create_for_surface*(surface: Pcairo_surface_t): Pcairo_pattern_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_pattern_create_linear*(x0, y0, x1, y1: float64): Pcairo_pattern_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_pattern_create_radial*(cx0, cy0, radius0, cx1, cy1, radius1: float64): Pcairo_pattern_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_pattern_reference*(pattern: Pcairo_pattern_t): Pcairo_pattern_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_pattern_destroy*(pattern: Pcairo_pattern_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_pattern_get_reference_count*(pattern: Pcairo_pattern_t): int32{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_pattern_status*(pattern: Pcairo_pattern_t): cairo_status_t{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_pattern_get_user_data*(pattern: Pcairo_pattern_t,
|
||||
key: Pcairo_user_data_key_t): Pointer{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_pattern_set_user_data*(pattern: Pcairo_pattern_t,
|
||||
key: Pcairo_user_data_key_t,
|
||||
user_data: Pointer,
|
||||
destroy: cairo_destroy_func_t): cairo_status_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_pattern_get_type*(pattern: Pcairo_pattern_t): cairo_pattern_type_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_pattern_add_color_stop_rgb*(pattern: Pcairo_pattern_t,
|
||||
offset, red, green, blue: float64){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_pattern_add_color_stop_rgba*(pattern: Pcairo_pattern_t, offset, red,
|
||||
green, blue, alpha: float64){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_pattern_set_matrix*(pattern: Pcairo_pattern_t,
|
||||
matrix: Pcairo_matrix_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_pattern_get_matrix*(pattern: Pcairo_pattern_t,
|
||||
matrix: Pcairo_matrix_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_pattern_set_extend*(pattern: Pcairo_pattern_t, extend: cairo_extend_t){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_pattern_get_extend*(pattern: Pcairo_pattern_t): cairo_extend_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_pattern_set_filter*(pattern: Pcairo_pattern_t, filter: cairo_filter_t){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_pattern_get_filter*(pattern: Pcairo_pattern_t): cairo_filter_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_pattern_get_rgba*(pattern: Pcairo_pattern_t,
|
||||
red, green, blue, alpha: var float64): cairo_status_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_pattern_get_surface*(pattern: Pcairo_pattern_t,
|
||||
surface: PPcairo_surface_t): cairo_status_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_pattern_get_color_stop_rgba*(pattern: Pcairo_pattern_t, index: int32,
|
||||
offset, red, green, blue, alpha: var float64): cairo_status_t{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_pattern_get_color_stop_count*(pattern: Pcairo_pattern_t,
|
||||
count: var int32): cairo_status_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_pattern_get_linear_points*(pattern: Pcairo_pattern_t,
|
||||
x0, y0, x1, y1: var float64): cairo_status_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_pattern_get_radial_circles*(pattern: Pcairo_pattern_t,
|
||||
x0, y0, r0, x1, y1, r1: var float64): cairo_status_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
#* Matrix functions
|
||||
proc cairo_matrix_init*(matrix: Pcairo_matrix_t, xx, yx, xy, yy, x0, y0: float64){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_matrix_init_identity*(matrix: Pcairo_matrix_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_matrix_init_translate*(matrix: Pcairo_matrix_t, tx, ty: float64){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_matrix_init_scale*(matrix: Pcairo_matrix_t, sx, sy: float64){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_matrix_init_rotate*(matrix: Pcairo_matrix_t, radians: float64){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_matrix_translate*(matrix: Pcairo_matrix_t, tx, ty: float64){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_matrix_scale*(matrix: Pcairo_matrix_t, sx, sy: float64){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_matrix_rotate*(matrix: Pcairo_matrix_t, radians: float64){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_matrix_invert*(matrix: Pcairo_matrix_t): cairo_status_t{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_matrix_multiply*(result, a, b: Pcairo_matrix_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_matrix_transform_distance*(matrix: Pcairo_matrix_t, dx, dy: var float64){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_matrix_transform_point*(matrix: Pcairo_matrix_t, x, y: var float64){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
#* PDF functions
|
||||
proc cairo_pdf_surface_create*(filename: cstring,
|
||||
width_in_points, height_in_points: float64): Pcairo_surface_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_pdf_surface_create_for_stream*(write_func: cairo_write_func_t,
|
||||
closure: Pointer, width_in_points, height_in_points: float64): Pcairo_surface_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_pdf_surface_set_size*(surface: Pcairo_surface_t,
|
||||
width_in_points, height_in_points: float64){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
#* PS functions
|
||||
proc cairo_ps_surface_create*(filename: cstring,
|
||||
width_in_points, height_in_points: float64): Pcairo_surface_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_ps_surface_create_for_stream*(write_func: cairo_write_func_t,
|
||||
closure: Pointer, width_in_points, height_in_points: float64): Pcairo_surface_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_ps_surface_set_size*(surface: Pcairo_surface_t,
|
||||
width_in_points, height_in_points: float64){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_ps_surface_dsc_comment*(surface: Pcairo_surface_t, comment: cstring){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_ps_surface_dsc_begin_setup*(surface: Pcairo_surface_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_ps_surface_dsc_begin_page_setup*(surface: Pcairo_surface_t){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
#* SVG functions
|
||||
proc cairo_svg_surface_create*(filename: cstring,
|
||||
width_in_points, height_in_points: float64): Pcairo_surface_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_svg_surface_create_for_stream*(write_func: cairo_write_func_t,
|
||||
closure: Pointer, width_in_points, height_in_points: float64): Pcairo_surface_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_svg_surface_restrict_to_version*(surface: Pcairo_surface_t,
|
||||
version: cairo_svg_version_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
#todo: see how translate this
|
||||
#procedure cairo_svg_get_versions(cairo_svg_version_t const **versions,
|
||||
# int *num_versions);
|
||||
proc cairo_svg_version_to_string*(version: cairo_svg_version_t): cstring{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
#* Functions to be used while debugging (not intended for use in production code)
|
||||
proc cairo_debug_reset_static_data*(){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
# implementation
|
||||
|
||||
proc cairo_version(major, minor, micro: var int32) =
|
||||
var version: int32
|
||||
version = cairo_version()
|
||||
major = version div 10000
|
||||
minor = (version mod (major * 10000)) div 100
|
||||
micro = (version mod ((major * 10000) + (minor * 100)))
|
||||
36
lib/base/cairo/cairoft.nim
Normal file
36
lib/base/cairo/cairoft.nim
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#
|
||||
# Translation of cairo-ft.h
|
||||
# by Jeffrey Pohlmeyer
|
||||
# updated to version 1.4 by Luiz Américo Pereira Câmara 2007
|
||||
#
|
||||
|
||||
import Cairo, freetypeh
|
||||
|
||||
#todo: properly define FcPattern:
|
||||
#It will require translate FontConfig header
|
||||
|
||||
#*
|
||||
#typedef struct _XftPattern {
|
||||
# int num;
|
||||
# int size;
|
||||
# XftPatternElt *elts;
|
||||
# } XftPattern;
|
||||
# typedef FcPattern XftPattern;
|
||||
#
|
||||
|
||||
type
|
||||
FcPattern* = Pointer
|
||||
PFcPattern* = ref FcPattern
|
||||
|
||||
proc cairo_ft_font_face_create_for_pattern*(pattern: PFcPattern): Pcairo_font_face_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_ft_font_options_substitute*(options: Pcairo_font_options_t,
|
||||
pattern: PFcPattern){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_ft_font_face_create_for_ft_face*(face: TFT_Face,
|
||||
load_flags: int32): Pcairo_font_face_t {.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_ft_scaled_font_lock_face*(
|
||||
scaled_font: Pcairo_scaled_font_t): TFT_Face{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_ft_scaled_font_unlock_face*(
|
||||
scaled_font: Pcairo_scaled_font_t){.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
|
||||
36
lib/base/cairo/cairowin32.nim
Normal file
36
lib/base/cairo/cairowin32.nim
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
|
||||
#
|
||||
# Translation of cairo-win32.h version 1.4
|
||||
# by Luiz Américo Pereira Câmara 2007
|
||||
#
|
||||
|
||||
import
|
||||
Cairo, windows
|
||||
|
||||
proc cairo_win32_surface_create*(hdc: HDC): Pcairo_surface_t{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_win32_surface_create_with_ddb*(hdc: HDC, format: cairo_format_t,
|
||||
width, height: int32): Pcairo_surface_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_win32_surface_create_with_dib*(format: cairo_format_t,
|
||||
width, height: int32): Pcairo_surface_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_win32_surface_get_dc*(surface: pcairo_surface_t): HDC{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_win32_surface_get_image*(surface: pcairo_surface_t): Pcairo_surface_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_win32_font_face_create_for_logfontw*(logfont: pLOGFONTW): Pcairo_font_face_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_win32_font_face_create_for_hfont*(font: HFONT): Pcairo_font_face_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_win32_scaled_font_select_font*(scaled_font: pcairo_scaled_font_t,
|
||||
hdc: HDC): cairo_status_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_win32_scaled_font_done_font*(scaled_font: pcairo_scaled_font_t){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_win32_scaled_font_get_metrics_factor*(
|
||||
scaled_font: pcairo_scaled_font_t): float64{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_win32_scaled_font_get_logical_to_device*(
|
||||
scaled_font: pcairo_scaled_font_t, logical_to_device: pcairo_matrix_t){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_win32_scaled_font_get_device_to_logical*(
|
||||
scaled_font: pcairo_scaled_font_t, device_to_logical: pcairo_matrix_t){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
# implementation
|
||||
40
lib/base/cairo/cairoxlib.nim
Normal file
40
lib/base/cairo/cairoxlib.nim
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
|
||||
#
|
||||
# Translation of cairo-xlib.h version 1.4
|
||||
# by Jeffrey Pohlmeyer
|
||||
# updated to version 1.4 by Luiz Américo Pereira Câmara 2007
|
||||
#
|
||||
|
||||
import
|
||||
Cairo, x, xlib, xrender
|
||||
|
||||
proc cairo_xlib_surface_create*(dpy: PDisplay, drawable: TDrawable,
|
||||
visual: PVisual, width, height: int32): Pcairo_surface_t{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_xlib_surface_create_for_bitmap*(dpy: PDisplay, bitmap: TPixmap,
|
||||
screen: PScreen, width, height: int32): Pcairo_surface_t{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_xlib_surface_create_with_xrender_format*(dpy: PDisplay,
|
||||
drawable: TDrawable, screen: PScreen, format: PXRenderPictFormat,
|
||||
width, height: int32): Pcairo_surface_t{.cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_xlib_surface_get_depth*(surface: Pcairo_surface_t): int32{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_xlib_surface_get_display*(surface: Pcairo_surface_t): PDisplay{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_xlib_surface_get_drawable*(surface: Pcairo_surface_t): TDrawable{.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
proc cairo_xlib_surface_get_height*(surface: Pcairo_surface_t): int32{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_xlib_surface_get_screen*(surface: Pcairo_surface_t): PScreen{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_xlib_surface_get_visual*(surface: Pcairo_surface_t): PVisual{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_xlib_surface_get_width*(surface: Pcairo_surface_t): int32{.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_xlib_surface_set_size*(surface: Pcairo_surface_t,
|
||||
width, height: int32){.cdecl, importc,
|
||||
dynlib: LIB_CAIRO.}
|
||||
proc cairo_xlib_surface_set_drawable*(surface: Pcairo_surface_t,
|
||||
drawable: TDrawable, width, height: int32){.
|
||||
cdecl, importc, dynlib: LIB_CAIRO.}
|
||||
# implementation
|
||||
234
lib/base/dialogs.nim
Executable file
234
lib/base/dialogs.nim
Executable file
|
|
@ -0,0 +1,234 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2008 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
|
||||
## This module implements portable dialogs for Nimrod; the implementation
|
||||
## builds on the GTK interface. On Windows, native dialogs are shown if
|
||||
## appropriate.
|
||||
|
||||
import
|
||||
glib2, gtk2
|
||||
|
||||
when defined(Windows):
|
||||
import windows, ShellAPI, os
|
||||
|
||||
type
|
||||
PWindow* = PGtkWindow ## A shortcut for a GTK window.
|
||||
|
||||
proc info*(window: PWindow, msg: string) =
|
||||
## Shows an information message to the user. The process waits until the
|
||||
## user presses the OK button.
|
||||
when defined(Windows):
|
||||
discard MessageBoxA(0, msg, "Information", MB_OK or MB_ICONINFORMATION)
|
||||
else:
|
||||
var dialog = GTK_DIALOG(gtk_message_dialog_new(window,
|
||||
GTK_DIALOG_MODAL or GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "%s", cstring(msg)))
|
||||
gtk_window_set_title(dialog, "Information")
|
||||
discard gtk_dialog_run(dialog)
|
||||
gtk_widget_destroy(dialog)
|
||||
|
||||
proc warning*(window: PWindow, msg: string) =
|
||||
## Shows a warning message to the user. The process waits until the user
|
||||
## presses the OK button.
|
||||
when defined(Windows):
|
||||
discard MessageBoxA(0, msg, "Warning", MB_OK or MB_ICONWARNING)
|
||||
else:
|
||||
var dialog = GTK_DIALOG(gtk_message_dialog_new(window,
|
||||
GTK_DIALOG_MODAL or GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "%s", cstring(msg)))
|
||||
gtk_window_set_title(dialog, "Warning")
|
||||
discard gtk_dialog_run(dialog)
|
||||
gtk_widget_destroy(dialog)
|
||||
|
||||
proc error*(window: PWindow, msg: string) =
|
||||
## Shows an error message to the user. The process waits until the user
|
||||
## presses the OK button.
|
||||
when defined(Windows):
|
||||
discard MessageBoxA(0, msg, "Error", MB_OK or MB_ICONERROR)
|
||||
else:
|
||||
var dialog = GTK_DIALOG(gtk_message_dialog_new(window,
|
||||
GTK_DIALOG_MODAL or GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", cstring(msg)))
|
||||
gtk_window_set_title(dialog, "Error")
|
||||
discard gtk_dialog_run(dialog)
|
||||
gtk_widget_destroy(dialog)
|
||||
|
||||
|
||||
proc ChooseFileToOpen*(window: PWindow, root: string = ""): string =
|
||||
## Opens a dialog that requests a filename from the user. Returns ""
|
||||
## if the user closed the dialog without selecting a file. On Windows,
|
||||
## the native dialog is used, else the GTK dialog is used.
|
||||
when defined(Windows):
|
||||
var
|
||||
opf: TOPENFILENAME
|
||||
buf: array [0..2047, char]
|
||||
opf.lStructSize = sizeof(opf)
|
||||
if root.len > 0:
|
||||
opf.lpstrInitialDir = root
|
||||
opf.lpstrFilter = "All Files\0*.*\0\0"
|
||||
opf.flags = OFN_FILEMUSTEXIST
|
||||
opf.lpstrFile = buf
|
||||
opf.nMaxFile = sizeof(buf)
|
||||
var res = GetOpenFileName(addr(opf))
|
||||
if res != 0:
|
||||
result = $buf
|
||||
else:
|
||||
result = ""
|
||||
else:
|
||||
var
|
||||
chooser: PGtkDialog
|
||||
chooser = GTK_DIALOG(gtk_file_chooser_dialog_new("Open File", window,
|
||||
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OPEN, GTK_RESPONSE_OK, nil))
|
||||
if root.len > 0:
|
||||
discard gtk_file_chooser_set_current_folder(chooser, root)
|
||||
if gtk_dialog_run(chooser) == GTK_RESPONSE_OK:
|
||||
var x = gtk_file_chooser_get_filename(chooser)
|
||||
result = $x
|
||||
g_free(x)
|
||||
else:
|
||||
result = ""
|
||||
gtk_widget_destroy(chooser)
|
||||
|
||||
proc ChooseFilesToOpen*(window: PWindow, root: string = ""): seq[string] =
|
||||
## Opens a dialog that requests filenames from the user. Returns []
|
||||
## if the user closed the dialog without selecting a file. On Windows,
|
||||
## the native dialog is used, else the GTK dialog is used.
|
||||
when defined(Windows):
|
||||
var
|
||||
opf: TOPENFILENAME
|
||||
buf: array [0..2047*4, char]
|
||||
opf.lStructSize = sizeof(opf)
|
||||
if root.len > 0:
|
||||
opf.lpstrInitialDir = root
|
||||
opf.lpstrFilter = "All Files\0*.*\0\0"
|
||||
opf.flags = OFN_FILEMUSTEXIST or OFN_ALLOWMULTISELECT or OFN_EXPLORER
|
||||
opf.lpstrFile = buf
|
||||
opf.nMaxFile = sizeof(buf)
|
||||
var res = GetOpenFileName(addr(opf))
|
||||
result = []
|
||||
if res != 0:
|
||||
# parsing the result is horrible:
|
||||
var
|
||||
i = 0
|
||||
s: string
|
||||
path = ""
|
||||
while buf[i] != '\0':
|
||||
add(path, buf[i])
|
||||
inc(i)
|
||||
inc(i)
|
||||
if buf[i] != '\0':
|
||||
while true:
|
||||
s = ""
|
||||
while buf[i] != '\0':
|
||||
add(s, buf[i])
|
||||
inc(i)
|
||||
add(result, s)
|
||||
inc(i)
|
||||
if buf[i] == '\0': break
|
||||
for i in 0..result.len-1: result[i] = os.joinPath(path, result[i])
|
||||
else:
|
||||
var
|
||||
chooser: PGtkDialog
|
||||
chooser = GTK_DIALOG(gtk_file_chooser_dialog_new("Open Files", window,
|
||||
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OPEN, GTK_RESPONSE_OK, nil))
|
||||
if root.len > 0:
|
||||
discard gtk_file_chooser_set_current_folder(chooser, root)
|
||||
gtk_file_chooser_set_select_multiple(chooser, true)
|
||||
result = []
|
||||
if gtk_dialog_run(chooser) == GTK_RESPONSE_OK:
|
||||
var L = gtk_file_chooser_get_filenames(chooser)
|
||||
var it = L
|
||||
while it != nil:
|
||||
add(result, $cast[cstring](it.data))
|
||||
g_free(it.data)
|
||||
it = it.next
|
||||
g_slist_free(L)
|
||||
gtk_widget_destroy(chooser)
|
||||
|
||||
|
||||
proc ChooseFileToSave*(window: PWindow, root: string = ""): string =
|
||||
## Opens a dialog that requests a filename to save to from the user.
|
||||
## Returns "" if the user closed the dialog without selecting a file.
|
||||
## On Windows, the native dialog is used, else the GTK dialog is used.
|
||||
when defined(Windows):
|
||||
var
|
||||
opf: TOPENFILENAME
|
||||
buf: array [0..2047, char]
|
||||
opf.lStructSize = sizeof(opf)
|
||||
if root.len > 0:
|
||||
opf.lpstrInitialDir = root
|
||||
opf.lpstrFilter = "All Files\0*.*\0\0"
|
||||
opf.flags = OFN_OVERWRITEPROMPT
|
||||
opf.lpstrFile = buf
|
||||
opf.nMaxFile = sizeof(buf)
|
||||
var res = GetSaveFileName(addr(opf))
|
||||
if res != 0:
|
||||
result = $buf
|
||||
else:
|
||||
result = ""
|
||||
else:
|
||||
var
|
||||
chooser: PGtkDialog
|
||||
chooser = GTK_DIALOG(gtk_file_chooser_dialog_new("Save File", window,
|
||||
GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OPEN, GTK_RESPONSE_OK, nil))
|
||||
if root.len > 0:
|
||||
discard gtk_file_chooser_set_current_folder(chooser, root)
|
||||
gtk_file_chooser_set_do_overwrite_confirmation(chooser, true)
|
||||
if gtk_dialog_run(chooser) == GTK_RESPONSE_OK:
|
||||
var x = gtk_file_chooser_get_filename(chooser)
|
||||
result = $x
|
||||
g_free(x)
|
||||
else:
|
||||
result = ""
|
||||
gtk_widget_destroy(chooser)
|
||||
|
||||
|
||||
proc ChooseDir*(window: PWindow, root: string = ""): string =
|
||||
## Opens a dialog that requests a directory from the user.
|
||||
## Returns "" if the user closed the dialog without selecting a directory.
|
||||
## On Windows, the native dialog is used, else the GTK dialog is used.
|
||||
when defined(Windows):
|
||||
var
|
||||
lpItemID: PItemIDList
|
||||
BrowseInfo: TBrowseInfo
|
||||
DisplayName: array [0..MAX_PATH, char]
|
||||
TempPath: array [0..MAX_PATH, char]
|
||||
Result = ""
|
||||
#BrowseInfo.hwndOwner = Application.Handle
|
||||
BrowseInfo.pszDisplayName = DisplayName
|
||||
BrowseInfo.ulFlags = 1 #BIF_RETURNONLYFSDIRS
|
||||
lpItemID = SHBrowseForFolder(cast[LPBrowseInfo](addr(BrowseInfo)))
|
||||
if lpItemId != nil:
|
||||
discard SHGetPathFromIDList(lpItemID, TempPath)
|
||||
Result = $TempPath
|
||||
discard GlobalFreePtr(lpItemID)
|
||||
else:
|
||||
var
|
||||
chooser: PGtkDialog
|
||||
chooser = GTK_DIALOG(gtk_file_chooser_dialog_new("Select Directory", window,
|
||||
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OPEN, GTK_RESPONSE_OK, nil))
|
||||
if root.len > 0:
|
||||
discard gtk_file_chooser_set_current_folder(chooser, root)
|
||||
if gtk_dialog_run(chooser) == GTK_RESPONSE_OK:
|
||||
var x = gtk_file_chooser_get_filename(chooser)
|
||||
result = $x
|
||||
g_free(x)
|
||||
else:
|
||||
result = ""
|
||||
gtk_widget_destroy(chooser)
|
||||
|
||||
1368
lib/base/gtk/atk.nim
Executable file
1368
lib/base/gtk/atk.nim
Executable file
File diff suppressed because it is too large
Load diff
3957
lib/base/gtk/gdk2.nim
Executable file
3957
lib/base/gtk/gdk2.nim
Executable file
File diff suppressed because it is too large
Load diff
279
lib/base/gtk/gdk2pixbuf.nim
Executable file
279
lib/base/gtk/gdk2pixbuf.nim
Executable file
|
|
@ -0,0 +1,279 @@
|
|||
import
|
||||
glib2
|
||||
|
||||
when defined(win32):
|
||||
{.define: gdkpixbufwin.}
|
||||
const
|
||||
gdkpixbuflib = "libgdk_pixbuf-2.0-0.dll"
|
||||
elif defined(darwin):
|
||||
const
|
||||
gdkpixbuflib = "gdk_pixbuf-2.0.0"
|
||||
# linklib gtk-x11-2.0
|
||||
# linklib gdk-x11-2.0
|
||||
# linklib pango-1.0.0
|
||||
# linklib glib-2.0.0
|
||||
# linklib gobject-2.0.0
|
||||
# linklib gdk_pixbuf-2.0.0
|
||||
# linklib atk-1.0.0
|
||||
else:
|
||||
const
|
||||
gdkpixbuflib = "libgdk_pixbuf-2.0.so"
|
||||
{.define: HasGTK2_4.}
|
||||
{.define: HasGTK2_6.}
|
||||
type
|
||||
PGdkPixbuf* = pointer
|
||||
PGdkPixbufAnimation* = pointer
|
||||
PGdkPixbufAnimationIter* = pointer
|
||||
PGdkPixbufAlphaMode* = ptr TGdkPixbufAlphaMode
|
||||
TGdkPixbufAlphaMode* = enum
|
||||
GDK_PIXBUF_ALPHA_BILEVEL, GDK_PIXBUF_ALPHA_FULL
|
||||
PGdkColorspace* = ptr TGdkColorspace
|
||||
TGdkColorspace* = enum
|
||||
GDK_COLORSPACE_RGB
|
||||
TGdkPixbufDestroyNotify* = proc (pixels: Pguchar, data: gpointer){.cdecl.}
|
||||
PGdkPixbufError* = ptr TGdkPixbufError
|
||||
TGdkPixbufError* = enum
|
||||
GDK_PIXBUF_ERROR_CORRUPT_IMAGE, GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
|
||||
GDK_PIXBUF_ERROR_BAD_OPTION, GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
|
||||
GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION, GDK_PIXBUF_ERROR_FAILED
|
||||
PGdkInterpType* = ptr TGdkInterpType
|
||||
TGdkInterpType* = enum
|
||||
GDK_INTERP_NEAREST, GDK_INTERP_TILES, GDK_INTERP_BILINEAR, GDK_INTERP_HYPER
|
||||
|
||||
proc GDK_TYPE_PIXBUF*(): GType
|
||||
proc GDK_PIXBUF*(anObject: pointer): PGdkPixbuf
|
||||
proc GDK_IS_PIXBUF*(anObject: pointer): bool
|
||||
proc GDK_TYPE_PIXBUF_ANIMATION*(): GType
|
||||
proc GDK_PIXBUF_ANIMATION*(anObject: pointer): PGdkPixbufAnimation
|
||||
proc GDK_IS_PIXBUF_ANIMATION*(anObject: pointer): bool
|
||||
proc GDK_TYPE_PIXBUF_ANIMATION_ITER*(): GType
|
||||
proc GDK_PIXBUF_ANIMATION_ITER*(anObject: pointer): PGdkPixbufAnimationIter
|
||||
proc GDK_IS_PIXBUF_ANIMATION_ITER*(anObject: pointer): bool
|
||||
proc GDK_PIXBUF_ERROR*(): TGQuark
|
||||
proc gdk_pixbuf_error_quark*(): TGQuark{.cdecl, dynlib: gdkpixbuflib,
|
||||
importc: "gdk_pixbuf_error_quark".}
|
||||
proc gdk_pixbuf_get_type*(): GType{.cdecl, dynlib: gdkpixbuflib,
|
||||
importc: "gdk_pixbuf_get_type".}
|
||||
when not defined(GDK_PIXBUF_DISABLE_DEPRECATED):
|
||||
proc gdk_pixbuf_ref(pixbuf: PGdkPixbuf): PGdkPixbuf{.cdecl,
|
||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_ref".}
|
||||
proc gdk_pixbuf_unref(pixbuf: PGdkPixbuf){.cdecl, dynlib: gdkpixbuflib,
|
||||
importc: "gdk_pixbuf_unref".}
|
||||
proc gdk_pixbuf_get_colorspace*(pixbuf: PGdkPixbuf): TGdkColorspace{.cdecl,
|
||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_get_colorspace".}
|
||||
proc gdk_pixbuf_get_n_channels*(pixbuf: PGdkPixbuf): int32{.cdecl,
|
||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_get_n_channels".}
|
||||
proc gdk_pixbuf_get_has_alpha*(pixbuf: PGdkPixbuf): gboolean{.cdecl,
|
||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_get_has_alpha".}
|
||||
proc gdk_pixbuf_get_bits_per_sample*(pixbuf: PGdkPixbuf): int32{.cdecl,
|
||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_get_bits_per_sample".}
|
||||
proc gdk_pixbuf_get_pixels*(pixbuf: PGdkPixbuf): Pguchar{.cdecl,
|
||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_get_pixels".}
|
||||
proc gdk_pixbuf_get_width*(pixbuf: PGdkPixbuf): int32{.cdecl,
|
||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_get_width".}
|
||||
proc gdk_pixbuf_get_height*(pixbuf: PGdkPixbuf): int32{.cdecl,
|
||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_get_height".}
|
||||
proc gdk_pixbuf_get_rowstride*(pixbuf: PGdkPixbuf): int32{.cdecl,
|
||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_get_rowstride".}
|
||||
proc gdk_pixbuf_new*(colorspace: TGdkColorspace, has_alpha: gboolean,
|
||||
bits_per_sample: int32, width: int32, height: int32): PGdkPixbuf{.
|
||||
cdecl, dynlib: gdkpixbuflib, importc: "gdk_pixbuf_new".}
|
||||
proc gdk_pixbuf_copy*(pixbuf: PGdkPixbuf): PGdkPixbuf{.cdecl,
|
||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_copy".}
|
||||
proc gdk_pixbuf_new_subpixbuf*(src_pixbuf: PGdkPixbuf, src_x: int32,
|
||||
src_y: int32, width: int32, height: int32): PGdkPixbuf{.
|
||||
cdecl, dynlib: gdkpixbuflib, importc: "gdk_pixbuf_new_subpixbuf".}
|
||||
proc gdk_pixbuf_new_from_file*(filename: cstring, error: pointer): PGdkPixbuf{.
|
||||
cdecl, dynlib: gdkpixbuflib, importc: "gdk_pixbuf_new_from_file".}
|
||||
proc gdk_pixbuf_new_from_data*(data: Pguchar, colorspace: TGdkColorspace,
|
||||
has_alpha: gboolean, bits_per_sample: int32,
|
||||
width: int32, height: int32, rowstride: int32,
|
||||
destroy_fn: TGdkPixbufDestroyNotify,
|
||||
destroy_fn_data: gpointer): PGdkPixbuf{.cdecl,
|
||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_new_from_data".}
|
||||
proc gdk_pixbuf_new_from_xpm_data*(data: PPchar): PGdkPixbuf{.cdecl,
|
||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_new_from_xpm_data".}
|
||||
proc gdk_pixbuf_new_from_inline*(data_length: gint, a: var guint8,
|
||||
copy_pixels: gboolean, error: pointer): PGdkPixbuf{.
|
||||
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,
|
||||
error: pointer): PGdkPixbuf{.cdecl,
|
||||
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,
|
||||
preserve_aspect_ratio: gboolean, error: pointer): PGdkPixbuf{.cdecl,
|
||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_new_from_file_at_scale".}
|
||||
proc gdk_pixbuf_fill*(pixbuf: PGdkPixbuf, pixel: guint32){.cdecl,
|
||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_fill".}
|
||||
proc gdk_pixbuf_save*(pixbuf: PGdkPixbuf, filename: cstring, `type`: cstring,
|
||||
error: pointer): gboolean{.cdecl, varargs,
|
||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_save".}
|
||||
proc gdk_pixbuf_savev*(pixbuf: PGdkPixbuf, filename: cstring, `type`: cstring,
|
||||
option_keys: PPchar, option_values: PPchar,
|
||||
error: pointer): gboolean{.cdecl, dynlib: gdkpixbuflib,
|
||||
importc: "gdk_pixbuf_savev".}
|
||||
proc gdk_pixbuf_add_alpha*(pixbuf: PGdkPixbuf, substitute_color: gboolean,
|
||||
r: guchar, g: guchar, b: guchar): PGdkPixbuf{.cdecl,
|
||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_add_alpha".}
|
||||
proc gdk_pixbuf_copy_area*(src_pixbuf: PGdkPixbuf, src_x: int32, src_y: int32,
|
||||
width: int32, height: int32, dest_pixbuf: PGdkPixbuf,
|
||||
dest_x: int32, dest_y: int32){.cdecl,
|
||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_copy_area".}
|
||||
proc gdk_pixbuf_saturate_and_pixelate*(src: PGdkPixbuf, dest: PGdkPixbuf,
|
||||
saturation: gfloat, pixelate: gboolean){.
|
||||
cdecl, dynlib: gdkpixbuflib, importc: "gdk_pixbuf_saturate_and_pixelate".}
|
||||
proc gdk_pixbuf_scale*(src: PGdkPixbuf, dest: PGdkPixbuf, dest_x: int32,
|
||||
dest_y: int32, dest_width: int32, dest_height: int32,
|
||||
offset_x: float64, offset_y: float64, scale_x: float64,
|
||||
scale_y: float64, interp_type: TGdkInterpType){.cdecl,
|
||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_scale".}
|
||||
proc gdk_pixbuf_composite*(src: PGdkPixbuf, dest: PGdkPixbuf, dest_x: int32,
|
||||
dest_y: int32, dest_width: int32, dest_height: int32,
|
||||
offset_x: float64, offset_y: float64,
|
||||
scale_x: float64, scale_y: float64,
|
||||
interp_type: TGdkInterpType, overall_alpha: int32){.
|
||||
cdecl, dynlib: gdkpixbuflib, importc: "gdk_pixbuf_composite".}
|
||||
proc gdk_pixbuf_composite_color*(src: PGdkPixbuf, dest: PGdkPixbuf,
|
||||
dest_x: int32, dest_y: int32,
|
||||
dest_width: int32, dest_height: int32,
|
||||
offset_x: float64, offset_y: float64,
|
||||
scale_x: float64, scale_y: float64,
|
||||
interp_type: TGdkInterpType,
|
||||
overall_alpha: int32, check_x: int32,
|
||||
check_y: int32, check_size: int32,
|
||||
color1: guint32, color2: guint32){.cdecl,
|
||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_composite_color".}
|
||||
proc gdk_pixbuf_scale_simple*(src: PGdkPixbuf, dest_width: int32,
|
||||
dest_height: int32, interp_type: TGdkInterpType): PGdkPixbuf{.
|
||||
cdecl, dynlib: gdkpixbuflib, importc: "gdk_pixbuf_scale_simple".}
|
||||
proc gdk_pixbuf_composite_color_simple*(src: PGdkPixbuf, dest_width: int32,
|
||||
dest_height: int32,
|
||||
interp_type: TGdkInterpType,
|
||||
overall_alpha: int32, check_size: int32,
|
||||
color1: guint32, color2: guint32): PGdkPixbuf{.
|
||||
cdecl, dynlib: gdkpixbuflib, importc: "gdk_pixbuf_composite_color_simple".}
|
||||
proc gdk_pixbuf_animation_get_type*(): GType{.cdecl, dynlib: gdkpixbuflib,
|
||||
importc: "gdk_pixbuf_animation_get_type".}
|
||||
proc gdk_pixbuf_animation_new_from_file*(filename: cstring, error: pointer): PGdkPixbufAnimation{.
|
||||
cdecl, dynlib: gdkpixbuflib, importc: "gdk_pixbuf_animation_new_from_file".}
|
||||
when not defined(GDK_PIXBUF_DISABLE_DEPRECATED):
|
||||
proc gdk_pixbuf_animation_ref(animation: PGdkPixbufAnimation): PGdkPixbufAnimation{.
|
||||
cdecl, dynlib: gdkpixbuflib, importc: "gdk_pixbuf_animation_ref".}
|
||||
proc gdk_pixbuf_animation_unref(animation: PGdkPixbufAnimation){.cdecl,
|
||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_animation_unref".}
|
||||
proc gdk_pixbuf_animation_get_width*(animation: PGdkPixbufAnimation): int32{.
|
||||
cdecl, dynlib: gdkpixbuflib, importc: "gdk_pixbuf_animation_get_width".}
|
||||
proc gdk_pixbuf_animation_get_height*(animation: PGdkPixbufAnimation): int32{.
|
||||
cdecl, dynlib: gdkpixbuflib, importc: "gdk_pixbuf_animation_get_height".}
|
||||
proc gdk_pixbuf_animation_is_static_image*(animation: PGdkPixbufAnimation): gboolean{.
|
||||
cdecl, dynlib: gdkpixbuflib, importc: "gdk_pixbuf_animation_is_static_image".}
|
||||
proc gdk_pixbuf_animation_get_static_image*(animation: PGdkPixbufAnimation): PGdkPixbuf{.
|
||||
cdecl, dynlib: gdkpixbuflib,
|
||||
importc: "gdk_pixbuf_animation_get_static_image".}
|
||||
proc gdk_pixbuf_animation_get_iter*(animation: PGdkPixbufAnimation,
|
||||
e: var TGTimeVal): PGdkPixbufAnimationIter{.
|
||||
cdecl, dynlib: gdkpixbuflib, importc: "gdk_pixbuf_animation_get_iter".}
|
||||
proc gdk_pixbuf_animation_iter_get_type*(): GType{.cdecl, dynlib: gdkpixbuflib,
|
||||
importc: "gdk_pixbuf_animation_iter_get_type".}
|
||||
proc gdk_pixbuf_animation_iter_get_delay_time*(iter: PGdkPixbufAnimationIter): int32{.
|
||||
cdecl, dynlib: gdkpixbuflib,
|
||||
importc: "gdk_pixbuf_animation_iter_get_delay_time".}
|
||||
proc gdk_pixbuf_animation_iter_get_pixbuf*(iter: PGdkPixbufAnimationIter): PGdkPixbuf{.
|
||||
cdecl, dynlib: gdkpixbuflib, importc: "gdk_pixbuf_animation_iter_get_pixbuf".}
|
||||
proc gdk_pixbuf_animation_iter_on_currently_loading_frame*(
|
||||
iter: PGdkPixbufAnimationIter): gboolean{.cdecl, dynlib: gdkpixbuflib,
|
||||
importc: "gdk_pixbuf_animation_iter_on_currently_loading_frame".}
|
||||
proc gdk_pixbuf_animation_iter_advance*(iter: PGdkPixbufAnimationIter,
|
||||
e: var TGTimeVal): gboolean{.cdecl,
|
||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_animation_iter_advance".}
|
||||
proc gdk_pixbuf_get_option*(pixbuf: PGdkPixbuf, key: cstring): cstring{.cdecl,
|
||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_get_option".}
|
||||
type
|
||||
PGdkPixbufLoader* = ptr TGdkPixbufLoader
|
||||
TGdkPixbufLoader* = record
|
||||
parent_instance*: TGObject
|
||||
priv*: gpointer
|
||||
|
||||
PGdkPixbufLoaderClass* = ptr TGdkPixbufLoaderClass
|
||||
TGdkPixbufLoaderClass* = record
|
||||
parent_class*: TGObjectClass
|
||||
area_prepared*: proc (loader: PGdkPixbufLoader){.cdecl.}
|
||||
area_updated*: proc (loader: PGdkPixbufLoader, x: int32, y: int32,
|
||||
width: int32, height: int32){.cdecl.}
|
||||
closed*: proc (loader: PGdkPixbufLoader){.cdecl.}
|
||||
|
||||
|
||||
proc GDK_TYPE_PIXBUF_LOADER*(): GType
|
||||
proc GDK_PIXBUF_LOADER*(obj: pointer): PGdkPixbufLoader
|
||||
proc GDK_PIXBUF_LOADER_CLASS*(klass: pointer): PGdkPixbufLoaderClass
|
||||
proc GDK_IS_PIXBUF_LOADER*(obj: pointer): bool
|
||||
proc GDK_IS_PIXBUF_LOADER_CLASS*(klass: pointer): bool
|
||||
proc GDK_PIXBUF_LOADER_GET_CLASS*(obj: pointer): PGdkPixbufLoaderClass
|
||||
proc gdk_pixbuf_loader_get_type*(): GType{.cdecl, dynlib: gdkpixbuflib,
|
||||
importc: "gdk_pixbuf_loader_get_type".}
|
||||
proc gdk_pixbuf_loader_new*(): PGdkPixbufLoader{.cdecl, dynlib: gdkpixbuflib,
|
||||
importc: "gdk_pixbuf_loader_new".}
|
||||
proc gdk_pixbuf_loader_new_with_type*(image_type: cstring, error: pointer): PGdkPixbufLoader{.
|
||||
cdecl, dynlib: gdkpixbuflib, importc: "gdk_pixbuf_loader_new_with_type".}
|
||||
proc gdk_pixbuf_loader_write*(loader: PGdkPixbufLoader, buf: Pguchar,
|
||||
count: gsize, error: pointer): gboolean{.cdecl,
|
||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_loader_write".}
|
||||
proc gdk_pixbuf_loader_get_pixbuf*(loader: PGdkPixbufLoader): PGdkPixbuf{.cdecl,
|
||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_loader_get_pixbuf".}
|
||||
proc gdk_pixbuf_loader_get_animation*(loader: PGdkPixbufLoader): PGdkPixbufAnimation{.
|
||||
cdecl, dynlib: gdkpixbuflib, importc: "gdk_pixbuf_loader_get_animation".}
|
||||
proc gdk_pixbuf_loader_close*(loader: PGdkPixbufLoader, error: pointer): gboolean{.
|
||||
cdecl, dynlib: gdkpixbuflib, importc: "gdk_pixbuf_loader_close".}
|
||||
proc GDK_TYPE_PIXBUF_LOADER*(): GType =
|
||||
result = gdk_pixbuf_loader_get_type()
|
||||
|
||||
proc GDK_PIXBUF_LOADER*(obj: pointer): PGdkPixbufLoader =
|
||||
result = cast[PGdkPixbufLoader](G_TYPE_CHECK_INSTANCE_CAST(obj,
|
||||
GDK_TYPE_PIXBUF_LOADER()))
|
||||
|
||||
proc GDK_PIXBUF_LOADER_CLASS*(klass: pointer): PGdkPixbufLoaderClass =
|
||||
result = cast[PGdkPixbufLoaderClass](G_TYPE_CHECK_CLASS_CAST(klass,
|
||||
GDK_TYPE_PIXBUF_LOADER()))
|
||||
|
||||
proc GDK_IS_PIXBUF_LOADER*(obj: pointer): bool =
|
||||
result = G_TYPE_CHECK_INSTANCE_TYPE(obj, GDK_TYPE_PIXBUF_LOADER())
|
||||
|
||||
proc GDK_IS_PIXBUF_LOADER_CLASS*(klass: pointer): bool =
|
||||
result = G_TYPE_CHECK_CLASS_TYPE(klass, GDK_TYPE_PIXBUF_LOADER())
|
||||
|
||||
proc GDK_PIXBUF_LOADER_GET_CLASS*(obj: pointer): PGdkPixbufLoaderClass =
|
||||
result = cast[PGdkPixbufLoaderClass](G_TYPE_INSTANCE_GET_CLASS(obj,
|
||||
GDK_TYPE_PIXBUF_LOADER()))
|
||||
|
||||
proc GDK_TYPE_PIXBUF*(): GType =
|
||||
result = gdk_pixbuf_get_type()
|
||||
|
||||
proc GDK_PIXBUF*(anObject: pointer): PGdkPixbuf =
|
||||
result = cast[PGdkPixbuf](G_TYPE_CHECK_INSTANCE_CAST(anObject, GDK_TYPE_PIXBUF()))
|
||||
|
||||
proc GDK_IS_PIXBUF*(anObject: pointer): bool =
|
||||
result = G_TYPE_CHECK_INSTANCE_TYPE(anObject, GDK_TYPE_PIXBUF())
|
||||
|
||||
proc GDK_TYPE_PIXBUF_ANIMATION*(): GType =
|
||||
result = gdk_pixbuf_animation_get_type()
|
||||
|
||||
proc GDK_PIXBUF_ANIMATION*(anObject: pointer): PGdkPixbufAnimation =
|
||||
result = cast[PGdkPixbufAnimation](G_TYPE_CHECK_INSTANCE_CAST(anObject,
|
||||
GDK_TYPE_PIXBUF_ANIMATION()))
|
||||
|
||||
proc GDK_IS_PIXBUF_ANIMATION*(anObject: pointer): bool =
|
||||
result = G_TYPE_CHECK_INSTANCE_TYPE(anObject, GDK_TYPE_PIXBUF_ANIMATION())
|
||||
|
||||
proc GDK_TYPE_PIXBUF_ANIMATION_ITER*(): GType =
|
||||
result = gdk_pixbuf_animation_iter_get_type()
|
||||
|
||||
proc GDK_PIXBUF_ANIMATION_ITER*(anObject: pointer): PGdkPixbufAnimationIter =
|
||||
result = cast[PGdkPixbufAnimationIter](G_TYPE_CHECK_INSTANCE_CAST(anObject,
|
||||
GDK_TYPE_PIXBUF_ANIMATION_ITER()))
|
||||
|
||||
proc GDK_IS_PIXBUF_ANIMATION_ITER*(anObject: pointer): bool =
|
||||
result = G_TYPE_CHECK_INSTANCE_TYPE(anObject, GDK_TYPE_PIXBUF_ANIMATION_ITER())
|
||||
|
||||
proc GDK_PIXBUF_ERROR*(): TGQuark =
|
||||
result = gdk_pixbuf_error_quark()
|
||||
562
lib/base/gtk/gdkglext.nim
Executable file
562
lib/base/gtk/gdkglext.nim
Executable file
|
|
@ -0,0 +1,562 @@
|
|||
import
|
||||
Glib2, Gdk2
|
||||
|
||||
when defined(WIN32):
|
||||
const
|
||||
GdkGLExtLib = "libgdkglext-win32-1.0-0.dll"
|
||||
else:
|
||||
const
|
||||
GdkGLExtLib = "libgdkglext-x11-1.0.so"
|
||||
type
|
||||
TGdkGLConfigAttrib* = int32
|
||||
TGdkGLConfigCaveat* = int32
|
||||
TGdkGLVisualType* = int32
|
||||
TGdkGLTransparentType* = int32
|
||||
TGdkGLDrawableTypeMask* = int32
|
||||
TGdkGLRenderTypeMask* = int32
|
||||
TGdkGLBufferMask* = int32
|
||||
TGdkGLConfigError* = int32
|
||||
TGdkGLRenderType* = int32
|
||||
TGdkGLDrawableAttrib* = int32
|
||||
TGdkGLPbufferAttrib* = int32
|
||||
TGdkGLEventMask* = int32
|
||||
TGdkGLEventType* = int32
|
||||
TGdkGLDrawableType* = int32
|
||||
TGdkGLProc* = Pointer
|
||||
PGdkGLConfig* = ptr TGdkGLConfig
|
||||
PGdkGLContext* = ptr TGdkGLContext
|
||||
PGdkGLDrawable* = ptr TGdkGLDrawable
|
||||
PGdkGLPixmap* = ptr TGdkGLPixmap
|
||||
PGdkGLWindow* = ptr TGdkGLWindow
|
||||
TGdkGLConfig* = object of TGObject
|
||||
layer_plane*: gint
|
||||
n_aux_buffers*: gint
|
||||
n_sample_buffers*: gint
|
||||
flag0*: int16
|
||||
|
||||
PGdkGLConfigClass* = ptr TGdkGLConfigClass
|
||||
TGdkGLConfigClass* = object of TGObjectClass
|
||||
|
||||
TGdkGLContext* = object of TGObject
|
||||
|
||||
PGdkGLContextClass* = ptr TGdkGLContextClass
|
||||
TGdkGLContextClass* = object of TGObjectClass
|
||||
|
||||
TGdkGLDrawable* = object of TGObject
|
||||
|
||||
PGdkGLDrawableClass* = ptr TGdkGLDrawableClass
|
||||
TGdkGLDrawableClass* = object of TGTypeInterface
|
||||
create_new_context*: proc (gldrawable: PGdkGLDrawable,
|
||||
share_list: PGdkGLContext, direct: gboolean,
|
||||
render_type: int32): PGdkGLContext{.cdecl.}
|
||||
make_context_current*: proc (draw: PGdkGLDrawable, a_read: PGdkGLDrawable,
|
||||
glcontext: PGdkGLContext): gboolean{.cdecl.}
|
||||
is_double_buffered*: proc (gldrawable: PGdkGLDrawable): gboolean{.cdecl.}
|
||||
swap_buffers*: proc (gldrawable: PGdkGLDrawable){.cdecl.}
|
||||
wait_gl*: proc (gldrawable: PGdkGLDrawable){.cdecl.}
|
||||
wait_gdk*: proc (gldrawable: PGdkGLDrawable){.cdecl.}
|
||||
gl_begin*: proc (draw: PGdkGLDrawable, a_read: PGdkGLDrawable,
|
||||
glcontext: PGdkGLContext): gboolean{.cdecl.}
|
||||
gl_end*: proc (gldrawable: PGdkGLDrawable){.cdecl.}
|
||||
get_gl_config*: proc (gldrawable: PGdkGLDrawable): PGdkGLConfig{.cdecl.}
|
||||
get_size*: proc (gldrawable: PGdkGLDrawable, width, height: PGInt){.cdecl.}
|
||||
|
||||
TGdkGLPixmap* = object of TGObject
|
||||
drawable*: PGdkDrawable
|
||||
|
||||
PGdkGLPixmapClass* = ptr TGdkGLPixmapClass
|
||||
TGdkGLPixmapClass* = object of TGObjectClass
|
||||
|
||||
TGdkGLWindow* = object of TGObject
|
||||
drawable*: PGdkDrawable
|
||||
|
||||
PGdkGLWindowClass* = ptr TGdkGLWindowClass
|
||||
TGdkGLWindowClass* = object of TGObjectClass
|
||||
|
||||
|
||||
const
|
||||
HEADER_GDKGLEXT_MAJOR_VERSION* = 1
|
||||
HEADER_GDKGLEXT_MINOR_VERSION* = 0
|
||||
HEADER_GDKGLEXT_MICRO_VERSION* = 6
|
||||
HEADER_GDKGLEXT_INTERFACE_AGE* = 4
|
||||
HEADER_GDKGLEXT_BINARY_AGE* = 6
|
||||
|
||||
proc HEADER_GDKGLEXT_CHECK_VERSION*(major, minor, micro: guint): bool
|
||||
var
|
||||
gdkglext_major_version*{.importc, dynlib: GdkGLExtLib.}: guint
|
||||
gdkglext_minor_version*{.importc, dynlib: GdkGLExtLib.}: guint
|
||||
gdkglext_micro_version*{.importc, dynlib: GdkGLExtLib.}: guint
|
||||
gdkglext_interface_age*{.importc, dynlib: GdkGLExtLib.}: guint
|
||||
gdkglext_binary_age*{.importc, dynlib: GdkGLExtLib.}: guint
|
||||
|
||||
const
|
||||
GDK_GL_SUCCESS* = 0
|
||||
GDK_GL_ATTRIB_LIST_NONE* = 0
|
||||
GDK_GL_USE_GL* = 1
|
||||
GDK_GL_BUFFER_SIZE* = 2
|
||||
GDK_GL_LEVEL* = 3
|
||||
GDK_GL_RGBA* = 4
|
||||
GDK_GL_DOUBLEBUFFER* = 5
|
||||
GDK_GL_STEREO* = 6
|
||||
GDK_GL_AUX_BUFFERS* = 7
|
||||
GDK_GL_RED_SIZE* = 8
|
||||
GDK_GL_GREEN_SIZE* = 9
|
||||
GDK_GL_BLUE_SIZE* = 10
|
||||
GDK_GL_ALPHA_SIZE* = 11
|
||||
GDK_GL_DEPTH_SIZE* = 12
|
||||
GDK_GL_STENCIL_SIZE* = 13
|
||||
GDK_GL_ACCUM_RED_SIZE* = 14
|
||||
GDK_GL_ACCUM_GREEN_SIZE* = 15
|
||||
GDK_GL_ACCUM_BLUE_SIZE* = 16
|
||||
GDK_GL_ACCUM_ALPHA_SIZE* = 17
|
||||
GDK_GL_CONFIG_CAVEAT* = 0x00000020
|
||||
GDK_GL_X_VISUAL_TYPE* = 0x00000022
|
||||
GDK_GL_TRANSPARENT_TYPE* = 0x00000023
|
||||
GDK_GL_TRANSPARENT_INDEX_VALUE* = 0x00000024
|
||||
GDK_GL_TRANSPARENT_RED_VALUE* = 0x00000025
|
||||
GDK_GL_TRANSPARENT_GREEN_VALUE* = 0x00000026
|
||||
GDK_GL_TRANSPARENT_BLUE_VALUE* = 0x00000027
|
||||
GDK_GL_TRANSPARENT_ALPHA_VALUE* = 0x00000028
|
||||
GDK_GL_DRAWABLE_TYPE* = 0x00008010
|
||||
GDK_GL_RENDER_TYPE* = 0x00008011
|
||||
GDK_GL_X_RENDERABLE* = 0x00008012
|
||||
GDK_GL_FBCONFIG_ID* = 0x00008013
|
||||
GDK_GL_MAX_PBUFFER_WIDTH* = 0x00008016
|
||||
GDK_GL_MAX_PBUFFER_HEIGHT* = 0x00008017
|
||||
GDK_GL_MAX_PBUFFER_PIXELS* = 0x00008018
|
||||
GDK_GL_VISUAL_ID* = 0x0000800B
|
||||
GDK_GL_SCREEN* = 0x0000800C
|
||||
GDK_GL_SAMPLE_BUFFERS* = 100000
|
||||
GDK_GL_SAMPLES* = 100001
|
||||
GDK_GL_DONT_CARE* = 0xFFFFFFFF
|
||||
GDK_GL_NONE* = 0x00008000
|
||||
GDK_GL_CONFIG_CAVEAT_DONT_CARE* = 0xFFFFFFFF
|
||||
GDK_GL_CONFIG_CAVEAT_NONE* = 0x00008000
|
||||
GDK_GL_SLOW_CONFIG* = 0x00008001
|
||||
GDK_GL_NON_CONFORMANT_CONFIG* = 0x0000800D
|
||||
GDK_GL_VISUAL_TYPE_DONT_CARE* = 0xFFFFFFFF
|
||||
GDK_GL_TRUE_COLOR* = 0x00008002
|
||||
GDK_GL_DIRECT_COLOR* = 0x00008003
|
||||
GDK_GL_PSEUDO_COLOR* = 0x00008004
|
||||
GDK_GL_STATIC_COLOR* = 0x00008005
|
||||
GDK_GL_GRAY_SCALE* = 0x00008006
|
||||
GDK_GL_STATIC_GRAY* = 0x00008007
|
||||
GDK_GL_TRANSPARENT_NONE* = 0x00008000
|
||||
GDK_GL_TRANSPARENT_RGB* = 0x00008008
|
||||
GDK_GL_TRANSPARENT_INDEX* = 0x00008009
|
||||
GDK_GL_WINDOW_BIT* = 1 shl 0
|
||||
GDK_GL_PIXMAP_BIT* = 1 shl 1
|
||||
GDK_GL_PBUFFER_BIT* = 1 shl 2
|
||||
GDK_GL_RGBA_BIT* = 1 shl 0
|
||||
GDK_GL_COLOR_INDEX_BIT* = 1 shl 1
|
||||
GDK_GL_FRONT_LEFT_BUFFER_BIT* = 1 shl 0
|
||||
GDK_GL_FRONT_RIGHT_BUFFER_BIT* = 1 shl 1
|
||||
GDK_GL_BACK_LEFT_BUFFER_BIT* = 1 shl 2
|
||||
GDK_GL_BACK_RIGHT_BUFFER_BIT* = 1 shl 3
|
||||
GDK_GL_AUX_BUFFERS_BIT* = 1 shl 4
|
||||
GDK_GL_DEPTH_BUFFER_BIT* = 1 shl 5
|
||||
GDK_GL_STENCIL_BUFFER_BIT* = 1 shl 6
|
||||
GDK_GL_ACCUM_BUFFER_BIT* = 1 shl 7
|
||||
GDK_GL_BAD_SCREEN* = 1
|
||||
GDK_GL_BAD_ATTRIBUTE* = 2
|
||||
GDK_GL_NO_EXTENSION* = 3
|
||||
GDK_GL_BAD_VISUAL* = 4
|
||||
GDK_GL_BAD_CONTEXT* = 5
|
||||
GDK_GL_BAD_VALUE* = 6
|
||||
GDK_GL_BAD_ENUM* = 7
|
||||
GDK_GL_RGBA_TYPE* = 0x00008014
|
||||
GDK_GL_COLOR_INDEX_TYPE* = 0x00008015
|
||||
GDK_GL_PRESERVED_CONTENTS* = 0x0000801B
|
||||
GDK_GL_LARGEST_PBUFFER* = 0x0000801C
|
||||
GDK_GL_WIDTH* = 0x0000801D
|
||||
GDK_GL_HEIGHT* = 0x0000801E
|
||||
GDK_GL_EVENT_MASK* = 0x0000801F
|
||||
GDK_GL_PBUFFER_PRESERVED_CONTENTS* = 0x0000801B
|
||||
GDK_GL_PBUFFER_LARGEST_PBUFFER* = 0x0000801C
|
||||
GDK_GL_PBUFFER_HEIGHT* = 0x00008040
|
||||
GDK_GL_PBUFFER_WIDTH* = 0x00008041
|
||||
GDK_GL_PBUFFER_CLOBBER_MASK* = 1 shl 27
|
||||
GDK_GL_DAMAGED* = 0x00008020
|
||||
GDK_GL_SAVED* = 0x00008021
|
||||
GDK_GL_WINDOW_VALUE* = 0x00008022
|
||||
GDK_GL_PBUFFER* = 0x00008023
|
||||
|
||||
proc gdk_gl_config_attrib_get_type*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_config_attrib_get_type".}
|
||||
proc GDK_TYPE_GL_CONFIG_ATTRIB*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_config_attrib_get_type".}
|
||||
proc gdk_gl_config_caveat_get_type*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_config_caveat_get_type".}
|
||||
proc GDK_TYPE_GL_CONFIG_CAVEAT*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_config_caveat_get_type".}
|
||||
proc gdk_gl_visual_type_get_type*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_visual_type_get_type".}
|
||||
proc GDK_TYPE_GL_VISUAL_TYPE*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_visual_type_get_type".}
|
||||
proc gdk_gl_transparent_type_get_type*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_transparent_type_get_type".}
|
||||
proc GDK_TYPE_GL_TRANSPARENT_TYPE*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_transparent_type_get_type".}
|
||||
proc gdk_gl_drawable_type_mask_get_type*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_drawable_type_mask_get_type".}
|
||||
proc GDK_TYPE_GL_DRAWABLE_TYPE_MASK*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_drawable_type_mask_get_type".}
|
||||
proc gdk_gl_render_type_mask_get_type*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_render_type_mask_get_type".}
|
||||
proc GDK_TYPE_GL_RENDER_TYPE_MASK*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_render_type_mask_get_type".}
|
||||
proc gdk_gl_buffer_mask_get_type*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_buffer_mask_get_type".}
|
||||
proc GDK_TYPE_GL_BUFFER_MASK*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_buffer_mask_get_type".}
|
||||
proc gdk_gl_config_error_get_type*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_config_error_get_type".}
|
||||
proc GDK_TYPE_GL_CONFIG_ERROR*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_config_error_get_type".}
|
||||
proc gdk_gl_render_type_get_type*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_render_type_get_type".}
|
||||
proc GDK_TYPE_GL_RENDER_TYPE*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_render_type_get_type".}
|
||||
proc gdk_gl_drawable_attrib_get_type*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_drawable_attrib_get_type".}
|
||||
proc GDK_TYPE_GL_DRAWABLE_ATTRIB*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_drawable_attrib_get_type".}
|
||||
proc gdk_gl_pbuffer_attrib_get_type*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_pbuffer_attrib_get_type".}
|
||||
proc GDK_TYPE_GL_PBUFFER_ATTRIB*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_pbuffer_attrib_get_type".}
|
||||
proc gdk_gl_event_mask_get_type*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_event_mask_get_type".}
|
||||
proc GDK_TYPE_GL_EVENT_MASK*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_event_mask_get_type".}
|
||||
proc gdk_gl_event_type_get_type*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_event_type_get_type".}
|
||||
proc GDK_TYPE_GL_EVENT_TYPE*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_event_type_get_type".}
|
||||
proc gdk_gl_drawable_type_get_type*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_drawable_type_get_type".}
|
||||
proc GDK_TYPE_GL_DRAWABLE_TYPE*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_drawable_type_get_type".}
|
||||
proc gdk_gl_config_mode_get_type*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_config_mode_get_type".}
|
||||
proc GDK_TYPE_GL_CONFIG_MODE*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_config_mode_get_type".}
|
||||
proc gdk_gl_parse_args*(argc: var int32, argv: ptr cstringArray): gboolean{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_parse_args".}
|
||||
proc gdk_gl_init_check*(argc: var int32, argv: ptr cstringArray): gboolean{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_init_check".}
|
||||
proc gdk_gl_init*(argc: var int32, argv: ptr cstringArray){.
|
||||
cdecl, dynlib: GdkGLExtLib, importc: "gdk_gl_init".}
|
||||
proc gdk_gl_query_gl_extension*(extension: cstring): gboolean{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_query_gl_extension".}
|
||||
proc gdk_gl_get_proc_address*(proc_name: cstring): TGdkGLProc{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_get_proc_address".}
|
||||
const
|
||||
bm_TGdkGLConfig_is_rgba* = 1 shl 0
|
||||
bp_TGdkGLConfig_is_rgba* = 0
|
||||
bm_TGdkGLConfig_is_double_buffered* = 1 shl 1
|
||||
bp_TGdkGLConfig_is_double_buffered* = 1
|
||||
bm_TGdkGLConfig_as_single_mode* = 1 shl 2
|
||||
bp_TGdkGLConfig_as_single_mode* = 2
|
||||
bm_TGdkGLConfig_is_stereo* = 1 shl 3
|
||||
bp_TGdkGLConfig_is_stereo* = 3
|
||||
bm_TGdkGLConfig_has_alpha* = 1 shl 4
|
||||
bp_TGdkGLConfig_has_alpha* = 4
|
||||
bm_TGdkGLConfig_has_depth_buffer* = 1 shl 5
|
||||
bp_TGdkGLConfig_has_depth_buffer* = 5
|
||||
bm_TGdkGLConfig_has_stencil_buffer* = 1 shl 6
|
||||
bp_TGdkGLConfig_has_stencil_buffer* = 6
|
||||
bm_TGdkGLConfig_has_accum_buffer* = 1 shl 7
|
||||
bp_TGdkGLConfig_has_accum_buffer* = 7
|
||||
|
||||
const
|
||||
GDK_GL_MODE_RGB* = 0
|
||||
GDK_GL_MODE_RGBA* = 0
|
||||
GDK_GL_MODE_INDEX* = 1 shl 0
|
||||
GDK_GL_MODE_SINGLE* = 0
|
||||
GDK_GL_MODE_DOUBLE* = 1 shl 1
|
||||
GDK_GL_MODE_STEREO* = 1 shl 2
|
||||
GDK_GL_MODE_ALPHA* = 1 shl 3
|
||||
GDK_GL_MODE_DEPTH* = 1 shl 4
|
||||
GDK_GL_MODE_STENCIL* = 1 shl 5
|
||||
GDK_GL_MODE_ACCUM* = 1 shl 6
|
||||
GDK_GL_MODE_MULTISAMPLE* = 1 shl 7
|
||||
|
||||
type
|
||||
TGdkGLConfigMode* = int32
|
||||
PGdkGLConfigMode* = ptr TGdkGLConfigMode
|
||||
|
||||
proc GDK_TYPE_GL_CONFIG*(): GType
|
||||
proc GDK_GL_CONFIG*(anObject: Pointer): PGdkGLConfig
|
||||
proc GDK_GL_CONFIG_CLASS*(klass: Pointer): PGdkGLConfigClass
|
||||
proc GDK_IS_GL_CONFIG*(anObject: Pointer): bool
|
||||
proc GDK_IS_GL_CONFIG_CLASS*(klass: Pointer): bool
|
||||
proc GDK_GL_CONFIG_GET_CLASS*(obj: Pointer): PGdkGLConfigClass
|
||||
proc gdk_gl_config_get_type*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_config_get_type".}
|
||||
proc gdk_gl_config_get_screen*(glconfig: PGdkGLConfig): PGdkScreen{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_config_get_screen".}
|
||||
proc gdk_gl_config_get_attrib*(glconfig: PGdkGLConfig, attribute: int,
|
||||
value: var cint): gboolean{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_config_get_attrib".}
|
||||
proc gdk_gl_config_get_colormap*(glconfig: PGdkGLConfig): PGdkColormap{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_config_get_colormap".}
|
||||
proc gdk_gl_config_get_visual*(glconfig: PGdkGLConfig): PGdkVisual{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_config_get_visual".}
|
||||
proc gdk_gl_config_get_depth*(glconfig: PGdkGLConfig): gint{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_config_get_depth".}
|
||||
proc gdk_gl_config_get_layer_plane*(glconfig: PGdkGLConfig): gint{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_config_get_layer_plane".}
|
||||
proc gdk_gl_config_get_n_aux_buffers*(glconfig: PGdkGLConfig): gint{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_config_get_n_aux_buffers".}
|
||||
proc gdk_gl_config_get_n_sample_buffers*(glconfig: PGdkGLConfig): gint{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_config_get_n_sample_buffers".}
|
||||
proc gdk_gl_config_is_rgba*(glconfig: PGdkGLConfig): gboolean{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_config_is_rgba".}
|
||||
proc gdk_gl_config_is_double_buffered*(glconfig: PGdkGLConfig): gboolean{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_config_is_double_buffered".}
|
||||
proc gdk_gl_config_is_stereo*(glconfig: PGdkGLConfig): gboolean{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_config_is_stereo".}
|
||||
proc gdk_gl_config_has_alpha*(glconfig: PGdkGLConfig): gboolean{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_config_has_alpha".}
|
||||
proc gdk_gl_config_has_depth_buffer*(glconfig: PGdkGLConfig): gboolean{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_config_has_depth_buffer".}
|
||||
proc gdk_gl_config_has_stencil_buffer*(glconfig: PGdkGLConfig): gboolean{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_config_has_stencil_buffer".}
|
||||
proc gdk_gl_config_has_accum_buffer*(glconfig: PGdkGLConfig): gboolean{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_config_has_accum_buffer".}
|
||||
proc GDK_TYPE_GL_CONTEXT*(): GType
|
||||
proc GDK_GL_CONTEXT*(anObject: Pointer): PGdkGLContext
|
||||
proc GDK_GL_CONTEXT_CLASS*(klass: Pointer): PGdkGLContextClass
|
||||
proc GDK_IS_GL_CONTEXT*(anObject: Pointer): bool
|
||||
proc GDK_IS_GL_CONTEXT_CLASS*(klass: Pointer): bool
|
||||
proc GDK_GL_CONTEXT_GET_CLASS*(obj: Pointer): PGdkGLContextClass
|
||||
proc gdk_gl_context_get_type*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_context_get_type".}
|
||||
proc gdk_gl_context_new*(gldrawable: PGdkGLDrawable, share_list: PGdkGLContext,
|
||||
direct: gboolean, render_type: int32): PGdkGLContext{.
|
||||
cdecl, dynlib: GdkGLExtLib, importc: "gdk_gl_context_new".}
|
||||
proc gdk_gl_context_destroy*(glcontext: PGdkGLContext){.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_context_destroy".}
|
||||
proc gdk_gl_context_copy*(glcontext: PGdkGLContext, src: PGdkGLContext,
|
||||
mask: int32): gboolean{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_context_copy".}
|
||||
proc gdk_gl_context_get_gl_drawable*(glcontext: PGdkGLContext): PGdkGLDrawable{.
|
||||
cdecl, dynlib: GdkGLExtLib, importc: "gdk_gl_context_get_gl_drawable".}
|
||||
proc gdk_gl_context_get_gl_config*(glcontext: PGdkGLContext): PGdkGLConfig{.
|
||||
cdecl, dynlib: GdkGLExtLib, importc: "gdk_gl_context_get_gl_config".}
|
||||
proc gdk_gl_context_get_share_list*(glcontext: PGdkGLContext): PGdkGLContext{.
|
||||
cdecl, dynlib: GdkGLExtLib, importc: "gdk_gl_context_get_share_list".}
|
||||
proc gdk_gl_context_is_direct*(glcontext: PGdkGLContext): gboolean{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_context_is_direct".}
|
||||
proc gdk_gl_context_get_render_type*(glcontext: PGdkGLContext): int32{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_context_get_render_type".}
|
||||
proc gdk_gl_context_get_current*(): PGdkGLContext{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_context_get_current".}
|
||||
proc GDK_TYPE_GL_DRAWABLE*(): GType
|
||||
proc GDK_GL_DRAWABLE*(inst: Pointer): PGdkGLDrawable
|
||||
proc GDK_GL_DRAWABLE_CLASS*(vtable: Pointer): PGdkGLDrawableClass
|
||||
proc GDK_IS_GL_DRAWABLE*(inst: Pointer): bool
|
||||
proc GDK_IS_GL_DRAWABLE_CLASS*(vtable: Pointer): bool
|
||||
proc GDK_GL_DRAWABLE_GET_CLASS*(inst: Pointer): PGdkGLDrawableClass
|
||||
proc gdk_gl_drawable_get_type*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_drawable_get_type".}
|
||||
proc gdk_gl_drawable_make_current*(gldrawable: PGdkGLDrawable,
|
||||
glcontext: PGdkGLContext): gboolean{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_drawable_make_current".}
|
||||
proc gdk_gl_drawable_is_double_buffered*(gldrawable: PGdkGLDrawable): gboolean{.
|
||||
cdecl, dynlib: GdkGLExtLib, importc: "gdk_gl_drawable_is_double_buffered".}
|
||||
proc gdk_gl_drawable_swap_buffers*(gldrawable: PGdkGLDrawable){.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_drawable_swap_buffers".}
|
||||
proc gdk_gl_drawable_wait_gl*(gldrawable: PGdkGLDrawable){.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_drawable_wait_gl".}
|
||||
proc gdk_gl_drawable_wait_gdk*(gldrawable: PGdkGLDrawable){.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_drawable_wait_gdk".}
|
||||
proc gdk_gl_drawable_gl_begin*(gldrawable: PGdkGLDrawable,
|
||||
glcontext: PGdkGLContext): gboolean{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_drawable_gl_begin".}
|
||||
proc gdk_gl_drawable_gl_end*(gldrawable: PGdkGLDrawable){.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_drawable_gl_end".}
|
||||
proc gdk_gl_drawable_get_gl_config*(gldrawable: PGdkGLDrawable): PGdkGLConfig{.
|
||||
cdecl, dynlib: GdkGLExtLib, importc: "gdk_gl_drawable_get_gl_config".}
|
||||
proc gdk_gl_drawable_get_size*(gldrawable: PGdkGLDrawable, width, height: PGInt){.
|
||||
cdecl, dynlib: GdkGLExtLib, importc: "gdk_gl_drawable_get_size".}
|
||||
proc gdk_gl_drawable_get_current*(): PGdkGLDrawable{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_drawable_get_current".}
|
||||
proc GDK_TYPE_GL_PIXMAP*(): GType
|
||||
proc GDK_GL_PIXMAP*(anObject: Pointer): PGdkGLPixmap
|
||||
proc GDK_GL_PIXMAP_CLASS*(klass: Pointer): PGdkGLPixmapClass
|
||||
proc GDK_IS_GL_PIXMAP*(anObject: Pointer): bool
|
||||
proc GDK_IS_GL_PIXMAP_CLASS*(klass: Pointer): bool
|
||||
proc GDK_GL_PIXMAP_GET_CLASS*(obj: Pointer): PGdkGLPixmapClass
|
||||
proc gdk_gl_pixmap_get_type*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_pixmap_get_type".}
|
||||
proc gdk_gl_pixmap_new*(glconfig: PGdkGLConfig, pixmap: PGdkPixmap,
|
||||
attrib_list: ptr int32): PGdkGLPixmap{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_pixmap_new".}
|
||||
proc gdk_gl_pixmap_destroy*(glpixmap: PGdkGLPixmap){.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_pixmap_destroy".}
|
||||
proc gdk_gl_pixmap_get_pixmap*(glpixmap: PGdkGLPixmap): PGdkPixmap{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_pixmap_get_pixmap".}
|
||||
proc gdk_pixmap_set_gl_capability*(pixmap: PGdkPixmap, glconfig: PGdkGLConfig,
|
||||
attrib_list: ptr int32): PGdkGLPixmap{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_pixmap_set_gl_capability".}
|
||||
proc gdk_pixmap_unset_gl_capability*(pixmap: PGdkPixmap){.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_pixmap_unset_gl_capability".}
|
||||
proc gdk_pixmap_is_gl_capable*(pixmap: PGdkPixmap): gboolean{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_pixmap_is_gl_capable".}
|
||||
proc gdk_pixmap_get_gl_pixmap*(pixmap: PGdkPixmap): PGdkGLPixmap{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_pixmap_get_gl_pixmap".}
|
||||
proc gdk_pixmap_get_gl_drawable*(pixmap: PGdkPixmap): PGdkGLDrawable
|
||||
proc GDK_TYPE_GL_WINDOW*(): GType
|
||||
proc GDK_GL_WINDOW*(anObject: Pointer): PGdkGLWindow
|
||||
proc GDK_GL_WINDOW_CLASS*(klass: Pointer): PGdkGLWindowClass
|
||||
proc GDK_IS_GL_WINDOW*(anObject: Pointer): bool
|
||||
proc GDK_IS_GL_WINDOW_CLASS*(klass: Pointer): bool
|
||||
proc GDK_GL_WINDOW_GET_CLASS*(obj: Pointer): PGdkGLWindowClass
|
||||
proc gdk_gl_window_get_type*(): GType{.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_window_get_type".}
|
||||
proc gdk_gl_window_new*(glconfig: PGdkGLConfig, window: PGdkWindow,
|
||||
attrib_list: ptr int32): PGdkGLWindow{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_window_new".}
|
||||
proc gdk_gl_window_destroy*(glwindow: PGdkGLWindow){.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_window_destroy".}
|
||||
proc gdk_gl_window_get_window*(glwindow: PGdkGLWindow): PGdkWindow{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_window_get_window".}
|
||||
proc gdk_window_set_gl_capability*(window: PGdkWindow, glconfig: PGdkGLConfig,
|
||||
attrib_list: ptr int32): PGdkGLWindow{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_window_set_gl_capability".}
|
||||
proc gdk_window_unset_gl_capability*(window: PGdkWindow){.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_window_unset_gl_capability".}
|
||||
proc gdk_window_is_gl_capable*(window: PGdkWindow): gboolean{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_window_is_gl_capable".}
|
||||
proc gdk_window_get_gl_window*(window: PGdkWindow): PGdkGLWindow{.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_window_get_gl_window".}
|
||||
proc gdk_window_get_gl_drawable*(window: PGdkWindow): PGdkGLDrawable
|
||||
proc gdk_gl_draw_cube*(solid: gboolean, size: float64){.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_draw_cube".}
|
||||
proc gdk_gl_draw_sphere*(solid: gboolean, radius: float64, slices: int32,
|
||||
stacks: int32){.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_draw_sphere".}
|
||||
proc gdk_gl_draw_cone*(solid: gboolean, base: float64, height: float64,
|
||||
slices: int32, stacks: int32){.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_draw_cone".}
|
||||
proc gdk_gl_draw_torus*(solid: gboolean, inner_radius: float64,
|
||||
outer_radius: float64, nsides: int32, rings: int32){.
|
||||
cdecl, dynlib: GdkGLExtLib, importc: "gdk_gl_draw_torus".}
|
||||
proc gdk_gl_draw_tetrahedron*(solid: gboolean){.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_draw_tetrahedron".}
|
||||
proc gdk_gl_draw_octahedron*(solid: gboolean){.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_draw_octahedron".}
|
||||
proc gdk_gl_draw_dodecahedron*(solid: gboolean){.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_draw_dodecahedron".}
|
||||
proc gdk_gl_draw_icosahedron*(solid: gboolean){.cdecl, dynlib: GdkGLExtLib,
|
||||
importc: "gdk_gl_draw_icosahedron".}
|
||||
proc gdk_gl_draw_teapot*(solid: gboolean, scale: float64){.cdecl,
|
||||
dynlib: GdkGLExtLib, importc: "gdk_gl_draw_teapot".}
|
||||
proc HEADER_GDKGLEXT_CHECK_VERSION*(major, minor, micro: guint): bool =
|
||||
result = (HEADER_GDKGLEXT_MAJOR_VERSION > major) or
|
||||
((HEADER_GDKGLEXT_MAJOR_VERSION == major) and
|
||||
(HEADER_GDKGLEXT_MINOR_VERSION > minor)) or
|
||||
((HEADER_GDKGLEXT_MAJOR_VERSION == major) and
|
||||
(HEADER_GDKGLEXT_MINOR_VERSION == minor) and
|
||||
(HEADER_GDKGLEXT_MICRO_VERSION >= micro))
|
||||
|
||||
proc GDK_TYPE_GL_CONFIG*(): GType =
|
||||
result = gdk_gl_config_get_type()
|
||||
|
||||
proc GDK_GL_CONFIG*(anObject: Pointer): PGdkGLConfig =
|
||||
result = cast[PGdkGLConfig](G_TYPE_CHECK_INSTANCE_CAST(anObject, GDK_TYPE_GL_CONFIG()))
|
||||
|
||||
proc GDK_GL_CONFIG_CLASS*(klass: Pointer): PGdkGLConfigClass =
|
||||
result = cast[PGdkGLConfigClass](G_TYPE_CHECK_CLASS_CAST(klass, GDK_TYPE_GL_CONFIG()))
|
||||
|
||||
proc GDK_IS_GL_CONFIG*(anObject: Pointer): bool =
|
||||
result = G_TYPE_CHECK_INSTANCE_TYPE(anObject, GDK_TYPE_GL_CONFIG())
|
||||
|
||||
proc GDK_IS_GL_CONFIG_CLASS*(klass: Pointer): bool =
|
||||
result = G_TYPE_CHECK_CLASS_TYPE(klass, GDK_TYPE_GL_CONFIG())
|
||||
|
||||
proc GDK_GL_CONFIG_GET_CLASS*(obj: Pointer): PGdkGLConfigClass =
|
||||
result = cast[PGdkGLConfigClass](G_TYPE_INSTANCE_GET_CLASS(obj, GDK_TYPE_GL_CONFIG()))
|
||||
|
||||
proc GDK_TYPE_GL_CONTEXT*(): GType =
|
||||
result = gdk_gl_context_get_type()
|
||||
|
||||
proc GDK_GL_CONTEXT*(anObject: Pointer): PGdkGLContext =
|
||||
result = cast[PGdkGLContext](G_TYPE_CHECK_INSTANCE_CAST(anObject,
|
||||
GDK_TYPE_GL_CONTEXT()))
|
||||
|
||||
proc GDK_GL_CONTEXT_CLASS*(klass: Pointer): PGdkGLContextClass =
|
||||
result = cast[PGdkGLContextClass](G_TYPE_CHECK_CLASS_CAST(klass, GDK_TYPE_GL_CONTEXT()))
|
||||
|
||||
proc GDK_IS_GL_CONTEXT*(anObject: Pointer): bool =
|
||||
result = G_TYPE_CHECK_INSTANCE_TYPE(anObject, GDK_TYPE_GL_CONTEXT())
|
||||
|
||||
proc GDK_IS_GL_CONTEXT_CLASS*(klass: Pointer): bool =
|
||||
result = G_TYPE_CHECK_CLASS_TYPE(klass, GDK_TYPE_GL_CONTEXT())
|
||||
|
||||
proc GDK_GL_CONTEXT_GET_CLASS*(obj: Pointer): PGdkGLContextClass =
|
||||
result = cast[PGdkGLContextClass](G_TYPE_INSTANCE_GET_CLASS(obj, GDK_TYPE_GL_CONTEXT()))
|
||||
|
||||
proc GDK_TYPE_GL_DRAWABLE*(): GType =
|
||||
result = gdk_gl_drawable_get_type()
|
||||
|
||||
proc GDK_GL_DRAWABLE*(inst: Pointer): PGdkGLDrawable =
|
||||
result = cast[PGdkGLDrawable](G_TYPE_CHECK_INSTANCE_CAST(inst, GDK_TYPE_GL_DRAWABLE()))
|
||||
|
||||
proc GDK_GL_DRAWABLE_CLASS*(vtable: Pointer): PGdkGLDrawableClass =
|
||||
result = cast[PGdkGLDrawableClass](G_TYPE_CHECK_CLASS_CAST(vtable,
|
||||
GDK_TYPE_GL_DRAWABLE()))
|
||||
|
||||
proc GDK_IS_GL_DRAWABLE*(inst: Pointer): bool =
|
||||
result = G_TYPE_CHECK_INSTANCE_TYPE(inst, GDK_TYPE_GL_DRAWABLE())
|
||||
|
||||
proc GDK_IS_GL_DRAWABLE_CLASS*(vtable: Pointer): bool =
|
||||
result = G_TYPE_CHECK_CLASS_TYPE(vtable, GDK_TYPE_GL_DRAWABLE())
|
||||
|
||||
proc GDK_GL_DRAWABLE_GET_CLASS*(inst: Pointer): PGdkGLDrawableClass =
|
||||
result = cast[PGdkGLDrawableClass](G_TYPE_INSTANCE_GET_INTERFACE(inst,
|
||||
GDK_TYPE_GL_DRAWABLE()))
|
||||
|
||||
proc GDK_TYPE_GL_PIXMAP*(): GType =
|
||||
result = gdk_gl_pixmap_get_type()
|
||||
|
||||
proc GDK_GL_PIXMAP*(anObject: Pointer): PGdkGLPixmap =
|
||||
result = cast[PGdkGLPixmap](G_TYPE_CHECK_INSTANCE_CAST(anObject, GDK_TYPE_GL_PIXMAP()))
|
||||
|
||||
proc GDK_GL_PIXMAP_CLASS*(klass: Pointer): PGdkGLPixmapClass =
|
||||
result = cast[PGdkGLPixmapClass](G_TYPE_CHECK_CLASS_CAST(klass, GDK_TYPE_GL_PIXMAP()))
|
||||
|
||||
proc GDK_IS_GL_PIXMAP*(anObject: Pointer): bool =
|
||||
result = G_TYPE_CHECK_INSTANCE_TYPE(anObject, GDK_TYPE_GL_PIXMAP())
|
||||
|
||||
proc GDK_IS_GL_PIXMAP_CLASS*(klass: Pointer): bool =
|
||||
result = G_TYPE_CHECK_CLASS_TYPE(klass, GDK_TYPE_GL_PIXMAP())
|
||||
|
||||
proc GDK_GL_PIXMAP_GET_CLASS*(obj: Pointer): PGdkGLPixmapClass =
|
||||
result = cast[PGdkGLPixmapClass](G_TYPE_INSTANCE_GET_CLASS(obj, GDK_TYPE_GL_PIXMAP()))
|
||||
|
||||
proc gdk_pixmap_get_gl_drawable*(pixmap: PGdkPixmap): PGdkGLDrawable =
|
||||
result = GDK_GL_DRAWABLE(gdk_pixmap_get_gl_pixmap(pixmap))
|
||||
|
||||
proc GDK_TYPE_GL_WINDOW*(): GType =
|
||||
result = gdk_gl_window_get_type()
|
||||
|
||||
proc GDK_GL_WINDOW*(anObject: Pointer): PGdkGLWindow =
|
||||
result = cast[PGdkGLWindow](G_TYPE_CHECK_INSTANCE_CAST(anObject, GDK_TYPE_GL_WINDOW()))
|
||||
|
||||
proc GDK_GL_WINDOW_CLASS*(klass: Pointer): PGdkGLWindowClass =
|
||||
result = cast[PGdkGLWindowClass](G_TYPE_CHECK_CLASS_CAST(klass, GDK_TYPE_GL_WINDOW()))
|
||||
|
||||
proc GDK_IS_GL_WINDOW*(anObject: Pointer): bool =
|
||||
result = G_TYPE_CHECK_INSTANCE_TYPE(anObject, GDK_TYPE_GL_WINDOW())
|
||||
|
||||
proc GDK_IS_GL_WINDOW_CLASS*(klass: Pointer): bool =
|
||||
result = G_TYPE_CHECK_CLASS_TYPE(klass, GDK_TYPE_GL_WINDOW())
|
||||
|
||||
proc GDK_GL_WINDOW_GET_CLASS*(obj: Pointer): PGdkGLWindowClass =
|
||||
result = cast[PGdkGLWindowClass](G_TYPE_INSTANCE_GET_CLASS(obj, GDK_TYPE_GL_WINDOW()))
|
||||
|
||||
proc gdk_window_get_gl_drawable*(window: PGdkWindow): PGdkGLDrawable =
|
||||
result = GDK_GL_DRAWABLE(gdk_window_get_gl_window(window))
|
||||
4498
lib/base/gtk/glib2.nim
Executable file
4498
lib/base/gtk/glib2.nim
Executable file
File diff suppressed because it is too large
Load diff
17226
lib/base/gtk/gtk2.nim
Executable file
17226
lib/base/gtk/gtk2.nim
Executable file
File diff suppressed because it is too large
Load diff
48
lib/base/gtk/gtkglext.nim
Executable file
48
lib/base/gtk/gtkglext.nim
Executable file
|
|
@ -0,0 +1,48 @@
|
|||
import
|
||||
Glib2, Gdk2, Gtk2, GdkGLExt
|
||||
|
||||
const
|
||||
GtkGLExtLib* = if defined(WIN32): "libgtkglext-win32-1.0-0.dll" else: "libgtkglext-x11-1.0.so"
|
||||
|
||||
const
|
||||
HEADER_GTKGLEXT_MAJOR_VERSION* = 1
|
||||
HEADER_GTKGLEXT_MINOR_VERSION* = 0
|
||||
HEADER_GTKGLEXT_MICRO_VERSION* = 6
|
||||
HEADER_GTKGLEXT_INTERFACE_AGE* = 4
|
||||
HEADER_GTKGLEXT_BINARY_AGE* = 6
|
||||
|
||||
proc gtk_gl_parse_args*(argc: Plongint, argv: PPPChar): gboolean{.cdecl,
|
||||
dynlib: GtkGLExtLib, importc: "gtk_gl_parse_args".}
|
||||
proc gtk_gl_init_check*(argc: Plongint, argv: PPPChar): gboolean{.cdecl,
|
||||
dynlib: GtkGLExtLib, importc: "gtk_gl_init_check".}
|
||||
proc gtk_gl_init*(argc: Plongint, argv: PPPChar){.cdecl, dynlib: GtkGLExtLib,
|
||||
importc: "gtk_gl_init".}
|
||||
proc gtk_widget_set_gl_capability*(widget: PGtkWidget, glconfig: PGdkGLConfig,
|
||||
share_list: PGdkGLContext, direct: gboolean,
|
||||
render_type: int): gboolean{.cdecl,
|
||||
dynlib: GtkGLExtLib, importc: "gtk_widget_set_gl_capability".}
|
||||
proc gtk_widget_is_gl_capable*(widget: PGtkWidget): gboolean{.cdecl,
|
||||
dynlib: GtkGLExtLib, importc: "gtk_widget_is_gl_capable".}
|
||||
proc gtk_widget_get_gl_config*(widget: PGtkWidget): PGdkGLConfig{.cdecl,
|
||||
dynlib: GtkGLExtLib, importc: "gtk_widget_get_gl_config".}
|
||||
proc gtk_widget_create_gl_context*(widget: PGtkWidget,
|
||||
share_list: PGdkGLContext, direct: gboolean,
|
||||
render_type: int): PGdkGLContext{.cdecl,
|
||||
dynlib: GtkGLExtLib, importc: "gtk_widget_create_gl_context".}
|
||||
proc gtk_widget_get_gl_context*(widget: PGtkWidget): PGdkGLContext{.cdecl,
|
||||
dynlib: GtkGLExtLib, importc: "gtk_widget_get_gl_context".}
|
||||
proc gtk_widget_get_gl_window*(widget: PGtkWidget): PGdkGLWindow{.cdecl,
|
||||
dynlib: GtkGLExtLib, importc: "gtk_widget_get_gl_window".}
|
||||
proc gtk_widget_get_gl_drawable*(widget: PGtkWidget): PGdkGLDrawable =
|
||||
nil
|
||||
|
||||
proc HEADER_GTKGLEXT_CHECK_VERSION*(major, minor, micro: guint): bool =
|
||||
result = (HEADER_GTKGLEXT_MAJOR_VERSION > major) or
|
||||
((HEADER_GTKGLEXT_MAJOR_VERSION == major) and
|
||||
(HEADER_GTKGLEXT_MINOR_VERSION > minor)) or
|
||||
((HEADER_GTKGLEXT_MAJOR_VERSION == major) and
|
||||
(HEADER_GTKGLEXT_MINOR_VERSION == minor) and
|
||||
(HEADER_GTKGLEXT_MICRO_VERSION >= micro))
|
||||
|
||||
proc gtk_widget_get_gl_drawable*(widget: PGtkWidget): PGdkGLDrawable =
|
||||
result = GDK_GL_DRAWABLE(gtk_widget_get_gl_window(widget))
|
||||
497
lib/base/gtk/gtkhtml.nim
Executable file
497
lib/base/gtk/gtkhtml.nim
Executable file
|
|
@ -0,0 +1,497 @@
|
|||
import
|
||||
gtk2, glib2, atk, pango, gdk2pixbuf, gdk2
|
||||
|
||||
when defined(windows):
|
||||
{.define: GTK_WINDOWING_WIN32.}
|
||||
const
|
||||
gtkhtmllib = "libgtkhtml-win32-2.0-0.dll"
|
||||
else:
|
||||
const
|
||||
gtkhtmllib = "libgtkhtml-2.so"
|
||||
const
|
||||
DOM_UNSPECIFIED_EVENT_TYPE_ERR* = 0
|
||||
DOM_INDEX_SIZE_ERR* = 1
|
||||
DOM_DOMSTRING_SIZE_ERR* = 2
|
||||
DOM_HIERARCHY_REQUEST_ERR* = 3
|
||||
DOM_WRONG_DOCUMENT_ERR* = 4
|
||||
DOM_INVALID_CHARACTER_ERR* = 5
|
||||
DOM_NO_DATA_ALLOWED_ERR* = 6
|
||||
DOM_NO_MODIFICATION_ALLOWED_ERR* = 7
|
||||
DOM_NOT_FOUND_ERR* = 8
|
||||
DOM_NOT_SUPPORTED_ERR* = 9
|
||||
DOM_INUSE_ATTRIBUTE_ERR* = 10
|
||||
DOM_INVALID_STATE_ERR* = 11
|
||||
DOM_SYNTAX_ERR* = 12
|
||||
DOM_INVALID_MODIFICATION_ERR* = 13
|
||||
DOM_NAMESPACE_ERR* = 14
|
||||
DOM_INVALID_ACCESS_ERR* = 15
|
||||
DOM_NO_EXCEPTION* = 255
|
||||
DOM_ELEMENT_NODE* = 1
|
||||
DOM_ATTRIBUTE_NODE* = 2
|
||||
DOM_TEXT_NODE* = 3
|
||||
DOM_CDATA_SECTION_NODE* = 4
|
||||
DOM_ENTITY_REFERENCE_NODE* = 5
|
||||
DOM_ENTITY_NODE* = 6
|
||||
DOM_PROCESSING_INSTRUCTION_NODE* = 7
|
||||
DOM_COMMENT_NODE* = 8
|
||||
DOM_DOCUMENT_NODE* = 9
|
||||
DOM_DOCUMENT_TYPE_NODE* = 10
|
||||
DOM_DOCUMENT_FRAGMENT_NODE* = 11
|
||||
DOM_NOTATION_NODE* = 12
|
||||
bm__HtmlFontSpecification_weight* = 0x0000000F
|
||||
bp__HtmlFontSpecification_weight* = 0
|
||||
bm__HtmlFontSpecification_style* = 0x00000030
|
||||
bp__HtmlFontSpecification_style* = 4
|
||||
bm__HtmlFontSpecification_variant* = 0x000000C0
|
||||
bp__HtmlFontSpecification_variant* = 6
|
||||
bm__HtmlFontSpecification_stretch* = 0x00000F00
|
||||
bp__HtmlFontSpecification_stretch* = 8
|
||||
bm__HtmlFontSpecification_decoration* = 0x00007000
|
||||
bp__HtmlFontSpecification_decoration* = 12
|
||||
|
||||
type
|
||||
TDomString* = gchar
|
||||
TDomBoolean* = gboolean
|
||||
TDomException* = gushort
|
||||
TDomTimeStamp* = guint64
|
||||
PDomNode* = ptr TDomNode
|
||||
TDomNode* = object of TGObject
|
||||
xmlnode*: pointer
|
||||
style*: pointer
|
||||
|
||||
PDomNodeClass* = ptr TDomNodeClass
|
||||
TDomNodeClass* = object of TGObjectClass
|
||||
`get_nodeName`*: proc (node: PDomNode): PDomString{.cdecl.}
|
||||
`get_nodeValue`*: proc (node: PDomNode, exc: PDomException): PDomString {.
|
||||
cdecl.}
|
||||
`set_nodeValue`*: proc (node: PDomNode, value: PDomString,
|
||||
exc: PDomException): PDomString{.cdecl.}
|
||||
|
||||
PDomDocument* = ptr TDomDocument
|
||||
TDomDocument* = record
|
||||
parent*: PDomNode
|
||||
iterators*: PGSList
|
||||
|
||||
PDomDocumentClass* = ptr TDomDocumentClass
|
||||
TDomDocumentClass* = record
|
||||
parent_class*: PDomNodeClass
|
||||
|
||||
PHtmlFocusIterator* = ptr THtmlFocusIterator
|
||||
THtmlFocusIterator* = object of TGObject
|
||||
document*: PDomDocument
|
||||
current_node*: PDomNode
|
||||
|
||||
PHtmlFocusIteratorClass* = ptr THtmlFocusIteratorClass
|
||||
THtmlFocusIteratorClass* = object of TGObjectClass
|
||||
|
||||
THtmlParserType* = enum
|
||||
HTML_PARSER_TYPE_HTML, HTML_PARSER_TYPE_XML
|
||||
PHtmlParser* = ptr THtmlParser
|
||||
THtmlParser* = object of TGObject
|
||||
parser_type*: THtmlParserType
|
||||
document*: PHtmlDocument
|
||||
stream*: PHtmlStream
|
||||
xmlctxt*: xmlParserCtxtPtr
|
||||
res*: int32
|
||||
chars*: array[0..9, char]
|
||||
blocking*: gboolean
|
||||
blocking_node*: PDomNode
|
||||
|
||||
PHtmlParserClass* = ptr THtmlParserClass
|
||||
THtmlParserClass* = object of TGtkObjectClass
|
||||
done_parsing*: proc (parser: PHtmlParser){.cdecl.}
|
||||
new_node*: proc (parser: PHtmlParser, node: PDomNode)
|
||||
parsed_document_node*: proc (parser: PHtmlParser, document: PDomDocument)
|
||||
|
||||
PHtmlStream* = ptr THtmlStream
|
||||
THtmlStreamCloseFunc* = proc (stream: PHtmlStream, user_data: gpointer){.cdecl.}
|
||||
THtmlStreamWriteFunc* = proc (stream: PHtmlStream, buffer: Pgchar,
|
||||
size: guint, user_data: gpointer){.cdecl.}
|
||||
THtmlStreamCancelFunc* = proc (stream: PHtmlStream, user_data: gpointer,
|
||||
cancel_data: gpointer){.cdecl.}
|
||||
THtmlStream* = object of TGObject
|
||||
write_func*: THtmlStreamWriteFunc
|
||||
close_func*: THtmlStreamCloseFunc
|
||||
cancel_func*: THtmlStreamCancelFunc
|
||||
user_data*: gpointer
|
||||
cancel_data*: gpointer
|
||||
written*: gint
|
||||
mime_type*: cstring
|
||||
|
||||
PHtmlStreamClass* = ptr THtmlStreamClass
|
||||
THtmlStreamClass* = object of TGObjectClass
|
||||
|
||||
THtmlStreamBufferCloseFunc* = proc (str: Pgchar, len: gint,
|
||||
user_data: gpointer){.cdecl.}
|
||||
PGtkHtmlContext* = ptr TGtkHtmlContext
|
||||
TGtkHtmlContext* = object of TGObject
|
||||
documents*: PGSList
|
||||
standard_font*: PHtmlFontSpecification
|
||||
fixed_font*: PHtmlFontSpecification
|
||||
debug_painting*: gboolean
|
||||
|
||||
PGtkHtmlContextClass* = ptr TGtkHtmlContextClass
|
||||
TGtkHtmlContextClass* = object of TGObjectClass
|
||||
|
||||
THtmlDocumentState* = enum
|
||||
HTML_DOCUMENT_STATE_DONE, HTML_DOCUMENT_STATE_PARSING
|
||||
PHtmlDocument* = ptr THtmlDocument
|
||||
THtmlDocument* = object of TGObject
|
||||
stylesheets*: PGSList
|
||||
current_stream*: PHtmlStream
|
||||
state*: THtmlDocumentState
|
||||
|
||||
PHtmlDocumentClass* = ptr THtmlDocumentClass
|
||||
THtmlDocumentClass* = object of TGObjectClass
|
||||
request_url*: proc (document: PHtmlDocument, url: Pgchar,
|
||||
stream: PHtmlStream){.cdecl.}
|
||||
link_clicked*: proc (document: PHtmlDocument, url: Pgchar){.cdecl.}
|
||||
set_base*: proc (document: PHtmlDocument, url: Pgchar){.cdecl.}
|
||||
title_changed*: proc (document: PHtmlDocument, new_title: Pgchar){.cdecl.}
|
||||
submit*: proc (document: PHtmlDocument, `method`: Pgchar, url: Pgchar,
|
||||
encoding: Pgchar){.cdecl.}
|
||||
|
||||
PHtmlView* = ptr THtmlView
|
||||
THtmlView* = object of TGtkLayout
|
||||
document*: PHtmlDocument
|
||||
node_table*: PGHashTable
|
||||
relayout_idle_id*: guint
|
||||
relayout_timeout_id*: guint
|
||||
mouse_down_x*: gint
|
||||
mouse_down_y*: gint
|
||||
mouse_detail*: gint
|
||||
sel_start_ypos*: gint
|
||||
sel_start_index*: gint
|
||||
sel_end_ypos*: gint
|
||||
sel_end_index*: gint
|
||||
sel_flag*: gboolean
|
||||
sel_backwards*: gboolean
|
||||
sel_start_found*: gboolean
|
||||
sel_list*: PGSList
|
||||
jump_to_anchor*: pgchar
|
||||
magnification*: gdouble
|
||||
magnification_modified*: gboolean
|
||||
on_url*: gboolean
|
||||
|
||||
PHtmlViewClass* = ptr THtmlViewClass
|
||||
THtmlViewClass* = object of TGtkLayoutClass
|
||||
move_cursor*: proc (html_view: PHtmlView, step: TGtkMovementStep,
|
||||
count: gint, extend_selection: gboolean){.cdecl.}
|
||||
on_url*: proc (html_view: PHtmlView, url: Pgchar)
|
||||
activate*: proc (html_view: PHtmlView)
|
||||
move_focus_out*: proc (html_view: PHtmlView, direction: TGtkDirectionType)
|
||||
|
||||
|
||||
proc DOM_TYPE_NODE*(): GType
|
||||
proc DOM_NODE*(theobject: pointer): PDomNode
|
||||
proc DOM_NODE_CLASS*(klass: pointer): PDomNodeClass
|
||||
proc DOM_IS_NODE*(theobject: pointer): bool
|
||||
proc DOM_IS_NODE_CLASS*(klass: pointer): bool
|
||||
proc DOM_NODE_GET_CLASS*(obj: pointer): int32
|
||||
proc dom_node_get_type*(): GType{.cdecl, dynlib: gtkhtmllib,
|
||||
importc: "dom_node_get_type".}
|
||||
proc dom_Node_mkref*(node: pointer): PDomNode{.cdecl, dynlib: gtkhtmllib,
|
||||
importc: "dom_Node_mkref".}
|
||||
proc dom_Node__get_childNodes*(node: PDomNode): PDomNodeList{.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "dom_Node__get_childNodes".}
|
||||
proc dom_Node_removeChild*(node: PDomNode, oldChild: PDomNode,
|
||||
exc: PDomException): PDomNode{.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "dom_Node_removeChild".}
|
||||
proc dom_Node__get_nodeValue*(node: PDomNode, exc: PDomException): PDomString{.
|
||||
cdecl, dynlib: gtkhtmllib, importc: "dom_Node__get_nodeValue".}
|
||||
proc dom_Node__get_firstChild*(node: PDomNode): PDomNode{.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "dom_Node__get_firstChild".}
|
||||
proc dom_Node__get_nodeName*(node: PDomNode): PDomString{.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "dom_Node__get_nodeName".}
|
||||
proc dom_Node__get_attributes*(node: PDomNode): PDomNamedNodeMap{.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "dom_Node__get_attributes".}
|
||||
proc dom_Document__get_doctype*(doc: PDomDocument): PDomDocumentType{.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "dom_Document__get_doctype".}
|
||||
proc dom_Node_hasChildNodes*(node: PDomNode): DomBoolean{.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "dom_Node_hasChildNodes".}
|
||||
proc dom_Node__get_parentNode*(node: PDomNode): PDomNode{.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "dom_Node__get_parentNode".}
|
||||
proc dom_Node__get_nextSibling*(node: PDomNode): PDomNode{.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "dom_Node__get_nextSibling".}
|
||||
proc dom_Node__get_nodeType*(node: PDomNode): gushort{.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "dom_Node__get_nodeType".}
|
||||
proc dom_Node_hasAttributes*(node: PDomNode): DomBoolean{.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "dom_Node_hasAttributes".}
|
||||
proc dom_Node_cloneNode*(node: PDomNode, deep: DomBoolean): PDomNode{.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "dom_Node_cloneNode".}
|
||||
proc dom_Node_appendChild*(node: PDomNode, newChild: PDomNode,
|
||||
exc: PDomException): PDomNode{.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "dom_Node_appendChild".}
|
||||
proc dom_Node__get_localName*(node: PDomNode): PDomString{.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "dom_Node__get_localName".}
|
||||
proc dom_Node__get_namespaceURI*(node: PDomNode): PDomString{.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "dom_Node__get_namespaceURI".}
|
||||
proc dom_Node__get_previousSibling*(node: PDomNode): PDomNode{.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "dom_Node__get_previousSibling".}
|
||||
proc dom_Node__get_lastChild*(node: PDomNode): PDomNode{.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "dom_Node__get_lastChild".}
|
||||
proc dom_Node__set_nodeValue*(node: PDomNode, value: PDomString,
|
||||
exc: PDomException){.cdecl, dynlib: gtkhtmllib,
|
||||
importc: "dom_Node__set_nodeValue".}
|
||||
proc dom_Node__get_ownerDocument*(node: PDomNode): PDomDocument{.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "dom_Node__get_ownerDocument".}
|
||||
proc dom_Node_hasAttributes*(node: PDomNode): gboolean{.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "dom_Node_hasAttributes".}
|
||||
proc DOM_TYPE_DOCUMENT*(): GType
|
||||
proc DOM_DOCUMENT*(theobject: pointer): PDomDocument
|
||||
proc DOM_DOCUMENT_CLASS*(klass: pointer): PDomDocumentClass
|
||||
proc DOM_IS_DOCUMENT*(theobject: pointer): bool
|
||||
proc DOM_IS_DOCUMENT_CLASS*(klass: pointer): bool
|
||||
proc DOM_DOCUMENT_GET_CLASS*(obj: pointer): PDomDocumentClass
|
||||
proc dom_document_get_type*(): GType
|
||||
proc dom_Document__get_documentElement*(doc: PDomDocument): PDomElement
|
||||
proc dom_Document_createElement*(doc: PDomDocument, tagName: PDomString): PDomElement
|
||||
proc dom_Document_createTextNode*(doc: PDomDocument, data: PDomString): PDomText
|
||||
proc dom_Document_createComment*(doc: PDomDocument, data: PDomString): PDomComment
|
||||
proc dom_Document_importNode*(doc: PDomDocument, importedNode: PDomNode,
|
||||
deep: DomBoolean, exc: PDomException): PDomNode
|
||||
proc HTML_TYPE_FOCUS_ITERATOR*(): GType
|
||||
proc HTML_FOCUS_ITERATOR*(theobject: pointer): PHtmlFocusIterator
|
||||
proc HTML_FOCUS_ITERATOR_CLASS*(klass: pointer): PHtmlFocusIteratorClass
|
||||
proc HTML_IS_FOCUS_ITERATOR*(theobject: pointer): bool
|
||||
proc HTML_IS_FOCUS_ITERATOR_CLASS*(klass: pointer): bool
|
||||
proc HTML_FOCUS_ITERATOR_GET_CLASS*(obj: pointer): PHtmlFocusIteratorClass
|
||||
proc html_focus_iterator_next_element*(document: PDomDocument,
|
||||
element: PDomElement): PDomElement{.
|
||||
cdecl, dynlib: gtkhtmllib, importc: "html_focus_iterator_next_element".}
|
||||
proc html_focus_iterator_prev_element*(document: PDomDocument,
|
||||
element: PDomElement): PDomElement{.
|
||||
cdecl, dynlib: gtkhtmllib, importc: "html_focus_iterator_prev_element".}
|
||||
proc HTML_PARSER_TYPE*(): GType
|
||||
proc HTML_PARSER*(obj: pointer): PHtmlParser
|
||||
proc HTML_PARSER_CLASS*(klass: pointer): PHtmlParserClass
|
||||
proc HTML_IS_PARSER*(obj: pointer): bool
|
||||
proc html_parser_get_type*(): GType
|
||||
proc html_parser_new*(document: PHtmlDocument, parser_type: THtmlParserType): PHtmlParser
|
||||
proc HTML_TYPE_STREAM*(): GType
|
||||
proc HTML_STREAM*(obj: pointer): PHtmlStream
|
||||
proc HTML_STREAM_CLASS*(klass: pointer): PHtmlStreamClass
|
||||
proc HTML_IS_STREAM*(obj: pointer): bool
|
||||
proc HTML_IS_STREAM_CLASS*(klass: pointer): bool
|
||||
proc HTML_STREAM_GET_CLASS*(obj: pointer): PHtmlStreamClass
|
||||
proc html_stream_get_type*(): GType{.cdecl, dynlib: gtkhtmllib,
|
||||
importc: "html_stream_get_type".}
|
||||
proc html_stream_new*(write_func: THtmlStreamWriteFunc,
|
||||
close_func: THtmlStreamCloseFunc, user_data: gpointer): PHtmlStream{.
|
||||
cdecl, dynlib: gtkhtmllib, importc: "html_stream_new".}
|
||||
proc html_stream_write*(stream: PHtmlStream, buffer: Pgchar, size: guint){.
|
||||
cdecl, dynlib: gtkhtmllib, importc: "html_stream_write".}
|
||||
proc html_stream_close*(stream: PHtmlStream){.cdecl, dynlib: gtkhtmllib,
|
||||
importc: "html_stream_close".}
|
||||
proc html_stream_destroy*(stream: PHtmlStream){.cdecl, dynlib: gtkhtmllib,
|
||||
importc: "html_stream_destroy".}
|
||||
proc html_stream_get_written*(stream: PHtmlStream): gint{.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "html_stream_get_written".}
|
||||
proc html_stream_cancel*(stream: PHtmlStream){.cdecl, dynlib: gtkhtmllib,
|
||||
importc: "html_stream_cancel".}
|
||||
proc html_stream_set_cancel_func*(stream: PHtmlStream,
|
||||
abort_func: THtmlStreamCancelFunc,
|
||||
cancel_data: gpointer){.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "html_stream_set_cancel_func".}
|
||||
proc html_stream_get_mime_type*(stream: PHtmlStream): cstring{.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "html_stream_get_mime_type".}
|
||||
proc html_stream_set_mime_type*(stream: PHtmlStream, mime_type: cstring){.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "html_stream_set_mime_type".}
|
||||
proc html_stream_buffer_new*(close_func: THtmlStreamBufferCloseFunc,
|
||||
user_data: gpointer): PHtmlStream{.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "html_stream_buffer_new".}
|
||||
proc html_event_mouse_move*(view: PHtmlView, event: PGdkEventMotion){.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "html_event_mouse_move".}
|
||||
proc html_event_button_press*(view: PHtmlView, button: PGdkEventButton){.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "html_event_button_press".}
|
||||
proc html_event_button_release*(view: PHtmlView, event: PGdkEventButton){.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "html_event_button_release".}
|
||||
proc html_event_activate*(view: PHtmlView){.cdecl, dynlib: gtkhtmllib,
|
||||
importc: "html_event_activate".}
|
||||
proc html_event_key_press*(view: PHtmlView, event: PGdkEventKey): gboolean{.
|
||||
cdecl, dynlib: gtkhtmllib, importc: "html_event_key_press".}
|
||||
proc html_event_find_root_box*(self: PHtmlBox, x: gint, y: gint): PHtmlBox{.
|
||||
cdecl, dynlib: gtkhtmllib, importc: "html_event_find_root_box".}
|
||||
proc html_selection_start*(view: PHtmlView, event: PGdkEventButton){.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "html_selection_start".}
|
||||
proc html_selection_end*(view: PHtmlView, event: PGdkEventButton){.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "html_selection_end".}
|
||||
proc html_selection_update*(view: PHtmlView, event: PGdkEventMotion){.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "html_selection_update".}
|
||||
proc html_selection_clear*(view: PHtmlView){.cdecl, dynlib: gtkhtmllib,
|
||||
importc: "html_selection_clear".}
|
||||
proc html_selection_set*(view: PHtmlView, start: PDomNode, offset: int32,
|
||||
len: int32){.cdecl, dynlib: gtkhtmllib,
|
||||
importc: "html_selection_set".}
|
||||
proc GTK_HTML_CONTEXT_TYPE*(): GType
|
||||
proc GTK_HTML_CONTEXT*(obj: pointer): PGtkHtmlContext
|
||||
proc GTK_HTML_CONTEXT_CLASS*(klass: pointer): PGtkHtmlContextClass
|
||||
proc GTK_HTML_IS_CONTEXT*(obj: pointer): bool
|
||||
proc GTK_HTML_IS_CONTEXT_CLASS*(klass: pointer): bool
|
||||
proc gtk_html_context_get_type*(): GType
|
||||
proc gtk_html_context_get*(): PGtkHtmlContext
|
||||
proc HTML_TYPE_DOCUMENT*(): GType
|
||||
proc HTML_DOCUMENT*(obj: pointer): PHtmlDocument
|
||||
proc HTML_DOCUMENT_CLASS*(klass: pointer): PHtmlDocumentClass
|
||||
proc HTML_IS_DOCUMENT*(obj: pointer): bool
|
||||
proc html_document_get_type*(): GType{.cdecl, dynlib: gtkhtmllib,
|
||||
importc: "html_document_get_type".}
|
||||
proc html_document_new*(): PHtmlDocument{.cdecl, dynlib: gtkhtmllib,
|
||||
importc: "html_document_new".}
|
||||
proc html_document_open_stream*(document: PHtmlDocument, mime_type: Pgchar): gboolean{.
|
||||
cdecl, dynlib: gtkhtmllib, importc: "html_document_open_stream".}
|
||||
proc html_document_write_stream*(document: PHtmlDocument, buffer: Pgchar,
|
||||
len: gint){.cdecl, dynlib: gtkhtmllib,
|
||||
importc: "html_document_write_stream".}
|
||||
proc html_document_close_stream*(document: PHtmlDocument){.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "html_document_close_stream".}
|
||||
proc html_document_clear*(document: PHtmlDocument){.cdecl, dynlib: gtkhtmllib,
|
||||
importc: "html_document_clear".}
|
||||
proc HTML_TYPE_VIEW*(): GType
|
||||
proc HTML_VIEW*(obj: pointer): PHtmlView
|
||||
proc HTML_VIEW_CLASS*(klass: pointer): PHtmlViewClass
|
||||
proc HTML_IS_VIEW*(obj: pointer): bool
|
||||
proc html_view_get_type*(): GType{.cdecl, dynlib: gtkhtmllib,
|
||||
importc: "html_view_get_type".}
|
||||
proc html_view_new*(): PGtkWidget{.cdecl, dynlib: gtkhtmllib,
|
||||
importc: "html_view_new".}
|
||||
proc html_view_set_document*(view: PHtmlView, document: PHtmlDocument){.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "html_view_set_document".}
|
||||
proc html_view_jump_to_anchor*(view: PHtmlView, anchor: Pgchar){.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "html_view_jump_to_anchor".}
|
||||
proc html_view_get_magnification*(view: PHtmlView): gdouble{.cdecl,
|
||||
dynlib: gtkhtmllib, importc: "html_view_get_magnification".}
|
||||
proc html_view_set_magnification*(view: PHtmlView, magnification: gdouble){.
|
||||
cdecl, dynlib: gtkhtmllib, importc: "html_view_set_magnification".}
|
||||
proc html_view_zoom_in*(view: PHtmlView){.cdecl, dynlib: gtkhtmllib,
|
||||
importc: "html_view_zoom_in".}
|
||||
proc html_view_zoom_out*(view: PHtmlView){.cdecl, dynlib: gtkhtmllib,
|
||||
importc: "html_view_zoom_out".}
|
||||
proc html_view_zoom_reset*(view: PHtmlView){.cdecl, dynlib: gtkhtmllib,
|
||||
importc: "html_view_zoom_reset".}
|
||||
proc DOM_TYPE_NODE*(): GType =
|
||||
result = dom_node_get_type()
|
||||
|
||||
proc DOM_NODE*(theobject: pointer): PDomNode =
|
||||
result = G_TYPE_CHECK_INSTANCE_CAST(theobject, DOM_TYPE_NODE(), TDomNode)
|
||||
|
||||
proc DOM_NODE_CLASS*(klass: pointer): PDomNodeClass =
|
||||
result = G_TYPE_CHECK_CLASS_CAST(klass, DOM_TYPE_NODE(), TDomNodeClass)
|
||||
|
||||
proc DOM_IS_NODE*(theobject: pointer): bool =
|
||||
result = G_TYPE_CHECK_INSTANCE_TYPE(theobject, DOM_TYPE_NODE())
|
||||
|
||||
proc DOM_IS_NODE_CLASS*(klass: pointer): bool =
|
||||
result = G_TYPE_CHECK_CLASS_TYPE(klass, DOM_TYPE_NODE())
|
||||
|
||||
proc DOM_NODE_GET_CLASS*(obj: pointer): PDomNodeClass =
|
||||
result = G_TYPE_INSTANCE_GET_CLASS(obj, DOM_TYPE_NODE(), TDomNodeClass)
|
||||
|
||||
proc DOM_TYPE_DOCUMENT*(): GType =
|
||||
result = dom_document_get_type()
|
||||
|
||||
proc DOM_DOCUMENT*(theobject: pointer): PDomDocument =
|
||||
result = G_TYPE_CHECK_INSTANCE_CAST(theobject, DOM_TYPE_DOCUMENT(), TDomDocument)
|
||||
|
||||
proc DOM_DOCUMENT_CLASS*(klass: pointer): PDomDocumentClass =
|
||||
result = G_TYPE_CHECK_CLASS_CAST(klass, DOM_TYPE_DOCUMENT(), TDomDocumentClass)
|
||||
|
||||
proc DOM_IS_DOCUMENT*(theobject: pointer): bool =
|
||||
result = G_TYPE_CHECK_INSTANCE_TYPE(theobject, DOM_TYPE_DOCUMENT())
|
||||
|
||||
proc DOM_IS_DOCUMENT_CLASS*(klass: pointer): bool =
|
||||
result = G_TYPE_CHECK_CLASS_TYPE(klass, DOM_TYPE_DOCUMENT())
|
||||
|
||||
proc DOM_DOCUMENT_GET_CLASS*(obj: pointer): PDomDocumentClass =
|
||||
result = G_TYPE_INSTANCE_GET_CLASS(obj, DOM_TYPE_DOCUMENT(), TDomDocumentClass)
|
||||
|
||||
proc HTML_TYPE_FOCUS_ITERATOR*(): GType =
|
||||
result = html_focus_iterator_get_type()
|
||||
|
||||
proc HTML_FOCUS_ITERATOR*(theobject: pointer): PHtmlFocusIterator =
|
||||
result = G_TYPE_CHECK_INSTANCE_CAST(theobject, HTML_TYPE_FOCUS_ITERATOR(),
|
||||
HtmlFocusIterator)
|
||||
|
||||
proc HTML_FOCUS_ITERATOR_CLASS*(klass: pointer): PHtmlFocusIteratorClass =
|
||||
result = G_TYPE_CHECK_CLASS_CAST(klass, HTML_TYPE_FOCUS_ITERATOR(),
|
||||
HtmlFocusIteratorClass)
|
||||
|
||||
proc HTML_IS_FOCUS_ITERATOR*(theobject: pointer): bool =
|
||||
result = G_TYPE_CHECK_INSTANCE_TYPE(theobject, HTML_TYPE_FOCUS_ITERATOR())
|
||||
|
||||
proc HTML_IS_FOCUS_ITERATOR_CLASS*(klass: pointer): bool =
|
||||
result = G_TYPE_CHECK_CLASS_TYPE(klass, HTML_TYPE_FOCUS_ITERATOR())
|
||||
|
||||
proc HTML_FOCUS_ITERATOR_GET_CLASS*(obj: pointer): PHtmlFocusIteratorClass =
|
||||
result = G_TYPE_INSTANCE_GET_CLASS(obj, HTML_TYPE_FOCUS_ITERATOR(),
|
||||
HtmlFocusIteratorClass)
|
||||
|
||||
proc HTML_PARSER_TYPE*(): GType =
|
||||
result = html_parser_get_type()
|
||||
|
||||
proc HTML_PARSER*(obj: pointer): PHtmlParser =
|
||||
result = GTK_CHECK_CAST(obj, HTML_PARSER_TYPE(), THtmlParser)
|
||||
|
||||
proc HTML_PARSER_CLASS*(klass: pointer): PHtmlParserClass =
|
||||
result = GTK_CHECK_CLASS_CAST(klass, HTML_PARSER_TYPE(), THtmlParserClass)
|
||||
|
||||
proc HTML_IS_PARSER*(obj: pointer): bool =
|
||||
result = GTK_CHECK_TYPE(obj, HTML_PARSER_TYPE())
|
||||
|
||||
proc HTML_TYPE_STREAM*(): GType =
|
||||
result = html_stream_get_type()
|
||||
|
||||
proc HTML_STREAM*(obj: pointer): PHtmlStream =
|
||||
result = PHtmlStream(G_TYPE_CHECK_INSTANCE_CAST(obj, HTML_TYPE_STREAM()))
|
||||
|
||||
proc HTML_STREAM_CLASS*(klass: pointer): PHtmlStreamClass =
|
||||
result = G_TYPE_CHECK_CLASS_CAST(klass, HTML_TYPE_STREAM())
|
||||
|
||||
proc HTML_IS_STREAM*(obj: pointer): bool =
|
||||
result = G_TYPE_CHECK_INSTANCE_TYPE(obj, HTML_TYPE_STREAM())
|
||||
|
||||
proc HTML_IS_STREAM_CLASS*(klass: pointer): bool =
|
||||
result = G_TYPE_CHECK_CLASS_TYPE(klass, HTML_TYPE_STREAM())
|
||||
|
||||
proc HTML_STREAM_GET_CLASS*(obj: pointer): PHtmlStreamClass =
|
||||
result = PHtmlStreamClass(G_TYPE_INSTANCE_GET_CLASS(obj, HTML_TYPE_STREAM()))
|
||||
|
||||
proc GTK_HTML_CONTEXT_TYPE*(): GType =
|
||||
result = gtk_html_context_get_type()
|
||||
|
||||
proc GTK_HTML_CONTEXT*(obj: pointer): PGtkHtmlContext =
|
||||
result = GTK_CHECK_CAST(obj, GTK_HTML_CONTEXT_TYPE(), TGtkHtmlContext)
|
||||
|
||||
proc GTK_HTML_CONTEXT_CLASS*(klass: pointer): PGtkHtmlContextClass =
|
||||
result = GTK_CHECK_CLASS_CAST(klass, GTK_HTML_CONTEXT_TYPE(),
|
||||
TGtkHtmlContextClass)
|
||||
|
||||
proc GTK_HTML_IS_CONTEXT*(obj: pointer): bool =
|
||||
result = GTK_CHECK_TYPE(obj, GTK_HTML_CONTEXT_TYPE())
|
||||
|
||||
proc GTK_HTML_IS_CONTEXT_CLASS*(klass: pointer): bool =
|
||||
result = GTK_CHECK_CLASS_TYPE(klass, GTK_HTML_CONTEXT_TYPE())
|
||||
|
||||
proc HTML_TYPE_DOCUMENT*(): GType =
|
||||
result = html_document_get_type()
|
||||
|
||||
proc HTML_DOCUMENT*(obj: pointer): PHtmlDocument =
|
||||
result = PHtmlDocument(GTK_CHECK_CAST(obj, HTML_TYPE_DOCUMENT()))
|
||||
|
||||
proc HTML_DOCUMENT_CLASS*(klass: pointer): PHtmlDocumentClass =
|
||||
result = GTK_CHECK_CLASS_CAST(klass, HTML_TYPE_DOCUMENT())
|
||||
|
||||
proc HTML_IS_DOCUMENT*(obj: pointer): bool =
|
||||
result = GTK_CHECK_TYPE(obj, HTML_TYPE_DOCUMENT())
|
||||
|
||||
proc HTML_TYPE_VIEW*(): GType =
|
||||
result = html_view_get_type()
|
||||
|
||||
proc HTML_VIEW*(obj: pointer): PHtmlView =
|
||||
result = PHtmlView(GTK_CHECK_CAST(obj, HTML_TYPE_VIEW()))
|
||||
|
||||
proc HTML_VIEW_CLASS*(klass: pointer): PHtmlViewClass =
|
||||
result = PHtmlViewClass(GTK_CHECK_CLASS_CAST(klass, HTML_TYPE_VIEW()))
|
||||
|
||||
proc HTML_IS_VIEW*(obj: pointer): bool =
|
||||
result = GTK_CHECK_TYPE(obj, HTML_TYPE_VIEW())
|
||||
117
lib/base/gtk/libglade2.nim
Executable file
117
lib/base/gtk/libglade2.nim
Executable file
|
|
@ -0,0 +1,117 @@
|
|||
import
|
||||
glib2, gtk2
|
||||
|
||||
when defined(win32):
|
||||
{.define: gtkwin.}
|
||||
const
|
||||
LibGladeLib = "libglade-2.0-0.dll"
|
||||
else:
|
||||
const
|
||||
LibGladeLib = "libglade-2.0.so"
|
||||
type
|
||||
PLongint* = ptr int32
|
||||
PSmallInt* = ptr int16
|
||||
PByte* = ptr int8
|
||||
PWord* = ptr int16
|
||||
PDWord* = ptr int32
|
||||
PDouble* = ptr float64
|
||||
|
||||
proc glade_init*(){.cdecl, dynlib: LibGladeLib, importc: "glade_init".}
|
||||
proc glade_require*(TheLibrary: cstring){.cdecl, dynlib: LibGladeLib,
|
||||
importc: "glade_require".}
|
||||
proc glade_provide*(TheLibrary: cstring){.cdecl, dynlib: LibGladeLib,
|
||||
importc: "glade_provide".}
|
||||
type
|
||||
PGladeXMLPrivate* = pointer
|
||||
PGladeXML* = ptr TGladeXML
|
||||
TGladeXML* = object of TGObject
|
||||
filename*: cstring
|
||||
priv*: PGladeXMLPrivate
|
||||
|
||||
PGladeXMLClass* = ptr TGladeXMLClass
|
||||
TGladeXMLClass* = object of TGObjectClass
|
||||
|
||||
TGladeXMLConnectFunc* = proc (handler_name: cstring, anObject: PGObject,
|
||||
signal_name: cstring, signal_data: cstring,
|
||||
connect_object: PGObject, after: gboolean,
|
||||
user_data: gpointer){.cdecl.}
|
||||
|
||||
proc GLADE_TYPE_XML*(): GType
|
||||
proc GLADE_XML*(obj: pointer): PGladeXML
|
||||
proc GLADE_XML_CLASS*(klass: pointer): PGladeXMLClass
|
||||
proc GLADE_IS_XML*(obj: pointer): gboolean
|
||||
proc GLADE_IS_XML_CLASS*(klass: pointer): gboolean
|
||||
proc GLADE_XML_GET_CLASS*(obj: pointer): PGladeXMLClass
|
||||
proc glade_xml_get_type*(): GType{.cdecl, dynlib: LibGladeLib,
|
||||
importc: "glade_xml_get_type".}
|
||||
proc glade_xml_new*(fname: cstring, root: cstring, domain: cstring): PGladeXML{.
|
||||
cdecl, dynlib: LibGladeLib, importc: "glade_xml_new".}
|
||||
proc glade_xml_new_from_buffer*(buffer: cstring, size: int32, root: cstring,
|
||||
domain: cstring): PGladeXML{.cdecl,
|
||||
dynlib: LibGladeLib, importc: "glade_xml_new_from_buffer".}
|
||||
proc glade_xml_construct*(self: PGladeXML, fname: cstring, root: cstring,
|
||||
domain: cstring): gboolean{.cdecl,
|
||||
dynlib: LibGladeLib, importc: "glade_xml_construct".}
|
||||
proc glade_xml_signal_connect*(self: PGladeXML, handlername: cstring,
|
||||
func: TGCallback){.cdecl, dynlib: LibGladeLib,
|
||||
importc: "glade_xml_signal_connect".}
|
||||
proc glade_xml_signal_connect_data*(self: PGladeXML, handlername: cstring,
|
||||
func: TGCallback, user_data: gpointer){.
|
||||
cdecl, dynlib: LibGladeLib, importc: "glade_xml_signal_connect_data".}
|
||||
proc glade_xml_signal_autoconnect*(self: PGladeXML){.cdecl, dynlib: LibGladeLib,
|
||||
importc: "glade_xml_signal_autoconnect".}
|
||||
proc glade_xml_signal_connect_full*(self: PGladeXML, handler_name: cstring,
|
||||
func: TGladeXMLConnectFunc,
|
||||
user_data: gpointer){.cdecl,
|
||||
dynlib: LibGladeLib, importc: "glade_xml_signal_connect_full".}
|
||||
proc glade_xml_signal_autoconnect_full*(self: PGladeXML,
|
||||
func: TGladeXMLConnectFunc,
|
||||
user_data: gpointer){.cdecl,
|
||||
dynlib: LibGladeLib, importc: "glade_xml_signal_autoconnect_full".}
|
||||
proc glade_xml_get_widget*(self: PGladeXML, name: cstring): PGtkWidget{.cdecl,
|
||||
dynlib: LibGladeLib, importc: "glade_xml_get_widget".}
|
||||
proc glade_xml_get_widget_prefix*(self: PGladeXML, name: cstring): PGList{.
|
||||
cdecl, dynlib: LibGladeLib, importc: "glade_xml_get_widget_prefix".}
|
||||
proc glade_xml_relative_file*(self: PGladeXML, filename: cstring): cstring{.cdecl,
|
||||
dynlib: LibGladeLib, importc: "glade_xml_relative_file".}
|
||||
proc glade_get_widget_name*(widget: PGtkWidget): cstring{.cdecl,
|
||||
dynlib: LibGladeLib, importc: "glade_get_widget_name".}
|
||||
proc glade_get_widget_tree*(widget: PGtkWidget): PGladeXML{.cdecl,
|
||||
dynlib: LibGladeLib, importc: "glade_get_widget_tree".}
|
||||
type
|
||||
PGladeXMLCustomWidgetHandler* = ptr TGladeXMLCustomWidgetHandler
|
||||
TGladeXMLCustomWidgetHandler* = TGtkWidget
|
||||
|
||||
proc glade_set_custom_handler*(handler: TGladeXMLCustomWidgetHandler,
|
||||
user_data: gpointer){.cdecl, dynlib: LibGladeLib,
|
||||
importc: "glade_set_custom_handler".}
|
||||
proc glade_gnome_init*() =
|
||||
glade_init()
|
||||
|
||||
proc glade_bonobo_init*() =
|
||||
glade_init()
|
||||
|
||||
proc glade_xml_new_with_domain*(fname: cstring, root: cstring, domain: cstring): PGladeXML =
|
||||
result = glade_xml_new(fname, root, domain)
|
||||
|
||||
proc glade_xml_new_from_memory*(buffer: cstring, size: int32, root: cstring,
|
||||
domain: cstring): PGladeXML =
|
||||
result = glade_xml_new_from_buffer(buffer, size, root, domain)
|
||||
|
||||
proc GLADE_TYPE_XML*(): GType =
|
||||
result = glade_xml_get_type()
|
||||
|
||||
proc GLADE_XML*(obj: pointer): PGladeXML =
|
||||
result = cast[PGladeXML](G_TYPE_CHECK_INSTANCE_CAST(obj, GLADE_TYPE_XML()))
|
||||
|
||||
proc GLADE_XML_CLASS*(klass: pointer): PGladeXMLClass =
|
||||
result = cast[PGladeXMLClass](G_TYPE_CHECK_CLASS_CAST(klass, GLADE_TYPE_XML()))
|
||||
|
||||
proc GLADE_IS_XML*(obj: pointer): gboolean =
|
||||
result = G_TYPE_CHECK_INSTANCE_TYPE(obj, GLADE_TYPE_XML())
|
||||
|
||||
proc GLADE_IS_XML_CLASS*(klass: pointer): gboolean =
|
||||
result = G_TYPE_CHECK_CLASS_TYPE(klass, GLADE_TYPE_XML())
|
||||
|
||||
proc GLADE_XML_GET_CLASS*(obj: pointer): PGladeXMLClass =
|
||||
result = cast[PGladeXMLClass](G_TYPE_INSTANCE_GET_CLASS(obj, GLADE_TYPE_XML()))
|
||||
1209
lib/base/gtk/pango.nim
Executable file
1209
lib/base/gtk/pango.nim
Executable file
File diff suppressed because it is too large
Load diff
46
lib/base/gtk/pangoutils.nim
Executable file
46
lib/base/gtk/pangoutils.nim
Executable file
|
|
@ -0,0 +1,46 @@
|
|||
import
|
||||
glib2, pango
|
||||
|
||||
type
|
||||
pint32* = ptr int32
|
||||
|
||||
proc pango_split_file_list*(str: cstring): PPchar{.cdecl, dynlib: pangolib,
|
||||
importc: "pango_split_file_list".}
|
||||
proc pango_trim_string*(str: cstring): cstring{.cdecl, dynlib: pangolib,
|
||||
importc: "pango_trim_string".}
|
||||
proc pango_read_line*(stream: TFile, str: PGString): gint{.cdecl,
|
||||
dynlib: pangolib, importc: "pango_read_line".}
|
||||
proc pango_skip_space*(pos: PPchar): gboolean{.cdecl, dynlib: pangolib,
|
||||
importc: "pango_skip_space".}
|
||||
proc pango_scan_word*(pos: PPchar, OutStr: PGString): gboolean{.cdecl,
|
||||
dynlib: pangolib, importc: "pango_scan_word".}
|
||||
proc pango_scan_string*(pos: PPchar, OutStr: PGString): gboolean{.cdecl,
|
||||
dynlib: pangolib, importc: "pango_scan_string".}
|
||||
proc pango_scan_int*(pos: PPchar, OutInt: pint32): gboolean{.cdecl,
|
||||
dynlib: pangolib, importc: "pango_scan_int".}
|
||||
when defined(PANGO_ENABLE_BACKEND):
|
||||
proc pango_config_key_get(key: cstring): cstring{.cdecl, dynlib: pangolib,
|
||||
importc: "pango_config_key_get".}
|
||||
proc pango_lookup_aliases(fontname: cstring, families: PPPchar,
|
||||
n_families: pint32){.cdecl, dynlib: pangolib,
|
||||
importc: "pango_lookup_aliases".}
|
||||
proc pango_parse_style*(str: cstring, style: PPangoStyle, warn: gboolean): gboolean{.
|
||||
cdecl, dynlib: pangolib, importc: "pango_parse_style".}
|
||||
proc pango_parse_variant*(str: cstring, variant: PPangoVariant, warn: gboolean): gboolean{.
|
||||
cdecl, dynlib: pangolib, importc: "pango_parse_variant".}
|
||||
proc pango_parse_weight*(str: cstring, weight: PPangoWeight, warn: gboolean): gboolean{.
|
||||
cdecl, dynlib: pangolib, importc: "pango_parse_weight".}
|
||||
proc pango_parse_stretch*(str: cstring, stretch: PPangoStretch, warn: gboolean): gboolean{.
|
||||
cdecl, dynlib: pangolib, importc: "pango_parse_stretch".}
|
||||
when defined(PANGO_ENABLE_BACKEND):
|
||||
proc pango_get_sysconf_subdirectory(): cstring{.cdecl, dynlib: pangolib,
|
||||
importc: "pango_get_sysconf_subdirectory".}
|
||||
proc pango_get_lib_subdirectory(): cstring{.cdecl, dynlib: pangolib,
|
||||
importc: "pango_get_lib_subdirectory".}
|
||||
proc pango_log2vis_get_embedding_levels*(str: Pgunichar, len: int32,
|
||||
pbase_dir: PPangoDirection, embedding_level_list: Pguint8): gboolean{.cdecl,
|
||||
dynlib: pangolib, importc: "pango_log2vis_get_embedding_levels".}
|
||||
proc pango_get_mirror_char*(ch: gunichar, mirrored_ch: Pgunichar): gboolean{.
|
||||
cdecl, dynlib: pangolib, importc: "pango_get_mirror_char".}
|
||||
proc pango_language_get_sample_string*(language: PPangoLanguage): cstring{.
|
||||
cdecl, dynlib: pangolib, importc: "pango_language_get_sample_string".}
|
||||
124
lib/base/nregex.nim
Executable file
124
lib/base/nregex.nim
Executable file
|
|
@ -0,0 +1,124 @@
|
|||
# new implementation of regular expressions
|
||||
|
||||
type
|
||||
TRegexKind = enum
|
||||
regNone,
|
||||
regChar,
|
||||
regSet,
|
||||
regConc,
|
||||
regAlt,
|
||||
regStar,
|
||||
regPlus,
|
||||
regMN,
|
||||
regNewline
|
||||
|
||||
TRegex = record
|
||||
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")
|
||||
296
lib/base/pcre.nim
Executable file
296
lib/base/pcre.nim
Executable file
|
|
@ -0,0 +1,296 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
# 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
|
||||
# h2pas could handle it. Then I used pas2mor to generate a Morpork binding.
|
||||
# Unfortunately, I had to fix some things later on; thus don't do all this
|
||||
# again! My manual changes will be lost!
|
||||
|
||||
# Converted by Pas2mor v1.37
|
||||
#
|
||||
# Automatically converted by H2Pas 0.99.16 from modpcre.h
|
||||
# The following command line parameters were used:
|
||||
# -D -c -l pcre.lib -T modpcre.h
|
||||
|
||||
{.compile: "pcre_all.c" .}
|
||||
|
||||
type
|
||||
Pbyte = ptr byte
|
||||
Pchar = CString
|
||||
PPchar = ptr PChar
|
||||
Pint = ptr cint
|
||||
Ppcre* = ptr TPcre
|
||||
Ppcre_callout_block = ptr tpcre_callout_block
|
||||
Ppcre_extra = ptr Tpcre_extra
|
||||
|
||||
#************************************************
|
||||
#* Perl-Compatible Regular Expressions *
|
||||
#************************************************
|
||||
#
|
||||
# Modified by Andreas Rumpf for h2pas.
|
||||
|
||||
# In its original form, this is the .in file that is transformed by
|
||||
# "configure" into pcre.h.
|
||||
#
|
||||
# Copyright (c) 1997-2005 University of Cambridge
|
||||
#
|
||||
# -----------------------------------------------------------------------------
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# * Neither the name of the University of Cambridge nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# The file pcre.h is build by "configure". Do not edit it; instead
|
||||
# make changes to pcre.in.
|
||||
|
||||
const
|
||||
PCRE_MAJOR* = 6
|
||||
PCRE_MINOR* = 3
|
||||
PCRE_DATE* = "2005/11/29"
|
||||
# Options
|
||||
PCRE_CASELESS* = 0x00000001
|
||||
PCRE_MULTILINE* = 0x00000002
|
||||
PCRE_DOTALL* = 0x00000004
|
||||
PCRE_EXTENDED* = 0x00000008
|
||||
PCRE_ANCHORED* = 0x00000010
|
||||
PCRE_DOLLAR_ENDONLY* = 0x00000020
|
||||
PCRE_EXTRA* = 0x00000040
|
||||
PCRE_NOTBOL* = 0x00000080
|
||||
PCRE_NOTEOL* = 0x00000100
|
||||
PCRE_UNGREEDY* = 0x00000200
|
||||
PCRE_NOTEMPTY* = 0x00000400
|
||||
PCRE_UTF8* = 0x00000800
|
||||
PCRE_NO_AUTO_CAPTURE* = 0x00001000
|
||||
PCRE_NO_UTF8_CHECK* = 0x00002000
|
||||
PCRE_AUTO_CALLOUT* = 0x00004000
|
||||
PCRE_PARTIAL* = 0x00008000
|
||||
PCRE_DFA_SHORTEST* = 0x00010000
|
||||
PCRE_DFA_RESTART* = 0x00020000
|
||||
PCRE_FIRSTLINE* = 0x00040000
|
||||
# Exec-time and get/set-time error codes
|
||||
PCRE_ERROR_NOMATCH* = -(1)
|
||||
PCRE_ERROR_NULL* = -(2)
|
||||
PCRE_ERROR_BADOPTION* = -(3)
|
||||
PCRE_ERROR_BADMAGIC* = -(4)
|
||||
PCRE_ERROR_UNKNOWN_NODE* = -(5)
|
||||
PCRE_ERROR_NOMEMORY* = -(6)
|
||||
PCRE_ERROR_NOSUBSTRING* = -(7)
|
||||
PCRE_ERROR_MATCHLIMIT* = -(8)
|
||||
# Never used by PCRE itself
|
||||
PCRE_ERROR_CALLOUT* = -(9)
|
||||
PCRE_ERROR_BADUTF8* = -(10)
|
||||
PCRE_ERROR_BADUTF8_OFFSET* = -(11)
|
||||
PCRE_ERROR_PARTIAL* = -(12)
|
||||
PCRE_ERROR_BADPARTIAL* = -(13)
|
||||
PCRE_ERROR_INTERNAL* = -(14)
|
||||
PCRE_ERROR_BADCOUNT* = -(15)
|
||||
PCRE_ERROR_DFA_UITEM* = -(16)
|
||||
PCRE_ERROR_DFA_UCOND* = -(17)
|
||||
PCRE_ERROR_DFA_UMLIMIT* = -(18)
|
||||
PCRE_ERROR_DFA_WSSIZE* = -(19)
|
||||
PCRE_ERROR_DFA_RECURSE* = -(20)
|
||||
# Request types for pcre_fullinfo()
|
||||
PCRE_INFO_OPTIONS* = 0
|
||||
PCRE_INFO_SIZE* = 1
|
||||
PCRE_INFO_CAPTURECOUNT* = 2
|
||||
PCRE_INFO_BACKREFMAX* = 3
|
||||
PCRE_INFO_FIRSTBYTE* = 4
|
||||
# For backwards compatibility
|
||||
PCRE_INFO_FIRSTCHAR* = 4
|
||||
PCRE_INFO_FIRSTTABLE* = 5
|
||||
PCRE_INFO_LASTLITERAL* = 6
|
||||
PCRE_INFO_NAMEENTRYSIZE* = 7
|
||||
PCRE_INFO_NAMECOUNT* = 8
|
||||
PCRE_INFO_NAMETABLE* = 9
|
||||
PCRE_INFO_STUDYSIZE* = 10
|
||||
PCRE_INFO_DEFAULT_TABLES* = 11
|
||||
# Request types for pcre_config()
|
||||
PCRE_CONFIG_UTF8* = 0
|
||||
PCRE_CONFIG_NEWLINE* = 1
|
||||
PCRE_CONFIG_LINK_SIZE* = 2
|
||||
PCRE_CONFIG_POSIX_MALLOC_THRESHOLD* = 3
|
||||
PCRE_CONFIG_MATCH_LIMIT* = 4
|
||||
PCRE_CONFIG_STACKRECURSE* = 5
|
||||
PCRE_CONFIG_UNICODE_PROPERTIES* = 6
|
||||
# Bit flags for the pcre_extra structure
|
||||
PCRE_EXTRA_STUDY_DATA* = 0x0001
|
||||
PCRE_EXTRA_MATCH_LIMIT* = 0x0002
|
||||
PCRE_EXTRA_CALLOUT_DATA* = 0x0004
|
||||
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* = record
|
||||
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* = record
|
||||
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
|
||||
|
||||
proc pcre_compile*(para1: Pchar, para2: cint, para3: ptr Pchar,
|
||||
para4: Pint, para5: Pbyte): Ppcre {.
|
||||
importc: "pcre_compile", noconv.}
|
||||
|
||||
proc pcre_compile2*(para1: Pchar, para2: cint, para3: Pint, para4: PPchar,
|
||||
para5: Pint, para6: Pbyte): Ppcre {.
|
||||
importc: "pcre_compile2", noconv.}
|
||||
|
||||
proc pcre_config*(para1: cint, para2: pointer): cint {.
|
||||
importc: "pcre_config", noconv.}
|
||||
|
||||
proc pcre_copy_named_substring*(para1: Ppcre, para2: Pchar, para3: Pint,
|
||||
para4: cint, para5: Pchar, para6: Pchar,
|
||||
para7: cint): cint {.
|
||||
importc: "pcre_copy_named_substring", noconv.}
|
||||
|
||||
proc pcre_copy_substring*(para1: Pchar, para2: Pint, para3: cint, para4: cint,
|
||||
para5: Pchar, para6: cint): cint {.
|
||||
importc: "pcre_copy_substring", noconv.}
|
||||
|
||||
proc pcre_dfa_exec*(para1: Ppcre, para2: Ppcre_extra, para3: Pchar,
|
||||
para4: cint, para5: cint, para6: cint, para7: Pint,
|
||||
para8: cint, para9: Pint, para10: cint): cint {.
|
||||
importc: "pcre_dfa_exec", noconv.}
|
||||
|
||||
proc pcre_exec*(para1: Ppcre, para2: Ppcre_extra, para3: Pchar,
|
||||
para4: cint, para5: cint, para6: cint, para7: Pint,
|
||||
para8: cint): cint {.importc: "pcre_exec", noconv.}
|
||||
|
||||
proc pcre_free_substring*(para1: Pchar) {.
|
||||
importc: "pcre_free_substring", noconv.}
|
||||
|
||||
proc pcre_free_substring_list*(para1: PPchar) {.
|
||||
importc: "pcre_free_substring_list", noconv.}
|
||||
|
||||
proc pcre_fullinfo*(para1: Ppcre, para2: Ppcre_extra, para3: cint,
|
||||
para4: pointer): cint {.importc: "pcre_fullinfo", noconv.}
|
||||
|
||||
proc pcre_get_named_substring*(para1: Ppcre, para2: Pchar, para3: Pint,
|
||||
para4: cint, para5: Pchar, para6: PPchar): cint {.
|
||||
importc: "pcre_get_named_substring", noconv.}
|
||||
|
||||
proc pcre_get_stringnumber*(para1: Ppcre, para2: Pchar): cint {.
|
||||
importc: "pcre_get_stringnumber", noconv.}
|
||||
|
||||
proc pcre_get_substring*(para1: Pchar, para2: Pint, para3: cint,
|
||||
para4: cint, para5: PPchar): cint {.
|
||||
importc: "pcre_get_substring", noconv.}
|
||||
|
||||
proc pcre_get_substring_list*(para1: Pchar, para2: Pint, para3: cint,
|
||||
para4: ptr PPchar): cint {.
|
||||
importc: "pcre_get_substring_list", noconv.}
|
||||
|
||||
proc pcre_info*(para1: Ppcre, para2: Pint, para3: Pint): cint {.
|
||||
importc: "pcre_info", noconv.}
|
||||
|
||||
proc pcre_maketables*: ptr byte {.
|
||||
importc: "pcre_maketables", noconv.}
|
||||
|
||||
proc pcre_refcount*(para1: Ppcre, para2: cint): cint {.
|
||||
importc: "pcre_refcount", noconv.}
|
||||
|
||||
proc pcre_study*(para1: Ppcre, para2: cint,
|
||||
para3: ptr CString): Ppcre_extra {.importc, noconv.}
|
||||
|
||||
proc pcre_version*: CString {.importc: "pcre_version", noconv.}
|
||||
|
||||
# Indirection for store get and free functions. These can be set to
|
||||
# alternative malloc/free functions if required. Special ones are used in the
|
||||
# non-recursive case for "frames". There is also an optional callout function
|
||||
# that is triggered by the (?) regex item.
|
||||
#
|
||||
|
||||
# we use Nimrod's memory manager (but not GC!) for these functions:
|
||||
var
|
||||
pcre_malloc {.importc: "pcre_malloc".}: proc (para1: int): pointer {.noconv.}
|
||||
pcre_free {.importc: "pcre_free".}: proc (para1: pointer) {.noconv.}
|
||||
pcre_stack_malloc {.importc: "pcre_stack_malloc".}:
|
||||
proc (para1: int): pointer {.noconv.}
|
||||
pcre_stack_free {.importc: "pcre_stack_free".}:
|
||||
proc (para1: pointer) {.noconv.}
|
||||
pcre_callout {.importc: "pcre_callout".}:
|
||||
proc (para1: Ppcre_callout_block): cint {.noconv.}
|
||||
|
||||
pcre_malloc = system.alloc
|
||||
pcre_free = system.dealloc
|
||||
pcre_stack_malloc = system.alloc
|
||||
pcre_stack_free = system.dealloc
|
||||
pcre_callout = nil
|
||||
30072
lib/base/pcre_all.c
Executable file
30072
lib/base/pcre_all.c
Executable file
File diff suppressed because it is too large
Load diff
114
lib/base/regexprs.nim
Executable file
114
lib/base/regexprs.nim
Executable file
|
|
@ -0,0 +1,114 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
## Regular expression support for Nimrod.
|
||||
## Currently this module is implemented by providing a wrapper around the
|
||||
## `PRCE (Perl-Compatible Regular Expressions) <http://www.pcre.org>`_
|
||||
## C library. This means that your application will depend on the PRCE
|
||||
## library's licence when using this module, which should not be a problem
|
||||
## though.
|
||||
## PRCE's licence follows:
|
||||
##
|
||||
## .. include:: ../doc/regexprs.txt
|
||||
##
|
||||
|
||||
# This is not just a convenient wrapper for the pcre library; the
|
||||
# API will stay the same if the implementation should change.
|
||||
|
||||
import
|
||||
pcre, strutils
|
||||
|
||||
type
|
||||
EInvalidRegEx* = object of EInvalidValue
|
||||
## is raised if the pattern is no valid regular expression.
|
||||
|
||||
const
|
||||
MaxSubpatterns* = 10
|
||||
## defines the maximum number of subpatterns that can be captured.
|
||||
## More subpatterns cannot be captured!
|
||||
|
||||
proc match*(s, pattern: string, substrs: var openarray[string],
|
||||
start: int = 0): bool
|
||||
## returns ``true`` if ``s`` matches the ``pattern[start..]`` and
|
||||
## the captured substrings in the array ``substrs``. If it does not
|
||||
## match, nothing is written into ``substrs`` and ``false`` is
|
||||
## returned.
|
||||
|
||||
proc match*(s, pattern: string, start: int = 0): bool
|
||||
## returns ``true`` if ``s`` matches the ``pattern`` beginning from ``start``.
|
||||
|
||||
proc matchLen*(s, pattern: string, substrs: var openarray[string],
|
||||
start: int = 0): int
|
||||
## the same as ``match``, but it returns the length of the match,
|
||||
## if there is no match, -1 is returned. Note that a match length
|
||||
## of zero can happen.
|
||||
|
||||
proc find*(s, pattern: string, substrs: var openarray[string],
|
||||
start: int = 0): bool
|
||||
## returns ``true`` if ``pattern`` occurs in ``s`` and the captured
|
||||
## substrings in the array ``substrs``. If it does not match, nothing
|
||||
## is written into ``substrs``.
|
||||
proc find*(s, pattern: string, start: int = 0): bool
|
||||
## returns ``true`` if ``pattern`` occurs in ``s``.
|
||||
|
||||
|
||||
proc rawCompile(pattern: string, flags: cint): PPcre =
|
||||
var
|
||||
msg: CString
|
||||
offset: cint
|
||||
com = pcreCompile(pattern, flags, addr(msg), addr(offset), nil)
|
||||
if com == nil:
|
||||
var e: ref EInvalidRegEx
|
||||
new(e)
|
||||
e.msg = $msg & "\n" & pattern & "\n" & repeatChar(offset) & "^\n"
|
||||
raise e
|
||||
return com
|
||||
|
||||
proc matchOrFind(s: string, pattern: PPcre, substrs: var openarray[string],
|
||||
start: cint): cint =
|
||||
var
|
||||
rawMatches: array [0..maxSubpatterns * 3 - 1, cint]
|
||||
res = int(pcreExec(pattern, nil, s, length(s), start, 0,
|
||||
cast[pint](addr(rawMatches)), maxSubpatterns * 3))
|
||||
dealloc(pattern)
|
||||
if res < 0: return res
|
||||
for i in 0..res-1:
|
||||
var
|
||||
a = rawMatches[i * 3]
|
||||
b = rawMatches[i * 3 + 1]
|
||||
if a >= 0: substrs[i] = copy(s, a, b)
|
||||
else: substrs[i] = ""
|
||||
return res
|
||||
|
||||
proc matchOrFind(s: string, pattern: PPcre, start: cint): cint =
|
||||
var
|
||||
rawMatches: array [0..maxSubpatterns * 3 - 1, cint]
|
||||
res = pcreExec(pattern, nil, s, length(s), start, 0,
|
||||
cast[pint](addr(rawMatches)), maxSubpatterns * 3)
|
||||
dealloc(pattern)
|
||||
return res
|
||||
|
||||
proc match(s, pattern: string, substrs: var openarray[string],
|
||||
start: int = 0): bool =
|
||||
return matchOrFind(s, rawCompile(pattern, PCRE_ANCHORED),
|
||||
substrs, start) >= 0
|
||||
|
||||
proc matchLen(s, pattern: string, substrs: var openarray[string],
|
||||
start: int = 0): int =
|
||||
return matchOrFind(s, rawCompile(pattern, PCRE_ANCHORED), substrs, start)
|
||||
|
||||
proc find(s, pattern: string, substrs: var openarray[string],
|
||||
start: int = 0): bool =
|
||||
return matchOrFind(s, rawCompile(pattern, 0), substrs, start) >= 0
|
||||
|
||||
proc match(s, pattern: string, start: int = 0): bool =
|
||||
return matchOrFind(s, rawCompile(pattern, PCRE_ANCHORED), start) >= 0
|
||||
|
||||
proc find(s, pattern: string, start: int = 0): bool =
|
||||
return matchOrFind(s, rawCompile(pattern, 0), start) >= 0
|
||||
20
lib/cntbits.nim
Executable file
20
lib/cntbits.nim
Executable file
|
|
@ -0,0 +1,20 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
|
||||
proc population16(a: int): int {.inline.} =
|
||||
var x = a
|
||||
x = ((x and 0xAAAA) shr 1) + (x and 0x5555)
|
||||
x = ((x and 0xCCCC) shr 2) + (x and 0x3333)
|
||||
x = ((x and 0xF0F0) shr 4) + (x and 0x0F0F)
|
||||
x = ((x and 0xFF00) shr 8) + (x and 0x00FF)
|
||||
return x
|
||||
|
||||
proc countBits(n: int32): int =
|
||||
result = population16(n and 0xffff) + population16(n shr 16)
|
||||
108
lib/complex.nim
Executable file
108
lib/complex.nim
Executable file
|
|
@ -0,0 +1,108 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
|
||||
|
||||
## This module implements complex numbers.
|
||||
|
||||
{.push checks:off, line_dir:off, stack_trace:off, debugger:off.}
|
||||
# the user does not want to trace a part
|
||||
# of the standard library!
|
||||
|
||||
import
|
||||
math
|
||||
|
||||
type
|
||||
TComplex* = record ## a complex number, consisting of a real and an
|
||||
## imaginary part
|
||||
re*: float ## real part of the complex number
|
||||
im*: float ## imarginary part of the complex number
|
||||
|
||||
proc `==` *(x, y: TComplex): bool =
|
||||
## Compare two complex numbers `x` and `y` for equality.
|
||||
result = x.re == y.re and x.im == y.im
|
||||
|
||||
proc `+` *(x, y: TComplex): TComplex =
|
||||
## Add two complex numbers.
|
||||
result.re = x.re + y.re
|
||||
result.im = x.im + y.im
|
||||
|
||||
proc `-` *(x, y: TComplex): TComplex =
|
||||
## Subtract two complex numbers.
|
||||
result.re = x.re - y.re
|
||||
result.im = x.im - y.im
|
||||
|
||||
proc `-` *(z: TComplex): TComplex =
|
||||
## Unary minus for complex numbers.
|
||||
result.re = -z.re
|
||||
result.im = -z.im
|
||||
|
||||
proc `/` *(x, y: TComplex): TComplex =
|
||||
## Divide `x` by `y`.
|
||||
var
|
||||
r, den: float
|
||||
if abs(y.re) < abs(y.im):
|
||||
r = y.re / y.im
|
||||
den = y.im + r * y.re
|
||||
result.re = (x.re * r + x.im) / den
|
||||
result.im = (x.im * r - x.re) / den
|
||||
else:
|
||||
r = y.im / y.re
|
||||
den = y.re + r * y.im
|
||||
result.re = (x.re + r * x.im) / den
|
||||
result.im = (x.im - r * x.re) / den
|
||||
|
||||
proc `*` *(x, y: TComplex): TComplex =
|
||||
## Multiply `x` with `y`.
|
||||
result.re = x.re * y.re - x.im * y.im
|
||||
result.im = x.im * y.re + x.re * y.im
|
||||
|
||||
proc abs*(z: TComplex): float =
|
||||
## Return the distance from (0,0) to `z`.
|
||||
|
||||
# optimized by checking special cases (sqrt is expensive)
|
||||
var x, y, temp: float
|
||||
|
||||
x = abs(z.re)
|
||||
y = abs(z.im)
|
||||
if x == 0.0:
|
||||
result = y
|
||||
elif y == 0.0:
|
||||
result = x
|
||||
elif x > y:
|
||||
temp = y / x
|
||||
result = x * sqrt(1.0 + temp * temp)
|
||||
else:
|
||||
temp = x / y
|
||||
result = y * sqrt(1.0 + temp * temp)
|
||||
|
||||
proc sqrt*(z: TComplex): TComplex =
|
||||
## Square root for a complex number `z`.
|
||||
var x, y, w, r: float
|
||||
|
||||
if z.re == 0.0 and z.im == 0.0:
|
||||
result = z
|
||||
else:
|
||||
x = abs(z.re)
|
||||
y = abs(z.im)
|
||||
if x >= y:
|
||||
r = y / x
|
||||
w = sqrt(x) * sqrt(0.5 * (1.0 + sqrt(1.0 + r * r)))
|
||||
else:
|
||||
r = x / y
|
||||
w = sqrt(y) * sqrt(0.5 * (r + sqrt(1.0 + r * r)))
|
||||
if z.re >= 0.0:
|
||||
result.re = w
|
||||
result.im = z.im / (w * 2)
|
||||
else:
|
||||
if z.im >= 0.0: result.im = w
|
||||
else: result.im = -w
|
||||
result.re = z.im / (c.im + c.im)
|
||||
|
||||
{.pop.}
|
||||
29
lib/copying.txt
Executable file
29
lib/copying.txt
Executable file
|
|
@ -0,0 +1,29 @@
|
|||
=======================================================
|
||||
The Nimrod Runtime Library
|
||||
Copyright (C) 2004-2007 Andreas Rumpf
|
||||
=======================================================
|
||||
|
||||
This is the file copying.txt, it applies to the Nimrod Run-Time Library
|
||||
(lib) and base packages (base) distributed by members of the Nimrod
|
||||
Development Team.
|
||||
|
||||
The source code of the Nimrod Runtime Libraries and packages are
|
||||
distributed under the Library GNU General Public License
|
||||
(see the file lgpl.txt) with the following modification:
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent modules,
|
||||
and to copy and distribute the resulting executable under terms of your choice,
|
||||
provided that you also meet, for each linked independent module, the terms
|
||||
and conditions of the license of that module. An independent module is a module
|
||||
which is not derived from or based on this library. If you modify this
|
||||
library, you may extend this exception to your version of the library, but
|
||||
you are not obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version.
|
||||
|
||||
If you didn't receive a copy of the file lgpl.txt, contact:
|
||||
Free Software Foundation
|
||||
675 Mass Ave
|
||||
Cambridge, MA 02139
|
||||
USA
|
||||
499
lib/debugger.nim
Executable file
499
lib/debugger.nim
Executable file
|
|
@ -0,0 +1,499 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2008 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
# This file implements the embedded debugger that can be linked
|
||||
# with the application. We should not use dynamic memory here as that
|
||||
# would interfere with the GC and trigger ON/OFF errors if the
|
||||
# user program corrupts memory. Unfortunately, for dispaying
|
||||
# variables we use the system.repr() proc which uses Nimrod
|
||||
# strings and thus allocates memory from the heap. Pity, but
|
||||
# I do not want to implement repr() twice. We also cannot deactivate
|
||||
# the GC here as that might run out of memory too quickly...
|
||||
|
||||
type
|
||||
TDbgState = enum
|
||||
dbOff, # debugger is turned off
|
||||
dbStepInto, # debugger is in tracing mode
|
||||
dbStepOver,
|
||||
dbSkipCurrent,
|
||||
dbQuiting, # debugger wants to quit
|
||||
dbBreakpoints # debugger is only interested in breakpoints
|
||||
|
||||
TDbgBreakpoint = record
|
||||
low, high: int # range from low to high; if disabled
|
||||
# both low and high are set to their negative values
|
||||
# this makes the check faster and safes memory
|
||||
filename: string
|
||||
name: string # name of breakpoint
|
||||
|
||||
TVarSlot {.compilerproc.} = record # variable slots used for debugger:
|
||||
address: pointer
|
||||
typ: PNimType
|
||||
name: cstring # for globals this is "module.name"
|
||||
|
||||
PExtendedFrame = ptr TExtendedFrame
|
||||
TExtendedFrame = record # If the debugger is enabled the compiler provides
|
||||
# an extended frame. Of course only slots that are
|
||||
# needed are allocated and not 10_000, except for
|
||||
# the global data description.
|
||||
f: TFrame
|
||||
slots: array[0..10_000, TVarSlot]
|
||||
|
||||
var
|
||||
dbgInSignal: bool # wether the debugger is in the signal handler
|
||||
dbgIn: TFile # debugger input stream
|
||||
dbgUser: string = "s" # buffer for user input; first command is ``step_into``
|
||||
# needs to be global cause we store the last command
|
||||
# in it
|
||||
dbgState: TDbgState = dbStepInto # state of debugger
|
||||
dbgBP: array[0..127, TDbgBreakpoint] # breakpoints
|
||||
dbgBPlen: int = 0
|
||||
|
||||
dbgSkipToFrame: PFrame # frame to be skipped to
|
||||
|
||||
dbgGlobalData: TExtendedFrame # this reserves much space, but
|
||||
# for now it is the most practical way
|
||||
|
||||
maxDisplayRecDepth: int = 5 # do not display too much data!
|
||||
|
||||
proc findBreakpoint(name: string): int =
|
||||
# returns -1 if not found
|
||||
for i in countdown(dbgBPlen-1, 0):
|
||||
if name == dbgBP[i].name: return i
|
||||
return -1
|
||||
|
||||
proc ListBreakPoints() =
|
||||
write(stdout, "*** emdb| Breakpoints:\n")
|
||||
for i in 0 .. dbgBPlen-1:
|
||||
write(stdout, dbgBP[i].name & ": " & $abs(dbgBP[i].low) & ".." &
|
||||
$abs(dbgBP[i].high) & dbgBP[i].filename)
|
||||
if dbgBP[i].low < 0:
|
||||
write(stdout, " [disabled]\n")
|
||||
else:
|
||||
write(stdout, "\n")
|
||||
write(stdout, "***\n")
|
||||
|
||||
proc openAppend(filename: string): TFile =
|
||||
if openFile(result, filename, fmAppend):
|
||||
write(result, "----------------------------------------\n")
|
||||
|
||||
proc dbgRepr(p: pointer, typ: PNimType): string =
|
||||
var
|
||||
cl: TReprClosure
|
||||
initReprClosure(cl)
|
||||
cl.recDepth = maxDisplayRecDepth
|
||||
# locks for the GC turned out to be a bad idea...
|
||||
# inc(recGcLock)
|
||||
result = ""
|
||||
reprAux(result, p, typ, cl)
|
||||
# dec(recGcLock)
|
||||
deinitReprClosure(cl)
|
||||
|
||||
proc writeVariable(stream: TFile, slot: TVarSlot) =
|
||||
write(stream, slot.name)
|
||||
write(stream, " = ")
|
||||
writeln(stream, dbgRepr(slot.address, slot.typ))
|
||||
|
||||
proc ListFrame(stream: TFile, f: PExtendedFrame) =
|
||||
write(stream, "*** emdb| Frame (" & $f.f.len & " slots):\n")
|
||||
for i in 0 .. f.f.len-1:
|
||||
writeVariable(stream, f.slots[i])
|
||||
write(stream, "***\n")
|
||||
|
||||
proc ListVariables(stream: TFile, f: PExtendedFrame) =
|
||||
write(stream, "*** emdb| Frame (" & $f.f.len & " slots):\n")
|
||||
for i in 0 .. f.f.len-1:
|
||||
writeln(stream, f.slots[i].name)
|
||||
write(stream, "***\n")
|
||||
|
||||
proc debugOut(msg: cstring) =
|
||||
# the *** *** markers are for easy recognition of debugger
|
||||
# output for external frontends.
|
||||
write(stdout, "*** emdb| ")
|
||||
write(stdout, msg)
|
||||
write(stdout, "***\n")
|
||||
|
||||
proc dbgFatal(msg: cstring) =
|
||||
debugOut(msg)
|
||||
dbgAborting = True # the debugger wants to abort
|
||||
quit(1)
|
||||
|
||||
proc findVariable(frame: PExtendedFrame, varname: cstring): int =
|
||||
for i in 0 .. frame.f.len - 1:
|
||||
if c_strcmp(frame.slots[i].name, varname) == 0: return i
|
||||
return -1
|
||||
|
||||
proc dbgShowCurrentProc(dbgFramePointer: PFrame) =
|
||||
if dbgFramePointer != nil:
|
||||
write(stdout, "*** emdb| now in proc: ")
|
||||
write(stdout, dbgFramePointer.procname)
|
||||
write(stdout, " ***\n")
|
||||
else:
|
||||
write(stdout, "*** emdb| (procedure name not available) ***\n")
|
||||
|
||||
proc dbgShowExecutionPoint() =
|
||||
write(stdout, "*** emdb| " & $framePtr.filename & "(" & $framePtr.line &
|
||||
") " & $framePtr.procname & " ***\n")
|
||||
|
||||
when defined(windows) or defined(dos) or defined(os2):
|
||||
{.define: FileSystemCaseInsensitive.}
|
||||
|
||||
proc fileMatches(c, bp: cstring): bool =
|
||||
# bp = breakpoint filename
|
||||
# c = current filename
|
||||
# we consider it a match if bp is a suffix of c
|
||||
# and the character for the suffix does not exist or
|
||||
# is one of: \ / :
|
||||
# depending on the OS case does not matter!
|
||||
var blen: int = c_strlen(bp)
|
||||
var clen: int = c_strlen(c)
|
||||
if blen > clen: return false
|
||||
# check for \ / :
|
||||
if clen-blen-1 >= 0 and c[clen-blen-1] notin {'\\', '/', ':'}:
|
||||
return false
|
||||
var i = 0
|
||||
while i < blen:
|
||||
var x, y: char
|
||||
x = bp[i]
|
||||
y = c[i+clen-blen]
|
||||
when defined(FileSystemCaseInsensitive):
|
||||
if x >= 'A' and x <= 'Z': x = chr(ord(x) - ord('A') + ord('a'))
|
||||
if y >= 'A' and y <= 'Z': y = chr(ord(y) - ord('A') + ord('a'))
|
||||
if x != y: return false
|
||||
inc(i)
|
||||
return true
|
||||
|
||||
proc dbgBreakpointReached(line: int): int =
|
||||
for i in 0..dbgBPlen-1:
|
||||
if line >= dbgBP[i].low and line <= dbgBP[i].high and
|
||||
fileMatches(framePtr.filename, dbgBP[i].filename): return i
|
||||
return -1
|
||||
|
||||
proc scanAndAppendWord(src: string, a: var string, start: int): int =
|
||||
result = start
|
||||
# skip whitespace:
|
||||
while src[result] in {'\t', ' '}: inc(result)
|
||||
while True:
|
||||
case src[result]
|
||||
of 'a'..'z', '0'..'9': add(a, src[result])
|
||||
of '_': nil # just skip it
|
||||
of 'A'..'Z': add(a, chr(ord(src[result]) - ord('A') + ord('a')))
|
||||
else: break
|
||||
inc(result)
|
||||
|
||||
proc scanWord(src: string, a: var string, start: int): int =
|
||||
a = ""
|
||||
result = scanAndAppendWord(src, a, start)
|
||||
|
||||
proc scanFilename(src: string, a: var string, start: int): int =
|
||||
result = start
|
||||
a = ""
|
||||
# skip whitespace:
|
||||
while src[result] in {'\t', ' '}: inc(result)
|
||||
while src[result] notin {'\t', ' ', '\0'}:
|
||||
add(a, src[result])
|
||||
inc(result)
|
||||
|
||||
proc scanNumber(src: string, a: var int, start: int): int =
|
||||
result = start
|
||||
a = 0
|
||||
while src[result] in {'\t', ' '}: inc(result)
|
||||
while true:
|
||||
case src[result]
|
||||
of '0'..'9': a = a * 10 + ord(src[result]) - ord('0')
|
||||
of '_': nil # skip underscores (nice for long line numbers)
|
||||
else: break
|
||||
inc(result)
|
||||
|
||||
proc dbgHelp() =
|
||||
debugOut("""
|
||||
list of commands (see the manual for further help):
|
||||
GENERAL
|
||||
h, help display this help message
|
||||
q, quit quit the debugger and the program
|
||||
<ENTER> repeat the previous debugger command
|
||||
EXECUTING
|
||||
s, stepinto single step, stepping into routine calls
|
||||
n, stepover single step, without stepping into routine calls
|
||||
f, skipcurrent continue execution until the current routine finishes
|
||||
c, continue continue execution until the next breakpoint
|
||||
i, ignore continue execution, ignore all breakpoints
|
||||
BREAKPOINTS
|
||||
b, setbreak <name> [fromline [toline]] [file]
|
||||
set a new breakpoint named 'name' for line and file
|
||||
if line or file are omitted the current one is used
|
||||
breakpoints display the entire breakpoint list
|
||||
disable <name> disable a breakpoint
|
||||
enable <name> enable a breakpoint
|
||||
DATA DISPLAY
|
||||
e, eval <exp> evaluate the expression <exp>
|
||||
o, out <file> <exp> evaluate <exp> and write it to <file>
|
||||
w, where display the current execution point
|
||||
stackframe [file] display current stack frame [and write it to file]
|
||||
u, up go up in the call stack
|
||||
d, down go down in the call stack
|
||||
callstack display the entire call stack
|
||||
l, locals display available local variables
|
||||
g, globals display available global variables
|
||||
maxdisplay <integer> set the display's recursion maximum
|
||||
""")
|
||||
|
||||
proc InvalidCommand() =
|
||||
debugOut("[Warning] invalid command ignored (type 'h' for help) ")
|
||||
|
||||
proc hasExt(s: string): bool =
|
||||
# returns true if s has a filename extension
|
||||
for i in countdown(len(s)-1, 0):
|
||||
if s[i] == '.': return true
|
||||
return false
|
||||
|
||||
proc setBreakPoint(s: string, start: int) =
|
||||
var dbgTemp: string
|
||||
var i = scanWord(s, dbgTemp, start)
|
||||
if i <= start:
|
||||
InvalidCommand()
|
||||
return
|
||||
if dbgBPlen >= high(dbgBP):
|
||||
debugOut("[Warning] no breakpoint could be set; out of breakpoint space ")
|
||||
return
|
||||
var x = dbgBPlen
|
||||
inc(dbgBPlen)
|
||||
dbgBP[x].name = dbgTemp
|
||||
i = scanNumber(s, dbgBP[x].low, i)
|
||||
if dbgBP[x].low == 0:
|
||||
# set to current line:
|
||||
dbgBP[x].low = framePtr.line
|
||||
i = scanNumber(s, dbgBP[x].high, i)
|
||||
if dbgBP[x].high == 0: # set to low:
|
||||
dbgBP[x].high = dbgBP[x].low
|
||||
i = scanFilename(s, dbgTemp, i)
|
||||
if not (dbgTemp.len == 0):
|
||||
if not hasExt(dbgTemp): add(dbgTemp, ".nim")
|
||||
dbgBP[x].filename = dbgTemp
|
||||
else: # use current filename
|
||||
dbgBP[x].filename = $framePtr.filename
|
||||
# skip whitespace:
|
||||
while s[i] in {' ', '\t'}: inc(i)
|
||||
if s[i] != '\0':
|
||||
dec(dbgBPLen) # remove buggy breakpoint
|
||||
InvalidCommand()
|
||||
|
||||
proc BreakpointSetEnabled(s: string, start, enabled: int) =
|
||||
var dbgTemp: string
|
||||
var i = scanWord(s, dbgTemp, start)
|
||||
if i <= start:
|
||||
InvalidCommand()
|
||||
return
|
||||
var x = findBreakpoint(dbgTemp)
|
||||
if x < 0: debugOut("[Warning] breakpoint does not exist ")
|
||||
elif enabled * dbgBP[x].low < 0: # signs are different?
|
||||
dbgBP[x].low = -dbgBP[x].low
|
||||
dbgBP[x].high = -dbgBP[x].high
|
||||
|
||||
proc dbgEvaluate(stream: TFile, s: string, start: int,
|
||||
currFrame: PExtendedFrame) =
|
||||
var dbgTemp: string
|
||||
var i = scanWord(s, dbgTemp, start)
|
||||
while s[i] in {' ', '\t'}: inc(i)
|
||||
var f = currFrame
|
||||
if s[i] == '.':
|
||||
inc(i) # skip '.'
|
||||
add(dbgTemp, '.')
|
||||
i = scanAndAppendWord(s, dbgTemp, i)
|
||||
# search for global var:
|
||||
f = addr(dbgGlobalData)
|
||||
if s[i] != '\0':
|
||||
debugOut("[Warning] could not parse expr ")
|
||||
return
|
||||
var j = findVariable(f, dbgTemp)
|
||||
if j < 0:
|
||||
debugOut("[Warning] could not find variable ")
|
||||
return
|
||||
writeVariable(stream, f.slots[j])
|
||||
|
||||
proc dbgOut(s: string, start: int, currFrame: PExtendedFrame) =
|
||||
var dbgTemp: string
|
||||
var i = scanFilename(s, dbgTemp, start)
|
||||
if dbgTemp.len == 0:
|
||||
InvalidCommand()
|
||||
return
|
||||
var stream = openAppend(dbgTemp)
|
||||
if stream == nil:
|
||||
debugOut("[Warning] could not open or create file ")
|
||||
return
|
||||
dbgEvaluate(stream, s, i, currFrame)
|
||||
closeFile(stream)
|
||||
|
||||
proc dbgStackFrame(s: string, start: int, currFrame: PExtendedFrame) =
|
||||
var dbgTemp: string
|
||||
var i = scanFilename(s, dbgTemp, start)
|
||||
if dbgTemp.len == 0:
|
||||
# just write it to stdout:
|
||||
ListFrame(stdout, currFrame)
|
||||
else:
|
||||
var stream = openAppend(dbgTemp)
|
||||
if stream == nil:
|
||||
debugOut("[Warning] could not open or create file ")
|
||||
return
|
||||
ListFrame(stream, currFrame)
|
||||
closeFile(stream)
|
||||
|
||||
proc CommandPrompt() =
|
||||
# if we return from this routine, user code executes again
|
||||
var
|
||||
again: bool = True
|
||||
dbgFramePtr = framePtr # for going down and up the stack
|
||||
dbgDown: int = 0 # how often we did go down
|
||||
|
||||
while again:
|
||||
write(stdout, "*** emdb| >>")
|
||||
var tmp = readLine(stdin)
|
||||
if tmp.len > 0: dbgUser = tmp
|
||||
# now look what we have to do:
|
||||
var dbgTemp: string
|
||||
var i = scanWord(dbgUser, dbgTemp, 0)
|
||||
case dbgTemp
|
||||
of "": InvalidCommand()
|
||||
of "s", "stepinto":
|
||||
dbgState = dbStepInto
|
||||
again = false
|
||||
of "n", "stepover":
|
||||
dbgState = dbStepOver
|
||||
dbgSkipToFrame = framePtr
|
||||
again = false
|
||||
of "f", "skipcurrent":
|
||||
dbgState = dbSkipCurrent
|
||||
dbgSkipToFrame = framePtr.prev
|
||||
again = false
|
||||
of "c", "continue":
|
||||
dbgState = dbBreakpoints
|
||||
again = false
|
||||
of "i", "ignore":
|
||||
dbgState = dbOff
|
||||
again = false
|
||||
of "h", "help":
|
||||
dbgHelp()
|
||||
of "q", "quit":
|
||||
dbgState = dbQuiting
|
||||
dbgAborting = True
|
||||
again = false
|
||||
quit(1) # BUGFIX: quit with error code > 0
|
||||
of "e", "eval":
|
||||
dbgEvaluate(stdout, dbgUser, i, cast[PExtendedFrame](dbgFramePtr))
|
||||
of "o", "out":
|
||||
dbgOut(dbgUser, i, cast[PExtendedFrame](dbgFramePtr))
|
||||
of "stackframe":
|
||||
dbgStackFrame(dbgUser, i, cast[PExtendedFrame](dbgFramePtr))
|
||||
of "w", "where":
|
||||
dbgShowExecutionPoint()
|
||||
of "l", "locals":
|
||||
ListVariables(stdout, cast[PExtendedFrame](dbgFramePtr))
|
||||
of "g", "globals":
|
||||
ListVariables(stdout, addr(dbgGlobalData))
|
||||
of "u", "up":
|
||||
if dbgDown <= 0:
|
||||
debugOut("[Warning] cannot go up any further ")
|
||||
else:
|
||||
dbgFramePtr = framePtr
|
||||
for j in 0 .. dbgDown-2: # BUGFIX
|
||||
dbgFramePtr = dbgFramePtr.prev
|
||||
dec(dbgDown)
|
||||
dbgShowCurrentProc(dbgFramePtr)
|
||||
of "d", "down":
|
||||
if dbgFramePtr != nil:
|
||||
inc(dbgDown)
|
||||
dbgFramePtr = dbgFramePtr.prev
|
||||
dbgShowCurrentProc(dbgFramePtr)
|
||||
else:
|
||||
debugOut("[Warning] cannot go down any further ")
|
||||
of "callstack":
|
||||
WriteStackTrace()
|
||||
of "b", "setbreak":
|
||||
setBreakPoint(dbgUser, i)
|
||||
of "breakpoints":
|
||||
ListBreakPoints()
|
||||
of "disable":
|
||||
BreakpointSetEnabled(dbgUser, i, -1)
|
||||
of "enable":
|
||||
BreakpointSetEnabled(dbgUser, i, +1)
|
||||
of "maxdisplay":
|
||||
var parsed: int
|
||||
i = scanNumber(dbgUser, parsed, i)
|
||||
if dbgUser[i-1] in {'0'..'9'}:
|
||||
if parsed == 0: maxDisplayRecDepth = -1
|
||||
else: maxDisplayRecDepth = parsed
|
||||
else:
|
||||
InvalidCommand()
|
||||
else:
|
||||
InvalidCommand()
|
||||
|
||||
proc endbStep() =
|
||||
# we get into here if an unhandled exception has been raised
|
||||
# XXX: do not allow the user to run the program any further?
|
||||
# XXX: BUG: the frame is lost here!
|
||||
dbgShowExecutionPoint()
|
||||
CommandPrompt()
|
||||
|
||||
proc checkForBreakpoint() =
|
||||
var i = dbgBreakpointReached(framePtr.line)
|
||||
if i >= 0:
|
||||
write(stdout, "*** emdb| reached ")
|
||||
write(stdout, dbgBP[i].name)
|
||||
write(stdout, " in ")
|
||||
write(stdout, framePtr.filename)
|
||||
write(stdout, "(")
|
||||
write(stdout, framePtr.line)
|
||||
write(stdout, ") ")
|
||||
write(stdout, framePtr.procname)
|
||||
write(stdout, " ***\n")
|
||||
CommandPrompt()
|
||||
|
||||
# interface to the user program:
|
||||
|
||||
proc dbgRegisterBreakpoint(line: int,
|
||||
filename, name: cstring) {.compilerproc.} =
|
||||
var x = dbgBPlen
|
||||
inc(dbgBPlen)
|
||||
dbgBP[x].name = $name
|
||||
dbgBP[x].filename = $filename
|
||||
dbgBP[x].low = line
|
||||
dbgBP[x].high = line
|
||||
|
||||
proc dbgRegisterGlobal(name: cstring, address: pointer,
|
||||
typ: PNimType) {.compilerproc.} =
|
||||
var i = dbgGlobalData.f.len
|
||||
if i >= high(dbgGlobalData.slots):
|
||||
debugOut("[Warning] cannot register global ")
|
||||
return
|
||||
dbgGlobalData.slots[i].name = name
|
||||
dbgGlobalData.slots[i].typ = typ
|
||||
dbgGlobalData.slots[i].address = address
|
||||
inc(dbgGlobalData.f.len)
|
||||
|
||||
proc endb(line: int) {.compilerproc.} =
|
||||
# This proc is called before any Nimrod code line!
|
||||
# Thus, it must have as few parameters as possible to keep the
|
||||
# code size small!
|
||||
# check if we are at an enabled breakpoint or "in the mood"
|
||||
framePtr.line = line # this is done here for smaller code size!
|
||||
if dbgLineHook != nil: dbgLineHook()
|
||||
case dbgState
|
||||
of dbStepInto:
|
||||
# we really want the command prompt here:
|
||||
dbgShowExecutionPoint()
|
||||
CommandPrompt()
|
||||
of dbSkipCurrent, dbStepOver: # skip current routine
|
||||
if framePtr == dbgSkipToFrame:
|
||||
dbgShowExecutionPoint()
|
||||
CommandPrompt()
|
||||
else: # breakpoints are wanted though (I guess)
|
||||
checkForBreakpoint()
|
||||
of dbBreakpoints: # debugger is only interested in breakpoints
|
||||
checkForBreakpoint()
|
||||
else: nil
|
||||
5071
lib/dlmalloc.c
Executable file
5071
lib/dlmalloc.c
Executable file
File diff suppressed because it is too large
Load diff
1143
lib/dlmalloc.h
Executable file
1143
lib/dlmalloc.h
Executable file
File diff suppressed because it is too large
Load diff
143
lib/dyncalls.nim
Executable file
143
lib/dyncalls.nim
Executable file
|
|
@ -0,0 +1,143 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
|
||||
#
|
||||
# This file implements the ability to call native procs from libraries.
|
||||
# It is not possible to do this in a platform independant way, unfortunately.
|
||||
# However, the interface has been designed to take platform differences into
|
||||
# account and been ported to all major platforms.
|
||||
#
|
||||
# interface
|
||||
|
||||
type
|
||||
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
|
||||
TLibHandle = pointer # private type
|
||||
TProcAddr = pointer # libary loading and loading of procs:
|
||||
|
||||
const
|
||||
NilLibHandle: TLibHandle = nil
|
||||
|
||||
proc nimLoadLibrary(path: string): TLibHandle {.compilerproc.}
|
||||
proc nimUnloadLibrary(lib: TLibHandle) {.compilerproc.}
|
||||
proc nimGetProcAddr(lib: TLibHandle, name: cstring): TProcAddr {.compilerproc.}
|
||||
|
||||
#implementation
|
||||
|
||||
# this code was inspired from Lua's source code:
|
||||
# Lua - An Extensible Extension Language
|
||||
# Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil
|
||||
# http://www.lua.org
|
||||
# mailto:info@lua.org
|
||||
|
||||
when defined(USE_DLOPEN):
|
||||
#
|
||||
# =========================================================================
|
||||
# This is an implementation based on the dlfcn interface.
|
||||
# The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
|
||||
# NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
|
||||
# as an emulation layer on top of native functions.
|
||||
# =========================================================================
|
||||
#
|
||||
|
||||
# c stuff:
|
||||
var
|
||||
RTLD_NOW {.importc: "RTLD_NOW", header: "<dlfcn.h>".}: int
|
||||
|
||||
proc dlclose(lib: TLibHandle) {.importc, header: "<dlfcn.h>".}
|
||||
proc dlopen(path: CString, mode: int): TLibHandle {.
|
||||
importc, header: "<dlfcn.h>".}
|
||||
proc dlsym(lib: TLibHandle, name: cstring): TProcAddr {.
|
||||
importc, header: "<dlfcn.h>".}
|
||||
|
||||
proc nimUnloadLibrary(lib: TLibHandle) =
|
||||
dlclose(lib)
|
||||
|
||||
proc nimLoadLibrary(path: string): TLibHandle =
|
||||
result = dlopen(path, RTLD_NOW)
|
||||
if result == nil:
|
||||
raise newException(EInvalidLibrary, "could not load: " & path)
|
||||
|
||||
proc nimGetProcAddr(lib: TLibHandle, name: cstring): TProcAddr =
|
||||
result = dlsym(lib, name)
|
||||
|
||||
elif defined(USE_DLL):
|
||||
#
|
||||
# =======================================================================
|
||||
# Native Windows Implementation
|
||||
# =======================================================================
|
||||
#
|
||||
type
|
||||
THINSTANCE {.importc: "HINSTANCE".} = pointer
|
||||
|
||||
proc FreeLibrary(lib: THINSTANCE) {.importc, header: "<windows.h>", stdcall.}
|
||||
proc winLoadLibrary(path: cstring): THINSTANCE {.
|
||||
importc: "LoadLibraryA", header: "<windows.h>", stdcall.}
|
||||
proc GetProcAddress(lib: THINSTANCE, name: cstring): TProcAddr {.
|
||||
importc: "GetProcAddress", header: "<windows.h>", stdcall.}
|
||||
|
||||
proc nimUnloadLibrary(lib: TLibHandle) =
|
||||
FreeLibrary(cast[THINSTANCE](lib))
|
||||
|
||||
proc nimLoadLibrary(path: string): TLibHandle =
|
||||
result = cast[TLibHandle](winLoadLibrary(path))
|
||||
if result == nil:
|
||||
raise newException(EInvalidLibrary, "could not load: " & path)
|
||||
|
||||
proc nimGetProcAddr(lib: TLibHandle, name: cstring): TProcAddr =
|
||||
result = GetProcAddress(cast[THINSTANCE](lib), name)
|
||||
|
||||
elif defined(USE_DYLD):
|
||||
#
|
||||
# =======================================================================
|
||||
# Native Mac OS X / Darwin Implementation
|
||||
# =======================================================================
|
||||
#
|
||||
{.error: "no implementation for dyncalls yet".}
|
||||
|
||||
proc nimUnloadLibrary(lib: TLibHandle) =
|
||||
NSUnLinkModule(NSModule(lib), NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES)
|
||||
|
||||
var
|
||||
dyld_present {.importc: "_dyld_present", header: "<dyld.h>".}: int
|
||||
|
||||
proc nimLoadLibrary(path: string): TLibHandle =
|
||||
var
|
||||
img: NSObjectFileImage
|
||||
ret: NSObjectFileImageReturnCode
|
||||
modul: NSModule
|
||||
# this would be a rare case, but prevents crashing if it happens
|
||||
result = nil
|
||||
if dyld_present != 0:
|
||||
ret = NSCreateObjectFileImageFromFile(path, addr(img))
|
||||
if ret == NSObjectFileImageSuccess:
|
||||
modul = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE or
|
||||
NSLINKMODULE_OPTION_RETURN_ON_ERROR)
|
||||
NSDestroyObjectFileImage(img)
|
||||
result = TLibHandle(modul)
|
||||
if result == nil:
|
||||
raise newException(EInvalidLibrary, "could not load: " & path)
|
||||
|
||||
proc nimGetProcAddr(lib: TLibHandle, cname: string): TProcAddr =
|
||||
var
|
||||
nss: NSSymbol
|
||||
nss = NSLookupSymbolInModule(NSModule(lib), name)
|
||||
result = TProcAddr(NSAddressOfSymbol(nss))
|
||||
|
||||
else: # workaround a newly introduced bug :-(
|
||||
{.error: "no implementation for dyncalls".}
|
||||
251
lib/excpt.nim
Executable file
251
lib/excpt.nim
Executable file
|
|
@ -0,0 +1,251 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
|
||||
# Exception handling code. This is difficult because it has
|
||||
# to work if there is no more memory. Thus we have to use
|
||||
# a static string. Do not use ``sprintf``, etc. as they are
|
||||
# unsafe!
|
||||
|
||||
when not defined(windows) or not defined(guiapp):
|
||||
proc writeToStdErr(msg: CString) = write(stdout, msg)
|
||||
|
||||
else:
|
||||
proc MessageBoxA(hWnd: cint, lpText, lpCaption: cstring, uType: int): int32 {.
|
||||
header: "<windows.h>", nodecl.}
|
||||
|
||||
proc writeToStdErr(msg: CString) =
|
||||
discard MessageBoxA(0, msg, nil, 0)
|
||||
|
||||
proc raiseException(e: ref E_Base, ename: CString) {.compilerproc.}
|
||||
proc reraiseException() {.compilerproc.}
|
||||
|
||||
proc registerSignalHandler() {.compilerproc.}
|
||||
|
||||
proc chckIndx(i, a, b: int): int {.inline, compilerproc.}
|
||||
proc chckRange(i, a, b: int): int {.inline, compilerproc.}
|
||||
proc chckRangeF(x, a, b: float): float {.inline, compilerproc.}
|
||||
proc chckNil(p: pointer) {.inline, compilerproc.}
|
||||
|
||||
type
|
||||
PSafePoint = ptr TSafePoint
|
||||
TSafePoint {.compilerproc.} = record
|
||||
prev: PSafePoint # points to next safe point ON THE STACK
|
||||
exc: ref E_Base
|
||||
status: int
|
||||
context: C_JmpBuf
|
||||
|
||||
var
|
||||
excHandler {.compilerproc, volatile.}: PSafePoint = nil
|
||||
# list of exception handlers
|
||||
# a global variable for the root of all try blocks
|
||||
|
||||
proc reraiseException() =
|
||||
if excHandler != nil:
|
||||
raise newException(ENoExceptionToReraise, "no exception to reraise")
|
||||
else:
|
||||
c_longjmp(excHandler.context, 1)
|
||||
|
||||
type
|
||||
PFrame = ptr TFrame
|
||||
TFrame {.importc, nodecl.} = record
|
||||
prev: PFrame
|
||||
procname: CString
|
||||
line: int # current line number
|
||||
filename: CString
|
||||
len: int # length of slots (when not debugging always zero)
|
||||
|
||||
TTempFrame = record # used for recursion elimination in WriteStackTrace
|
||||
procname: CString
|
||||
line: int
|
||||
|
||||
var
|
||||
buf: string # cannot be allocated on the stack!
|
||||
assertBuf: string # we need a different buffer for
|
||||
# assert, as it raises an exception and
|
||||
# exception handler needs the buffer too
|
||||
|
||||
framePtr {.exportc, volatile.}: PFrame
|
||||
|
||||
tempFrames: array [0..255, TTempFrame] # cannot be allocated
|
||||
# on the stack!
|
||||
|
||||
proc auxWriteStackTrace(f: PFrame, s: var string) =
|
||||
var
|
||||
it = f
|
||||
i = 0
|
||||
total = 0
|
||||
while it != nil and i <= high(tempFrames):
|
||||
tempFrames[i].procname = it.procname
|
||||
tempFrames[i].line = it.line
|
||||
inc(i)
|
||||
inc(total)
|
||||
it = it.prev
|
||||
while it != nil:
|
||||
inc(total)
|
||||
it = it.prev
|
||||
# if the buffer overflowed print '...':
|
||||
if total != i:
|
||||
add(s, "(")
|
||||
add(s, $(total-i))
|
||||
add(s, " calls omitted) ...\n")
|
||||
for j in countdown(i-1, 0):
|
||||
add(s, $tempFrames[j].procname)
|
||||
if tempFrames[j].line > 0:
|
||||
add(s, ", line: ")
|
||||
add(s, $tempFrames[j].line)
|
||||
add(s, "\n")
|
||||
|
||||
proc rawWriteStackTrace(s: var string) =
|
||||
if framePtr == nil:
|
||||
add(s, "No stack traceback available\n")
|
||||
else:
|
||||
add(s, "Traceback (most recent call last)\n")
|
||||
auxWriteStackTrace(framePtr, s)
|
||||
|
||||
proc quitOrDebug() {.inline.} =
|
||||
when not defined(emdb):
|
||||
quit(1)
|
||||
else:
|
||||
emdbStep() # call the debugger
|
||||
|
||||
proc raiseException(e: ref E_Base, ename: CString) =
|
||||
GC_disable() # a bad thing is an error in the GC while raising an exception
|
||||
e.name = ename
|
||||
if excHandler != nil:
|
||||
excHandler.exc = e
|
||||
c_longjmp(excHandler.context, 1)
|
||||
else:
|
||||
if cast[pointer](buf) != nil:
|
||||
setLen(buf, 0)
|
||||
rawWriteStackTrace(buf)
|
||||
if e.msg != nil and e.msg[0] != '\0':
|
||||
add(buf, "Error: unhandled exception: ")
|
||||
add(buf, $e.msg)
|
||||
else:
|
||||
add(buf, "Error: unhandled exception")
|
||||
add(buf, " [")
|
||||
add(buf, $ename)
|
||||
add(buf, "]\n")
|
||||
writeToStdErr(buf)
|
||||
else:
|
||||
writeToStdErr("*** FATAL ERROR *** ")
|
||||
writeToStdErr(ename)
|
||||
writeToStdErr("\n")
|
||||
quitOrDebug()
|
||||
GC_enable()
|
||||
|
||||
var
|
||||
gAssertionFailed: ref EAssertionFailed
|
||||
|
||||
proc internalAssert(file: cstring, line: int, cond: bool) {.compilerproc.} =
|
||||
if not cond:
|
||||
GC_disable() # BUGFIX: `$` allocates a new string object!
|
||||
if cast[pointer](assertBuf) != nil: # BUGFIX: when debugging the GC, assertBuf may be nil
|
||||
setLen(assertBuf, 0)
|
||||
add(assertBuf, "[Assertion failure] file: ")
|
||||
add(assertBuf, file)
|
||||
add(assertBuf, " line: ")
|
||||
add(assertBuf, $line)
|
||||
add(assertBuf, "\n")
|
||||
gAssertionFailed.msg = assertBuf
|
||||
GC_enable()
|
||||
raise gAssertionFailed # newException(EAssertionFailed, assertBuf)
|
||||
|
||||
proc WriteStackTrace() =
|
||||
var
|
||||
s: string = ""
|
||||
rawWriteStackTrace(s)
|
||||
writeToStdErr(s)
|
||||
|
||||
var
|
||||
dbgAborting: bool # whether the debugger wants to abort
|
||||
|
||||
proc signalHandler(sig: cint) {.exportc: "signalHandler", noconv.} =
|
||||
# print stack trace and quit
|
||||
var
|
||||
s = int(sig)
|
||||
setLen(buf, 0)
|
||||
rawWriteStackTrace(buf)
|
||||
|
||||
if s == SIGINT: add(buf, "SIGINT: Interrupted by Ctrl-C.\n")
|
||||
elif s == SIGSEGV: add(buf, "SIGSEGV: Illegal storage access.\n")
|
||||
elif s == SIGABRT:
|
||||
if dbgAborting: return # the debugger wants to abort
|
||||
add(buf, "SIGABRT: Abnormal termination.\n")
|
||||
elif s == SIGFPE: add(buf, "SIGFPE: Arithmetic error.\n")
|
||||
elif s == SIGILL: add(buf, "SIGILL: Illegal operation.\n")
|
||||
elif s == SIGBUS: add(buf, "SIGBUS: Illegal storage access.\n")
|
||||
else: add(buf, "unknown signal\n")
|
||||
writeToStdErr(buf)
|
||||
dbgAborting = True # play safe here...
|
||||
quit(1) # always quit when SIGABRT
|
||||
|
||||
proc registerSignalHandler() =
|
||||
c_signal(SIGINT, signalHandler)
|
||||
c_signal(SIGSEGV, signalHandler)
|
||||
c_signal(SIGABRT, signalHandler)
|
||||
c_signal(SIGFPE, signalHandler)
|
||||
c_signal(SIGILL, signalHandler)
|
||||
c_signal(SIGBUS, signalHandler)
|
||||
|
||||
registerSignalHandler() # call it in initialization section
|
||||
# for easier debugging of the GC, this memory is only allocated after the
|
||||
# signal handlers have been registered
|
||||
new(gAssertionFailed)
|
||||
buf = newString(2048)
|
||||
assertBuf = newString(2048)
|
||||
setLen(buf, 0)
|
||||
setLen(assertBuf, 0)
|
||||
|
||||
proc raiseRangeError() {.compilerproc, noreturn.} =
|
||||
raise newException(EOutOfRange, "value out of range")
|
||||
|
||||
proc raiseIndexError() {.compilerproc, noreturn.} =
|
||||
raise newException(EInvalidIndex, "index out of bounds")
|
||||
|
||||
proc chckIndx(i, a, b: int): int =
|
||||
if i >= a and i <= b:
|
||||
return i
|
||||
else:
|
||||
raiseIndexError()
|
||||
|
||||
proc chckRange(i, a, b: int): int =
|
||||
if i >= a and i <= b:
|
||||
return i
|
||||
else:
|
||||
raiseRangeError()
|
||||
|
||||
proc chckRange64(i, a, b: int64): int64 {.compilerproc.} =
|
||||
if i >= a and i <= b:
|
||||
return i
|
||||
else:
|
||||
raiseRangeError()
|
||||
|
||||
proc chckRangeF(x, a, b: float): float =
|
||||
if x >= a and x <= b:
|
||||
return x
|
||||
else:
|
||||
raiseRangeError()
|
||||
|
||||
proc chckNil(p: pointer) =
|
||||
if p == nil: c_raise(SIGSEGV)
|
||||
|
||||
proc chckObj(obj, subclass: PNimType) {.compilerproc.} =
|
||||
# checks if obj is of type subclass:
|
||||
var x = obj
|
||||
if x == subclass: return # optimized fast path
|
||||
while x != subclass:
|
||||
if x == nil:
|
||||
raise newException(EInvalidObjectConversion, "invalid object conversion")
|
||||
x = x.base
|
||||
|
||||
proc chckObjAsgn(a, b: PNimType) {.compilerproc, inline.} =
|
||||
if a != b:
|
||||
raise newException(EInvalidObjectAssignment, "invalid object assignment")
|
||||
897
lib/gc.nim
Executable file
897
lib/gc.nim
Executable file
|
|
@ -0,0 +1,897 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
|
||||
# Garbage Collector
|
||||
|
||||
# For a description of the algorithms used here see:
|
||||
# intern.html
|
||||
|
||||
#{.define: debugGC.} # we wish to debug the GC...
|
||||
|
||||
#when defined(debugGC):
|
||||
# {.define: logGC.} # define if the GC should log some of its activities
|
||||
|
||||
{.define: cycleGC.}
|
||||
|
||||
# Guess the page size of the system; if it is the
|
||||
# wrong value, performance may be worse (this is not
|
||||
# for sure though), but GC still works; must be a power of two!
|
||||
const
|
||||
PageSize = 1024 * sizeof(int)
|
||||
RC_Increase = 7 * PageSize # is an additive increase
|
||||
CycleIncrease = 2 # is a multiplicative increase
|
||||
|
||||
when defined(debugGC):
|
||||
const InitialThreshold = 64*1024
|
||||
const stressGC = True # GC is debugged; no need to stress it
|
||||
else:
|
||||
const stressGC = False
|
||||
const InitialThreshold = RC_Increase
|
||||
# this may need benchmarking...
|
||||
|
||||
# things the System module thinks should be available:
|
||||
when defined(useDL) or defined(nativeDL):
|
||||
type
|
||||
TMallocInfo {.importc: "struct mallinfo", nodecl.} = record
|
||||
arena: cint # non-mmapped space allocated from system
|
||||
ordblks: cint # number of free chunks
|
||||
smblks: cint # number of fastbin blocks
|
||||
hblks: cint # number of mmapped regions
|
||||
hblkhd: cint # space in mmapped regions
|
||||
usmblks: cint # maximum total allocated space
|
||||
fsmblks: cint # space available in freed fastbin blocks
|
||||
uordblks: cint # total allocated space
|
||||
fordblks: cint # total free space
|
||||
keepcost: cint # top-most, releasable (via malloc_trim) space
|
||||
|
||||
when defined(useDL):
|
||||
proc mallinfo: TMallocInfo {.importc: "dlmallinfo", nodecl.}
|
||||
elif defined(nativeDL):
|
||||
proc mallinfo: TMallocInfo {.importc: "mallinfo", nodecl.}
|
||||
|
||||
when defined(useDL) or defined(nativeDL):
|
||||
proc getOccupiedMem(): int = return mallinfo().uordblks
|
||||
proc getFreeMem(): int = return mallinfo().fordblks
|
||||
proc getTotalMem(): int =
|
||||
var m = mallinfo()
|
||||
return int(m.hblkhd) + int(m.arena)
|
||||
else: # not available:
|
||||
proc getOccupiedMem(): int = return -1
|
||||
proc getFreeMem(): int = return -1
|
||||
proc getTotalMem(): int = return -1
|
||||
|
||||
var
|
||||
rcThreshold: int = InitialThreshold
|
||||
cycleThreshold: int = InitialThreshold
|
||||
|
||||
memUsed: int = 0 # we have to keep track how much we have allocated
|
||||
|
||||
recGcLock: int = 0
|
||||
# we use a lock to prevend the garbage collector to
|
||||
# be triggered in a finalizer; the collector should not call
|
||||
# itself this way! Thus every object allocated by a finalizer
|
||||
# will not trigger a garbage collection. This is wasteful but safe.
|
||||
# This is a lock against recursive garbage collection, not a lock for
|
||||
# threads!
|
||||
|
||||
when defined(useDL) and not defined(nativeDL):
|
||||
{.compile: "dlmalloc.c".}
|
||||
|
||||
type
|
||||
TFinalizer {.compilerproc.} = proc (self: pointer)
|
||||
# A ref type can have a finalizer that is called before the object's
|
||||
# storage is freed.
|
||||
PPointer = ptr pointer
|
||||
|
||||
proc asgnRef(dest: ppointer, src: pointer) {.compilerproc.}
|
||||
proc unsureAsgnRef(dest: ppointer, src: pointer) {.compilerproc.}
|
||||
# unsureAsgnRef updates the reference counters only if dest is not on the
|
||||
# stack. It is used by the code generator if it cannot decide wether a
|
||||
# reference is in the stack or not (this can happen for out/var parameters).
|
||||
proc growObj(old: pointer, newsize: int): pointer {.compilerproc.}
|
||||
proc newObj(typ: PNimType, size: int): pointer {.compilerproc.}
|
||||
proc newSeq(typ: PNimType, len: int): pointer {.compilerproc.}
|
||||
|
||||
# implementation:
|
||||
|
||||
when defined(useDL):
|
||||
proc nimSize(p: pointer): int {.
|
||||
importc: "dlmalloc_usable_size", header: "dlmalloc.h".}
|
||||
elif defined(nativeDL):
|
||||
proc nimSize(p: pointer): int {.
|
||||
importc: "malloc_usable_size", header: "<malloc.h>".}
|
||||
|
||||
type
|
||||
TWalkOp = enum
|
||||
waNone, waRelease, waZctDecRef, waCycleDecRef, waCycleIncRef, waDebugIncRef
|
||||
|
||||
TCollectorData = int
|
||||
TCell = record
|
||||
refcount: TCollectorData # the refcount and bit flags
|
||||
typ: PNimType
|
||||
stackcount: int # stack counter for debugging
|
||||
drefc: int # real reference counter for debugging
|
||||
|
||||
PCell = ptr TCell
|
||||
|
||||
var
|
||||
gOutOfMem: ref EOutOfMemory
|
||||
|
||||
proc raiseOutOfMem() {.noreturn.} =
|
||||
if gOutOfMem == nil:
|
||||
writeToStdErr("out of memory; cannot even throw an exception")
|
||||
quit(1)
|
||||
gOutOfMem.msg = "out of memory"
|
||||
raise gOutOfMem
|
||||
|
||||
proc cellToUsr(cell: PCell): pointer {.inline.} =
|
||||
# convert object (=pointer to refcount) to pointer to userdata
|
||||
result = cast[pointer](cast[TAddress](cell)+%TAddress(sizeof(TCell)))
|
||||
|
||||
proc usrToCell(usr: pointer): PCell {.inline.} =
|
||||
# convert pointer to userdata to object (=pointer to refcount)
|
||||
result = cast[PCell](cast[TAddress](usr)-%TAddress(sizeof(TCell)))
|
||||
|
||||
proc extGetCellType(c: pointer): PNimType {.compilerproc.} =
|
||||
# used for code generation concerning debugging
|
||||
result = usrToCell(c).typ
|
||||
|
||||
proc internRefcount(p: pointer): int {.exportc: "getRefcount".} =
|
||||
result = int(usrToCell(p).refcount)
|
||||
|
||||
proc gcAlloc(size: int): pointer =
|
||||
result = alloc0(size)
|
||||
if result == nil: raiseOutOfMem()
|
||||
|
||||
proc GC_disable() = inc(recGcLock)
|
||||
proc GC_enable() =
|
||||
if recGcLock > 0: dec(recGcLock)
|
||||
|
||||
proc GC_setStrategy(strategy: TGC_Strategy) =
|
||||
case strategy
|
||||
of gcThroughput: nil
|
||||
of gcResponsiveness: nil
|
||||
of gcOptimizeSpace: nil
|
||||
of gcOptimizeTime: nil
|
||||
|
||||
proc GC_enableMarkAndSweep() =
|
||||
cycleThreshold = InitialThreshold
|
||||
|
||||
proc GC_disableMarkAndSweep() =
|
||||
cycleThreshold = high(cycleThreshold)-1
|
||||
# set to the max value to suppress the cycle detector
|
||||
|
||||
proc nextTry(h, maxHash: int): int {.inline.} =
|
||||
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
|
||||
# random-number generation for proof).
|
||||
|
||||
# ------------------ Zero count table (ZCT) and any table (AT) -------------
|
||||
|
||||
# these values are for DL-malloc known for sure (and other allocators
|
||||
# can only be worse):
|
||||
when defined(useDL) or not defined(bcc):
|
||||
const MemAlignment = 8 # minimal memory block that can be allocated
|
||||
else:
|
||||
const MemAlignment = 4 # Borland's memory manager is terrible!
|
||||
|
||||
const
|
||||
BitsPerUnit = sizeof(int)*8
|
||||
# a "unit" is a word, i.e. 4 bytes
|
||||
# on a 32 bit system; I do not use the term "word" because under 32-bit
|
||||
# Windows it is sometimes only 16 bits
|
||||
|
||||
BitsPerPage = PageSize div MemAlignment
|
||||
UnitsPerPage = BitsPerPage div BitsPerUnit
|
||||
# how many units do we need to describe a page:
|
||||
# on 32 bit systems this is only 16 (!)
|
||||
|
||||
# this that has to equals zero, otherwise we have to round up UnitsPerPage:
|
||||
when BitsPerPage mod BitsPerUnit != 0:
|
||||
{.error: "(BitsPerPage mod BitsPerUnit) should be zero!".}
|
||||
|
||||
# ------------------- cell set handling ------------------------------
|
||||
# A cellset consists of a hash table of page descriptors. A page
|
||||
# descriptor has a bit for
|
||||
# every Memalignment'th byte in the page.
|
||||
# However, only bits corresponding to addresses that start memory blocks
|
||||
# are set.
|
||||
# Page descriptors are also linked to a list; the list
|
||||
# is used for easy traversing of all page descriptors; this allows a
|
||||
# fast iterator.
|
||||
# We use a specialized hashing scheme; the formula is :
|
||||
# hash = Page bitand max
|
||||
# We use linear probing with the formular: (5*h)+1
|
||||
# Thus we likely get no collisions at all if the pages are given us
|
||||
# sequentially by the operating system!
|
||||
type
|
||||
PPageDesc = ptr TPageDesc
|
||||
|
||||
TBitIndex = range[0..UnitsPerPage-1]
|
||||
|
||||
TPageDesc = record
|
||||
next: PPageDesc # all nodes are connected with this pointer
|
||||
key: TAddress # start address at bit 0
|
||||
bits: array[TBitIndex, int] # a bit vector
|
||||
|
||||
PPageDescArray = ptr array[0..1000_000, PPageDesc]
|
||||
TCellSet = record
|
||||
counter, max: int
|
||||
head: PPageDesc
|
||||
data: PPageDescArray
|
||||
|
||||
const
|
||||
InitCellSetSize = 1024 # must be a power of two!
|
||||
|
||||
proc CellSetInit(s: var TCellSet) =
|
||||
s.data = cast[PPageDescArray](gcAlloc(InitCellSetSize * sizeof(PPageDesc)))
|
||||
s.max = InitCellSetSize-1
|
||||
s.counter = 0
|
||||
s.head = nil
|
||||
|
||||
proc CellSetDeinit(s: var TCellSet) =
|
||||
var it = s.head
|
||||
while it != nil:
|
||||
var n = it.next
|
||||
dealloc(it)
|
||||
it = n
|
||||
s.head = nil # play it safe here
|
||||
dealloc(s.data)
|
||||
s.data = nil
|
||||
s.counter = 0
|
||||
|
||||
proc CellSetGet(t: TCellSet, key: TAddress): PPageDesc =
|
||||
var h = cast[int](key) and t.max
|
||||
while t.data[h] != nil:
|
||||
if t.data[h].key == key: return t.data[h]
|
||||
h = nextTry(h, t.max)
|
||||
return nil
|
||||
|
||||
proc CellSetRawInsert(t: TCellSet, data: PPageDescArray,
|
||||
desc: PPageDesc) =
|
||||
var h = cast[int](desc.key) and t.max
|
||||
while data[h] != nil:
|
||||
assert(data[h] != desc)
|
||||
h = nextTry(h, t.max)
|
||||
assert(data[h] == nil)
|
||||
data[h] = desc
|
||||
|
||||
proc CellSetEnlarge(t: var TCellSet) =
|
||||
var
|
||||
n: PPageDescArray
|
||||
oldMax = t.max
|
||||
t.max = ((t.max+1)*2)-1
|
||||
n = cast[PPageDescArray](gcAlloc((t.max + 1) * sizeof(PPageDesc)))
|
||||
for i in 0 .. oldmax:
|
||||
if t.data[i] != nil:
|
||||
CellSetRawInsert(t, n, t.data[i])
|
||||
dealloc(t.data)
|
||||
t.data = n
|
||||
|
||||
proc CellSetPut(t: var TCellSet, key: TAddress): PPageDesc =
|
||||
var h = cast[int](key) and t.max
|
||||
while true:
|
||||
var x = t.data[h]
|
||||
if x == nil: break
|
||||
if x.key == key: return x
|
||||
h = nextTry(h, t.max)
|
||||
|
||||
if (t.max+1) * 2 < t.counter * 3: CellSetEnlarge(t)
|
||||
inc(t.counter)
|
||||
h = cast[int](key) and t.max
|
||||
while t.data[h] != nil: h = nextTry(h, t.max)
|
||||
assert(t.data[h] == nil)
|
||||
# the new page descriptor goes into result
|
||||
result = cast[PPageDesc](gcAlloc(sizeof(TPageDesc)))
|
||||
result.next = t.head
|
||||
result.key = key
|
||||
t.head = result
|
||||
t.data[h] = result
|
||||
|
||||
# ---------- slightly higher level procs ----------------------------------
|
||||
|
||||
proc in_Operator(s: TCellSet, cell: PCell): bool =
|
||||
var
|
||||
u: TAddress
|
||||
t: PPageDesc
|
||||
u = cast[TAddress](cell)
|
||||
t = CellSetGet(s, u /% PageSize)
|
||||
if t != nil:
|
||||
u = (u %% PageSize) /% MemAlignment
|
||||
result = (t.bits[u /% BitsPerUnit] and (1 shl (u %% BitsPerUnit))) != 0
|
||||
else:
|
||||
result = false
|
||||
|
||||
proc incl(s: var TCellSet, cell: PCell) =
|
||||
var
|
||||
u: TAddress
|
||||
t: PPageDesc
|
||||
u = cast[TAddress](cell)
|
||||
t = CellSetPut(s, u /% PageSize)
|
||||
u = (u %% PageSize) /% MemAlignment
|
||||
t.bits[u /% BitsPerUnit] = t.bits[u /% BitsPerUnit] or
|
||||
(1 shl (u %% BitsPerUnit))
|
||||
|
||||
proc excl(s: var TCellSet, cell: PCell) =
|
||||
var
|
||||
u: TAddress
|
||||
t: PPageDesc
|
||||
u = cast[TAddress](cell)
|
||||
t = CellSetGet(s, u /% PageSize)
|
||||
if t != nil:
|
||||
u = (u %% PageSize) /% MemAlignment
|
||||
t.bits[u /% BitsPerUnit] = (t.bits[u /% BitsPerUnit] and
|
||||
not (1 shl (u %% BitsPerUnit)))
|
||||
|
||||
iterator elements(t: TCellSet): PCell {.inline.} =
|
||||
# while traversing it is forbidden to add pointers to the tree!
|
||||
var r = t.head
|
||||
while r != nil:
|
||||
var i = 0
|
||||
while i <= high(r.bits):
|
||||
var w = r.bits[i] # taking a copy of r.bits[i] here is correct, because
|
||||
# modifying operations are not allowed during traversation
|
||||
var j = 0
|
||||
while w != 0: # test all remaining bits for zero
|
||||
if (w and 1) != 0: # the bit is set!
|
||||
yield cast[PCell]((r.key *% PageSize) +%
|
||||
(i*%BitsPerUnit+%j) *% MemAlignment)
|
||||
inc(j)
|
||||
w = w shr 1
|
||||
inc(i)
|
||||
r = r.next
|
||||
|
||||
# --------------- end of Cellset routines -------------------------------------
|
||||
|
||||
proc testPageDescs() =
|
||||
var root: TCellSet
|
||||
CellSetInit(root)
|
||||
var u = 10_000
|
||||
while u <= 20_000:
|
||||
incl(root, cast[PCell](u))
|
||||
inc(u, 8)
|
||||
for cell in elements(root):
|
||||
c_fprintf(c_stdout, "%ld\n", cast[int](cell))
|
||||
|
||||
# testPageDescs()
|
||||
|
||||
when defined(debugGC):
|
||||
proc writeCell(msg: CString, c: PCell) =
|
||||
c_fprintf(c_stdout, "%s: %p\n", msg, c)
|
||||
proc writePtr(msg: CString, p: Pointer) =
|
||||
c_fprintf(c_stdout, "%s: %p\n", msg, p)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
type
|
||||
PStackCells = ptr array[0..1000_0000, PCell]
|
||||
TCountTables = record # this contains the zero count and
|
||||
# non-zero count table
|
||||
mask: TAddress # mask for fast pointer detection
|
||||
zct: TCellSet # the zero count table
|
||||
at: TCellSet # a table that contains all references
|
||||
newAT: TCellSet
|
||||
newZCT: TCellSet
|
||||
stackCells: PStackCells # cells that need to be decremented because they
|
||||
# are in the hardware stack; a cell may occur
|
||||
# several times in this data structure
|
||||
stackLen, stackMax: int # for managing the stack cells
|
||||
|
||||
proc addStackCell(ct: var TCountTables, cell: PCell) =
|
||||
if ct.stackLen >= ct.stackMax:
|
||||
ct.stackMax = ct.stackMax * 3 div 2
|
||||
ct.stackCells = cast[PStackCells](realloc(ct.stackCells, ct.stackMax *
|
||||
sizeof(PCell)))
|
||||
if ct.stackCells == nil: raiseOutOfMem()
|
||||
ct.stackCells[ct.stackLen] = cell
|
||||
inc(ct.stackLen)
|
||||
|
||||
var
|
||||
stackBottom: pointer
|
||||
ct: TCountTables
|
||||
|
||||
proc GC_invariant(): bool =
|
||||
result = True
|
||||
when stressGC:
|
||||
if recGcLock == 0:
|
||||
GC_disable()
|
||||
for cell in elements(ct.at):
|
||||
var t = cell.typ # getCellType(cell)
|
||||
if t == nil or t.kind notin {tySequence, tyString, tyRef}:
|
||||
writeCell("corrupt cell?", cell)
|
||||
result = false
|
||||
GC_enable()
|
||||
|
||||
when stressGC:
|
||||
proc GCdebugHook() =
|
||||
if not GC_invariant():
|
||||
assert(false)
|
||||
|
||||
dbgLineHook = GCdebugHook
|
||||
|
||||
proc prepareDealloc(cell: PCell) =
|
||||
if cell.typ.finalizer != nil:
|
||||
# the finalizer could invoke something that
|
||||
# allocates memory; this could trigger a garbage
|
||||
# collection. Since we are already collecting we
|
||||
# prevend recursive entering here by a lock.
|
||||
# XXX: we should set the cell's children to nil!
|
||||
inc(recGcLock)
|
||||
(cast[TFinalizer](cell.typ.finalizer))(cellToUsr(cell))
|
||||
dec(recGcLock)
|
||||
|
||||
when defined(nimSize):
|
||||
memUsed = memUsed - nimSize(cell)
|
||||
else:
|
||||
memUsed = memUsed - cell.typ.size
|
||||
|
||||
proc setStackBottom(theStackBottom: pointer) {.compilerproc.} =
|
||||
stackBottom = theStackBottom
|
||||
|
||||
proc initGC() =
|
||||
# init the rt
|
||||
CellSetInit(ct.zct)
|
||||
CellSetInit(ct.at)
|
||||
ct.stackLen = 0
|
||||
ct.stackMax = 255
|
||||
ct.stackCells = cast[PStackCells](gcAlloc((ct.stackMax+1) * sizeof(PCell)))
|
||||
ct.mask = 0
|
||||
new(gOutOfMem) # reserve space for the EOutOfMemory exception here!
|
||||
assert(GC_invariant())
|
||||
|
||||
# forward declarations:
|
||||
proc collectCT(ct: var TCountTables)
|
||||
proc IsOnStack(p: pointer): bool
|
||||
proc forAllChildren(cell: PCell, op: TWalkOp)
|
||||
proc collectCycles()
|
||||
|
||||
proc reprAny(p: pointer, typ: PNimType): string {.compilerproc.}
|
||||
# we need the prototype here for debugging purposes
|
||||
|
||||
proc outputCell(c: PCell) =
|
||||
inc(recGcLock)
|
||||
write(stdout, reprAny(cellToUsr(c), c.typ))
|
||||
dec(recGcLock)
|
||||
|
||||
proc writeGraph() =
|
||||
{.checkpoint.}
|
||||
block:
|
||||
inc(recGcLock)
|
||||
for c in elements(ct.AT): outputCell(c)
|
||||
dec(recGcLock)
|
||||
|
||||
proc checkRefc(): bool =
|
||||
if recGcLock >= 1: return true # prevent endless recursion
|
||||
inc(recGcLock)
|
||||
result = True
|
||||
# set counters back to zero:
|
||||
for c in elements(ct.AT):
|
||||
c.drefc = 0
|
||||
for c in elements(ct.AT):
|
||||
forAllChildren(c, waDebugIncRef)
|
||||
for c in elements(ct.AT):
|
||||
if c.drefc > c.refcount - c.stackcount:
|
||||
result = false # failed
|
||||
c_fprintf(c_stdout,
|
||||
"broken cell: %p, refc: %ld, stack: %ld, real: %ld\n",
|
||||
c, c.refcount, c.stackcount, c.drefc)
|
||||
dec(recGcLock)
|
||||
|
||||
proc seqCheck(cell: PCell): bool =
|
||||
assert(cell.typ != nil)
|
||||
if cell.typ.kind in {tySequence, tyString}:
|
||||
result = cell.refcount - cell.stackcount <= 1
|
||||
else:
|
||||
result = true
|
||||
|
||||
proc decRef(cell: PCell) {.inline.} =
|
||||
assert(cell in ct.AT)
|
||||
when defined(debugGC):
|
||||
if cell.refcount == 0:
|
||||
writePtr("decref broken", cellToUsr(cell))
|
||||
assert(cell.refcount > 0) # this should be the case!
|
||||
assert(seqCheck(cell))
|
||||
dec(cell.refcount)
|
||||
if cell.refcount == 0:
|
||||
incl(ct.zct, cell)
|
||||
|
||||
proc incRef(cell: PCell) {.inline.} =
|
||||
assert(seqCheck(cell))
|
||||
inc(cell.refcount)
|
||||
|
||||
proc asgnRef(dest: ppointer, src: pointer) =
|
||||
# the code generator calls this proc!
|
||||
assert(not isOnStack(dest))
|
||||
# BUGFIX: first incRef then decRef!
|
||||
if src != nil: incRef(usrToCell(src))
|
||||
if dest^ != nil: decRef(usrToCell(dest^))
|
||||
dest^ = src
|
||||
#assert(checkRefc())
|
||||
|
||||
proc unsureAsgnRef(dest: ppointer, src: pointer) =
|
||||
if not IsOnStack(dest):
|
||||
if src != nil: incRef(usrToCell(src))
|
||||
if dest^ != nil: decRef(usrToCell(dest^))
|
||||
dest^ = src
|
||||
#assert(checkRefc())
|
||||
|
||||
proc restore(cell: PCell) =
|
||||
if cell notin ct.newAT:
|
||||
incl(ct.newAT, Cell)
|
||||
forAllChildren(cell, waCycleIncRef)
|
||||
|
||||
proc doOperation(p: pointer, op: TWalkOp) =
|
||||
if p == nil: return
|
||||
var cell: PCell = usrToCell(p)
|
||||
assert(cell != nil)
|
||||
case op # faster than function pointers because of easy prediction
|
||||
of waNone: assert(false)
|
||||
of waRelease: decRef(cell) # DEAD CODE!
|
||||
of waZctDecRef:
|
||||
assert(cell.refcount > 0)
|
||||
assert(seqCheck(cell))
|
||||
dec(cell.refcount)
|
||||
if cell.refcount == 0:
|
||||
incl(ct.newZCT, cell)
|
||||
of waCycleDecRef:
|
||||
assert(cell.refcount != 0)
|
||||
dec(cell.refcount)
|
||||
of waCycleIncRef:
|
||||
inc(cell.refcount) # restore proper reference counts!
|
||||
restore(cell)
|
||||
of waDebugIncRef:
|
||||
inc(cell.drefc)
|
||||
|
||||
type
|
||||
TByteArray = array[0..1000_0000, byte]
|
||||
PByte = ptr TByteArray
|
||||
PString = ptr string
|
||||
|
||||
proc forAllChildrenAux(dest: Pointer, mt: PNimType, op: TWalkOp)
|
||||
|
||||
proc getDiscriminant(aa: Pointer, n: ptr TNimNode): int =
|
||||
assert(n.kind == nkCase)
|
||||
var d: int32
|
||||
var a = cast[TAddress](aa)
|
||||
case n.typ.size
|
||||
of 1: d = toU32(cast[ptr int8](a +% n.offset)^)
|
||||
of 2: d = toU32(cast[ptr int16](a +% n.offset)^)
|
||||
of 4: d = toU32(cast[ptr int32](a +% n.offset)^)
|
||||
else: assert(false)
|
||||
return int(d)
|
||||
|
||||
proc selectBranch(aa: Pointer, n: ptr TNimNode): ptr TNimNode =
|
||||
var discr = getDiscriminant(aa, n)
|
||||
if discr <% n.len:
|
||||
result = n.sons[discr]
|
||||
if result == nil: result = n.sons[n.len]
|
||||
# n.sons[n.len] contains the ``else`` part (but may be nil)
|
||||
else:
|
||||
result = n.sons[n.len]
|
||||
|
||||
proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) =
|
||||
var
|
||||
d = cast[TAddress](dest)
|
||||
case n.kind
|
||||
of nkNone: assert(false)
|
||||
of nkSlot: forAllChildrenAux(cast[pointer](d +% n.offset), n.typ, op)
|
||||
of nkList:
|
||||
for i in 0..n.len-1: forAllSlotsAux(dest, n.sons[i], op)
|
||||
of nkCase:
|
||||
var m = selectBranch(dest, n)
|
||||
if m != nil: forAllSlotsAux(dest, m, op)
|
||||
|
||||
proc forAllChildrenAux(dest: Pointer, mt: PNimType, op: TWalkOp) =
|
||||
var
|
||||
d = cast[TAddress](dest)
|
||||
if dest == nil: return # nothing to do
|
||||
case mt.Kind
|
||||
of tyArray, tyArrayConstr, tyOpenArray:
|
||||
for i in 0..(mt.size div mt.base.size)-1:
|
||||
forAllChildrenAux(cast[pointer](d +% i *% mt.base.size), mt.base, op)
|
||||
of tyRef, tyString, tySequence: # leaf:
|
||||
doOperation(cast[ppointer](d)^, op)
|
||||
of tyRecord, tyObject, tyTuple:
|
||||
forAllSlotsAux(dest, mt.node, op)
|
||||
else: nil
|
||||
|
||||
proc forAllChildren(cell: PCell, op: TWalkOp) =
|
||||
assert(cell != nil)
|
||||
when defined(debugGC):
|
||||
if cell.typ == nil:
|
||||
writeCell("cell has no type descriptor", cell)
|
||||
assert(cell.typ != nil)
|
||||
case cell.typ.Kind
|
||||
of tyRef: # common case
|
||||
forAllChildrenAux(cellToUsr(cell), cell.typ.base, op)
|
||||
of tySequence:
|
||||
var d = cast[TAddress](cellToUsr(cell))
|
||||
var s = cast[PGenericSeq](d)
|
||||
if s != nil: # BUGFIX
|
||||
for i in 0..s.len-1:
|
||||
forAllChildrenAux(cast[pointer](d +% i *% cell.typ.base.size +%
|
||||
GenericSeqSize), cell.typ.base, op)
|
||||
of tyString: nil
|
||||
else: assert(false)
|
||||
|
||||
proc checkCollection() {.inline.} =
|
||||
# checks if a collection should be done
|
||||
if recGcLock == 0:
|
||||
if memUsed >= rcThreshold or stressGC:
|
||||
collectCT(ct)
|
||||
when defined(debugGC):
|
||||
write(stdout, "threshold is now: ")
|
||||
writeln(stdout, rcThreshold)
|
||||
|
||||
proc newObj(typ: PNimType, size: int): pointer =
|
||||
# generates a new object and sets its reference counter to 0
|
||||
var
|
||||
res: PCell
|
||||
assert(typ.kind in {tyRef, tyString, tySequence})
|
||||
# check if we have to collect:
|
||||
checkCollection()
|
||||
res = cast[PCell](Alloc0(size + sizeof(TCell)))
|
||||
if res == nil: raiseOutOfMem()
|
||||
when defined(nimSize):
|
||||
memUsed = memUsed + nimSize(res)
|
||||
else:
|
||||
memUsed = memUsed + size
|
||||
|
||||
res.refcount = 0
|
||||
# now it is buffered in the ZCT
|
||||
res.typ = typ
|
||||
incl(ct.zct, res) # its refcount is zero, so add it to the ZCT
|
||||
incl(ct.at, res) # add it to the any table too
|
||||
ct.mask = ct.mask or cast[TAddress](res)
|
||||
when defined(debugGC):
|
||||
writeCell("new cell", res)
|
||||
assert(gcInvariant())
|
||||
result = cellToUsr(res)
|
||||
|
||||
proc newSeq(typ: PNimType, len: int): pointer =
|
||||
# XXX: overflow checks!
|
||||
result = newObj(typ, len * typ.base.size + GenericSeqSize)
|
||||
cast[PGenericSeq](result).len = len
|
||||
cast[PGenericSeq](result).space = len
|
||||
|
||||
proc growObj(old: pointer, newsize: int): pointer =
|
||||
var
|
||||
res, ol: PCell
|
||||
checkCollection()
|
||||
ol = usrToCell(old)
|
||||
assert(ol.typ.kind in {tyString, tySequence})
|
||||
assert(seqCheck(ol))
|
||||
when defined(nimSize):
|
||||
memUsed = memUsed - nimSize(ol)
|
||||
else:
|
||||
memUsed = memUsed - ol.size # this is not exact
|
||||
# pity that we don't know the old size
|
||||
res = cast[PCell](realloc(ol, newsize + sizeof(TCell)))
|
||||
when defined(nimSize):
|
||||
memUsed = memUsed + nimSize(res)
|
||||
else:
|
||||
memUsed = memUsed + newsize
|
||||
|
||||
if res != ol:
|
||||
if res == nil: raiseOutOfMem()
|
||||
excl(ct.zct, ol) # remove old pointer in any case:
|
||||
# It may have a refcount > 0 and is still in the ZCT.
|
||||
# So do it safe here and remove it anyway.
|
||||
excl(ct.at, ol)
|
||||
if res.refcount == 0:
|
||||
# store new pointer in ZCT, if refcount == 0:
|
||||
incl(ct.zct, res)
|
||||
incl(ct.at, res)
|
||||
ct.mask = ct.mask or cast[TAddress](res)
|
||||
when defined(debugGC):
|
||||
writeCell("growObj old cell", ol)
|
||||
writeCell("growObj new cell", res)
|
||||
result = cellToUsr(res)
|
||||
#assert(checkRefc())
|
||||
|
||||
proc collectCycles() =
|
||||
when defined(debugGC):
|
||||
echo("collecting cycles!\n")
|
||||
|
||||
# step 1: pretend that any node is dead
|
||||
for c in elements(ct.at):
|
||||
forallChildren(c, waCycleDecRef)
|
||||
CellSetInit(ct.newAt)
|
||||
# step 2: restore life cells
|
||||
for c in elements(ct.at):
|
||||
if c.refcount > 0: restore(c)
|
||||
# step 3: free dead cells:
|
||||
for cell in elements(ct.at):
|
||||
if cell.refcount == 0:
|
||||
assert(cell notin ct.zct)
|
||||
# We free an object that is part of a cycle here. Its children
|
||||
# may have been freed already. Thus the finalizer could access
|
||||
# garbage. To handle this case properly we need two passes for
|
||||
# freeing here which is too expensive. We just don't call the
|
||||
# finalizer for now. YYY: Any better ideas?
|
||||
prepareDealloc(cell)
|
||||
dealloc(cell)
|
||||
when defined(debugGC):
|
||||
writeCell("cycle collector dealloc cell", cell)
|
||||
CellSetDeinit(ct.at)
|
||||
ct.at = ct.newAt
|
||||
#ct.newAt = nil
|
||||
|
||||
proc gcMark(p: pointer) =
|
||||
# the addresses are not as objects on the stack, so turn them to objects:
|
||||
var cell = usrToCell(p)
|
||||
var c = cast[TAddress](cell)
|
||||
if ((c and ct.mask) == c) and cell in ct.at:
|
||||
# is the page that p "points to" in the AT? (All allocated pages are
|
||||
# always in the AT)
|
||||
inc(cell.refcount)
|
||||
inc(cell.stackcount)
|
||||
addStackCell(ct, cell)
|
||||
|
||||
proc unmarkStackAndRegisters() =
|
||||
for i in 0 .. ct.stackLen-1:
|
||||
var cell = ct.stackCells[i]
|
||||
assert(cell.refcount > 0)
|
||||
when defined(debugGC):
|
||||
if cell.stackcount == 0:
|
||||
writeGraph()
|
||||
writePtr("broken stackcount", cellToUsr(cell))
|
||||
assert(cell.stackcount > 0)
|
||||
dec(cell.refcount)
|
||||
dec(cell.stackcount)
|
||||
if cell.refcount == 0:
|
||||
incl(ct.zct, cell)
|
||||
ct.stackLen = 0 # reset to zero
|
||||
|
||||
# ----------------- stack management --------------------------------------
|
||||
# inspired from Smart Eiffel (c)
|
||||
|
||||
proc stackSize(): int =
|
||||
var stackTop: array[0..1, pointer]
|
||||
result = abs(cast[int](addr(stackTop[0])) - cast[int](stackBottom))
|
||||
|
||||
when defined(sparc): # For SPARC architecture.
|
||||
|
||||
proc isOnStack(p: pointer): bool =
|
||||
var
|
||||
stackTop: array[0..1, pointer]
|
||||
result = p >= addr(stackTop[0]) and p <= stackBottom
|
||||
|
||||
proc markStackAndRegisters() =
|
||||
when defined(sparcv9):
|
||||
asm " flushw"
|
||||
else:
|
||||
asm " ta 0x3 ! ST_FLUSH_WINDOWS"
|
||||
|
||||
var
|
||||
max = stackBottom
|
||||
sp: PPointer
|
||||
stackTop: array[0..1, pointer]
|
||||
stackTop[0] = nil
|
||||
stackTop[1] = nil
|
||||
sp = addr(stackTop[0])
|
||||
# Addresses decrease as the stack grows.
|
||||
while sp <= max:
|
||||
gcMark(sp^)
|
||||
sp = cast[ppointer](cast[TAddress](sp) +% sizeof(pointer))
|
||||
|
||||
elif defined(ELATE):
|
||||
{.error: "stack marking code has to be written for this architecture".}
|
||||
|
||||
elif defined(hppa) or defined(hp9000) or defined(hp9000s300) or
|
||||
defined(hp9000s700) or defined(hp9000s800) or defined(hp9000s820):
|
||||
# ---------------------------------------------------------------------------
|
||||
# Generic code for architectures where addresses increase as the stack grows.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
proc isOnStack(p: pointer): bool =
|
||||
var
|
||||
stackTop: array[0..1, pointer]
|
||||
result = p <= addr(stackTop[0]) and p >= stackBottom
|
||||
|
||||
var
|
||||
jmpbufSize {.importc: "sizeof(jmp_buf)".}: int
|
||||
# a little hack to get the size of a TJmpBuf in the generated C code
|
||||
# in a platform independant way
|
||||
|
||||
proc markStackAndRegisters() =
|
||||
var
|
||||
max = stackBottom
|
||||
registers: C_JmpBuf # The jmp_buf buffer is in the C stack.
|
||||
sp: PPointer # Used to traverse the stack and registers assuming
|
||||
# that `setjmp' will save registers in the C stack.
|
||||
c_setjmp(registers) # To fill the C stack with registers.
|
||||
sp = cast[ppointer](cast[TAddress](addr(registers)) +%
|
||||
jmpbufSize -% sizeof(pointer))
|
||||
# sp will traverse the JMP_BUF as well (jmp_buf size is added,
|
||||
# otherwise sp would be below the registers structure).
|
||||
while sp >= max:
|
||||
gcMark(sp^)
|
||||
sp = cast[ppointer](cast[TAddress](sp) -% sizeof(pointer))
|
||||
|
||||
else:
|
||||
# ---------------------------------------------------------------------------
|
||||
# Generic code for architectures where addresses decrease as the stack grows.
|
||||
# ---------------------------------------------------------------------------
|
||||
proc isOnStack(p: pointer): bool =
|
||||
var
|
||||
stackTop: array [0..1, pointer]
|
||||
result = p >= addr(stackTop[0]) and p <= stackBottom
|
||||
|
||||
proc markStackAndRegisters() =
|
||||
var
|
||||
max = stackBottom
|
||||
registers: C_JmpBuf # The jmp_buf buffer is in the C stack.
|
||||
sp: PPointer # Used to traverse the stack and registers assuming
|
||||
# that `setjmp' will save registers in the C stack.
|
||||
c_setjmp(registers) # To fill the C stack with registers.
|
||||
sp = cast[ppointer](addr(registers))
|
||||
while sp <= max:
|
||||
gcMark(sp^)
|
||||
sp = cast[ppointer](cast[TAddress](sp) +% sizeof(pointer))
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# end of non-portable code
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
proc CollectZCT =
|
||||
CellSetInit(ct.newZCT)
|
||||
for c in elements(ct.zct):
|
||||
if c.refcount == 0:
|
||||
# if != 0 the reference count has been increased, so this does not
|
||||
# belong to the ZCT. We simply do nothing - it won't appear in the newZCT
|
||||
# anyway.
|
||||
# We are about to free the object, call the finalizer BEFORE its
|
||||
# children are deleted as well, because otherwise the finalizer may
|
||||
# access invalid memory. This is done by prepareDealloc():
|
||||
prepareDealloc(c)
|
||||
forAllChildren(c, waZctDecRef)
|
||||
assert(c.refcount == 0) # should still be zero
|
||||
excl(ct.at, c)
|
||||
excl(ct.newZCT, c) # BUGFIX
|
||||
when defined(debugGC):
|
||||
writeCell("zct dealloc cell", c)
|
||||
dealloc(c)
|
||||
CellSetDeinit(ct.zct)
|
||||
ct.zct = ct.newZCT
|
||||
#ct.newZCT = nil
|
||||
|
||||
proc collectCT(ct: var TCountTables) =
|
||||
when defined(debugGC):
|
||||
c_fprintf(c_stdout, "collecting zero count table; stack size: %ld\n",
|
||||
stackSize())
|
||||
markStackAndRegisters()
|
||||
assert(GC_invariant())
|
||||
while True:
|
||||
collectZCT()
|
||||
if ct.zct.counter == 0: break
|
||||
# ``counter`` counts the pages, but zero pages means zero cells
|
||||
|
||||
when defined(cycleGC):
|
||||
# still over the cycle threshold?
|
||||
if memUsed >= cycleThreshold or stressGC:
|
||||
# collect the cyclic things:
|
||||
assert(ct.zct.counter == 0)
|
||||
assert(GC_invariant())
|
||||
collectCycles()
|
||||
|
||||
# recompute the thresholds:
|
||||
rcThreshold = (memUsed div RC_increase + 1) * RC_Increase
|
||||
cycleThreshold = memUsed * cycleIncrease
|
||||
|
||||
assert(GC_invariant())
|
||||
unmarkStackAndRegisters()
|
||||
|
||||
proc GC_fullCollect() =
|
||||
var oldThreshold = cycleThreshold
|
||||
cycleThreshold = 0 # forces cycle collection
|
||||
collectCT(ct)
|
||||
cycleThreshold = oldThreshold
|
||||
51
lib/hti.nim
Executable file
51
lib/hti.nim
Executable file
|
|
@ -0,0 +1,51 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2008 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
type # This should be he same as ast.TTypeKind
|
||||
# some enum fields are not used at runtime
|
||||
TNimKind = enum
|
||||
tyNone, tyBool, tyChar,
|
||||
tyEmptySet, tyArrayConstr, tyNil, tyRecordConstr,
|
||||
tyGeneric,
|
||||
tyGenericInst,
|
||||
tyGenericParam,
|
||||
tyEnum, tyAnyEnum,
|
||||
tyArray,
|
||||
tyRecord,
|
||||
tyObject,
|
||||
tyTuple,
|
||||
tySet,
|
||||
tyRange,
|
||||
tyPtr, tyRef,
|
||||
tyVar,
|
||||
tySequence,
|
||||
tyProc,
|
||||
tyPointer, tyOpenArray,
|
||||
tyString, tyCString, tyForward,
|
||||
tyInt, tyInt8, tyInt16, tyInt32, tyInt64,
|
||||
tyFloat, tyFloat32, tyFloat64, tyFloat128
|
||||
|
||||
TNimNodeKind = enum nkNone, nkSlot, nkList, nkCase
|
||||
TNimNode {.compilerproc.} = record
|
||||
kind: TNimNodeKind
|
||||
offset: int
|
||||
typ: ptr TNimType
|
||||
name: Cstring
|
||||
len: int
|
||||
sons: ptr array [0..0x7fff, ptr TNimNode]
|
||||
|
||||
TNimType {.compilerproc.} = record
|
||||
size: int
|
||||
kind: TNimKind
|
||||
base: ptr TNimType
|
||||
node: ptr TNimNode # valid for tyRecord, tyObject, tyTuple, tyEnum
|
||||
finalizer: pointer # the finalizer for the type
|
||||
PNimType = ptr TNimType
|
||||
|
||||
# node.len may be the ``first`` element of a set
|
||||
70
lib/i386.asm.in
Executable file
70
lib/i386.asm.in
Executable file
|
|
@ -0,0 +1,70 @@
|
|||
; This contains the CPU-dependant variants of some routines.
|
||||
; (C) 2005 Andreas Rumpf
|
||||
; This code was inspired by the Freepascal compiler's sources
|
||||
; All routines here have the _cdecl calling convention because
|
||||
; that is the only convention any C compiler supports.
|
||||
|
||||
\python{
|
||||
# as usual I use my own preprocessor :-)
|
||||
import os
|
||||
|
||||
def c(name):
|
||||
if os.name == 'posix':
|
||||
return name
|
||||
else:
|
||||
return "_" + name
|
||||
}
|
||||
|
||||
segment code
|
||||
|
||||
global \c{cpu_inc_locked}
|
||||
global \c{cpu_dec_locked}
|
||||
global \c{cpu_lock}
|
||||
global \c{cpu_unlock}
|
||||
|
||||
\c{cpu_dec_locked}:
|
||||
push ebp
|
||||
mov ebp,esp
|
||||
mov eax,[ebp+8] ; first parameter to function
|
||||
lock dec dword [eax]
|
||||
setz al
|
||||
mov esp,ebp
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
\c{cpu_inc_locked}:
|
||||
push ebp
|
||||
mov ebp,esp
|
||||
mov eax,[ebp+8] ; first parameter to function
|
||||
lock inc dword [eax]
|
||||
mov esp,ebp
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
; This code uses the highest bit of the RC to indicate that the RC is
|
||||
; locked (spinlock).
|
||||
\c{cpu_lock}
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
mov eax, [ebp+8] ; first parameter to function
|
||||
mov edx, [eax] ; load RC
|
||||
or edx, 0x80000000 ; set highest bit
|
||||
spin:
|
||||
xchg [eax], edx ; atomic instruction!
|
||||
pause ; wait a few cycles
|
||||
and edx, 0x80000000 ; mask highest bit
|
||||
jnz spin
|
||||
mov esp, ebp
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
\c{cpu_unlock}
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
mov eax, [ebp+8] ; first parameter to function
|
||||
mov edx, [eax] ; load RC
|
||||
and edx, 0x7FFFFFFF ; unset highest bit
|
||||
xchg [eax], edx ; atomic instruction!
|
||||
mov esp, ebp
|
||||
pop ebp
|
||||
ret
|
||||
72
lib/int64s.nim
Executable file
72
lib/int64s.nim
Executable file
|
|
@ -0,0 +1,72 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
# 64 bit integers for platforms that don't have those
|
||||
|
||||
type
|
||||
IInt64 = record # "internal" int64
|
||||
lo, hi: int32
|
||||
|
||||
proc cmpI64(x, y: IInt64): int32 {.compilerproc.} =
|
||||
result = x.hi -% y.hi
|
||||
if result == 0: result = x.lo -% y.lo
|
||||
|
||||
proc addI64(x, y: IInt64): IInt64 {.compilerproc.} =
|
||||
result = x
|
||||
result.lo = result.lo +% y.lo
|
||||
result.hi = result.hi +% y.hi
|
||||
if y.lo > 0 and result.lo < y.lo:
|
||||
inc(result.hi)
|
||||
elif y.lo < 0 and result.lo > y.lo:
|
||||
dec(result.hi)
|
||||
|
||||
proc subI64(x, y: IInt64): IInt64 {.compilerproc.} =
|
||||
result = x
|
||||
result.lo = result.lo -% y.lo
|
||||
result.hi = result.hi -% y.hi
|
||||
if y.lo > 0 and result.lo < y.lo:
|
||||
inc(result.hi)
|
||||
elif y.lo < 0 and result.lo > y.lo:
|
||||
dec(result.hi)
|
||||
|
||||
proc mulI64(x, y: IInt64): IInt64 {.compilerproc.} =
|
||||
result.lo = x.lo *% y.lo
|
||||
result.hi = y.hi *% y.hi
|
||||
if y.lo > 0 and result.lo < y.lo:
|
||||
inc(result.hi)
|
||||
elif y.lo < 0 and result.lo > y.lo:
|
||||
dec(result.hi)
|
||||
|
||||
proc divI64(x, y: IInt64): IInt64 {.compilerproc.} =
|
||||
# XXX: to implement
|
||||
|
||||
proc modI64(x, y: IInt64): IInt64 {.compilerproc.} =
|
||||
# XXX: to implement
|
||||
|
||||
proc bitandI64(x, y: IInt64): IInt64 {.compilerproc.} =
|
||||
result.hi = x.hi and y.hi
|
||||
result.lo = x.lo and y.lo
|
||||
|
||||
proc bitorI64(x, y: IInt64): IInt64 {.compilerproc.} =
|
||||
result.hi = x.hi or y.hi
|
||||
result.lo = x.lo or y.lo
|
||||
|
||||
proc bitxorI64(x, y: IInt64): IInt64 {.compilerproc.} =
|
||||
result.hi = x.hi xor y.hi
|
||||
result.lo = x.lo xor y.lo
|
||||
|
||||
proc bitnotI64(x: IInt64): IInt64 {.compilerproc.} =
|
||||
result.lo = not x.lo
|
||||
result.hi = not x.hi
|
||||
|
||||
proc shlI64(x, y: IInt64): IInt64 {.compilerproc.} =
|
||||
# XXX: to implement
|
||||
|
||||
proc shrI64(x, y: IInt64): IInt64 {.compilerproc.} =
|
||||
# XXX: to implement
|
||||
502
lib/lgpl.txt
Executable file
502
lib/lgpl.txt
Executable file
|
|
@ -0,0 +1,502 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 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.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
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 and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, 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 library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete 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 distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
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.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
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 Library, 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.
|
||||
|
||||
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 Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you 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.
|
||||
|
||||
If distribution of 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 satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be 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.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library 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.
|
||||
|
||||
9. 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 Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
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 with
|
||||
this License.
|
||||
|
||||
11. 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 Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library 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 Library.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library 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.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser 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.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
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 Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
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.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "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
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. 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 LIBRARY 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
|
||||
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. 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.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
||||
18
lib/locks.nim
Executable file
18
lib/locks.nim
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2008 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
# Simple platform dependant lock implementation
|
||||
|
||||
type
|
||||
TSimpleLock = pointer
|
||||
|
||||
proc initLock(s: TSimpleLock)
|
||||
proc deinitLock(s: TSimpleLock)
|
||||
proc lock(s: TSimpleLock)
|
||||
proc unlock(s: TSimpleLock)
|
||||
131
lib/math.nim
Executable file
131
lib/math.nim
Executable file
|
|
@ -0,0 +1,131 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
|
||||
|
||||
# math routines
|
||||
|
||||
# interface
|
||||
|
||||
{.push debugger:off .} # the user does not want to trace a part
|
||||
# of the standard library!
|
||||
|
||||
{.push checks:off, line_dir:off, stack_trace:off.}
|
||||
|
||||
proc nextPowerOfTwo*(x: int): int
|
||||
## returns the nearest power of two, so that
|
||||
## result**2 >= x > (result-1)**2.
|
||||
proc isPowerOfTwo*(x: int): bool {.noSideEffect.}
|
||||
## returns true, if x is a power of two, false otherwise.
|
||||
## Negative numbers are not a power of two.
|
||||
proc countBits*(n: int32): int {.noSideEffect.}
|
||||
## counts the set bits in `n`.
|
||||
|
||||
proc random*(max: int): int
|
||||
## returns a random number in the range 0..max-1. The sequence of
|
||||
## random number is always the same, unless `randomize` is called
|
||||
## which initializes the random number generator with a "random"
|
||||
## number, i.e. a tickcount.
|
||||
proc randomize*()
|
||||
## initializes the random number generator with a "random"
|
||||
## number, i.e. a tickcount.
|
||||
|
||||
proc sqrt*(x: float): float {.importc: "sqrt", header: "<math.h>".}
|
||||
## computes the square root of `x`.
|
||||
|
||||
proc ln*(x: float): float {.importc: "log", header: "<math.h>".}
|
||||
## computes ln(x).
|
||||
proc exp*(x: float): float {.importc: "exp", header: "<math.h>".}
|
||||
## computes e**x.
|
||||
|
||||
proc frexp*(x: float, exponent: var int): float {.
|
||||
importc: "frexp", header: "<math.h>".}
|
||||
## Split a number into mantissa and exponent.
|
||||
## `frexp` calculates the mantissa m (a float greater than or equal to 0.5
|
||||
## and less than 1) and the integer value n such that `x` (the original
|
||||
## float value) equals m * 2**n. frexp stores n in `exponent` and returns
|
||||
## m.
|
||||
|
||||
proc arccos*(x: float): float {.importc: "acos", header: "<math.h>".}
|
||||
proc arcsin*(x: float): float {.importc: "asin", header: "<math.h>".}
|
||||
proc arctan*(x: float): float {.importc: "atan", header: "<math.h>".}
|
||||
proc arctan2*(y, x: float): float {.importc: "atan2", header: "<math.h>".}
|
||||
## Calculate the arc tangent of `y` / `x`.
|
||||
## `atan2` returns the arc tangent of `y` / `x`; it produces correct
|
||||
## results even when the resulting angle is near pi/2 or -pi/2
|
||||
## (`x` near 0).
|
||||
|
||||
proc cos*(x: float): float {.importc: "cos", header: "<math.h>".}
|
||||
proc cosh*(x: float): float {.importc: "cosh", header: "<math.h>".}
|
||||
proc hypot*(x: float): float {.importc: "hypot", header: "<math.h>".}
|
||||
proc log10*(x: float): float {.importc: "log10", header: "<math.h>".}
|
||||
proc sinh*(x: float): float {.importc: "sinh", header: "<math.h>".}
|
||||
proc tan*(x: float): float {.importc: "tan", header: "<math.h>".}
|
||||
proc tanh*(x: float): float {.importc: "tanh", header: "<math.h>".}
|
||||
proc pow*(x, y: float): float {.importc: "pos", header: "<math.h>".}
|
||||
## computes x to power raised of y.
|
||||
|
||||
type
|
||||
TFloatClass* = enum ## describes the class a floating point value belongs to.
|
||||
## This is the type that is returned by `classify`.
|
||||
fcNormal, ## value is an ordinary nonzero floating point value
|
||||
fcSubnormal, ## value is a subnormal (a very small) floating point value
|
||||
fcZero, ## value is zero
|
||||
fcNegZero, ## value is the negative zero
|
||||
fcNan, ## value is Not-A-Number (NAN)
|
||||
fcInf, ## value is positive infinity
|
||||
fcNegInf ## value is negative infinity
|
||||
|
||||
proc classify*(x: float): TFloatClass
|
||||
## classifies a floating point value. Returns `x`'s class as specified by
|
||||
## `TFloatClass`
|
||||
|
||||
# implementation
|
||||
|
||||
include cntbits
|
||||
|
||||
proc nextPowerOfTwo(x: int): int =
|
||||
result = x - 1
|
||||
when defined(cpu64):
|
||||
result = result or (result shr 32)
|
||||
result = result or (result shr 16)
|
||||
result = result or (result shr 8)
|
||||
result = result or (result shr 4)
|
||||
result = result or (result shr 2)
|
||||
result = result or (result shr 1)
|
||||
Inc(result)
|
||||
|
||||
# C procs:
|
||||
proc gettime(dummy: ptr cint): cint {.
|
||||
importc: "time", header: "<time.h>".}
|
||||
proc srand(seed: cint) {.
|
||||
importc: "srand", nodecl.}
|
||||
proc rand(): cint {.importc: "rand", nodecl.}
|
||||
|
||||
# most C compilers have no classify:
|
||||
proc classify(x: float): TFloatClass =
|
||||
if x == 0.0:
|
||||
if 1.0/x == 1.0/0.0:
|
||||
return fcZero
|
||||
else:
|
||||
return fcNegZero
|
||||
if x*0.5 == x:
|
||||
if x > 0.0: return fcInf
|
||||
else: return fcNegInf
|
||||
if x != x: return fcNan
|
||||
return fcNormal
|
||||
# XXX: fcSubnormal is not detected!
|
||||
|
||||
proc randomize() = srand(gettime(nil))
|
||||
proc random(max: int): int = return rand() mod max
|
||||
|
||||
proc isPowerOfTwo(x: int): bool = return (x and -x) == x
|
||||
|
||||
{.pop.}
|
||||
{.pop.}
|
||||
599
lib/memman.nim
Executable file
599
lib/memman.nim
Executable file
|
|
@ -0,0 +1,599 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2008 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
|
||||
# Memory manager. Based on:
|
||||
# Two Levels Segregate Fit memory allocator (TLSF)
|
||||
# Version 2.4.2
|
||||
#
|
||||
# Written by Miguel Masmano Tello <mimastel@doctor.upv.es>
|
||||
#
|
||||
# Thanks to Ismael Ripoll for his suggestions and reviews
|
||||
#
|
||||
# Copyright (C) 2008, 2007, 2006, 2005, 2004
|
||||
#
|
||||
# This code is released using a dual license strategy: GPL/LGPL
|
||||
# You can choose the licence that better fits your requirements.
|
||||
#
|
||||
# Released under the terms of the GNU General Public License Version 2.0
|
||||
# Released under the terms of the GNU Lesser General Public License Version 2.1
|
||||
|
||||
|
||||
# Some IMPORTANT TLSF parameters
|
||||
const
|
||||
blockAlign = sizeof(pointer) * 2
|
||||
maxFli = 30
|
||||
maxLog2Sli = 5
|
||||
maxSli = 1 shl maxLog2Sli
|
||||
|
||||
fliOffset = 6 # tlsf structure just will manage blocks bigger than 128 bytes
|
||||
smallBlock = 128
|
||||
realFli = MaxFli - fliOffset
|
||||
|
||||
type
|
||||
TFreePtr = record
|
||||
prev, next: PBhdr
|
||||
Pbhdr = ptr Tbhdr
|
||||
Tbhdr = record
|
||||
prevHdr: Pbhdr # this is just valid if the first bit of size is set
|
||||
size: int # the size is stored in bytes
|
||||
# bit 0 indicates whether the block is used and
|
||||
# bit 1 allows to know whether the previous block is free
|
||||
freePtr: TFreePtr # at this offset bhdr.buffer starts (was a union in the
|
||||
# C version)
|
||||
TAreaInfo = record # This structure is embedded at the beginning of each
|
||||
# area, giving us enough information to cope with a set
|
||||
# of areas
|
||||
theEnd: Pbhdr
|
||||
next: PAreaInfo
|
||||
PAreaInfo = ptr TAreaInfo
|
||||
|
||||
TLSF = record
|
||||
tlsf_signature: int32 # the TLSF's structure signature
|
||||
usedSize, maxSize: int
|
||||
areaHead: PAreaInfo # A linked list holding all the existing areas
|
||||
|
||||
flBitmap: int32 # the first-level bitmap
|
||||
# This array should have a size of REAL_FLI bits
|
||||
slBitmap: array[0..realFli, int32] # the second-level bitmap
|
||||
matrix: array [0..realFli, array[0..maxSli, PBhdr]]
|
||||
|
||||
const
|
||||
minBlockSize = sizeof(TFreePtr)
|
||||
bhdrOverhead = sizeof(Tbhdr) - minBlockSize
|
||||
tlsfSignature = 0x2A59FA59
|
||||
ptrMask = sizeof(pointer) - 1
|
||||
blockSize = 0xFFFFFFFF - ptrMask
|
||||
memAlign = blockAlign - 1
|
||||
blockState = 0x1
|
||||
prevState = 0x2
|
||||
|
||||
freeBlock = 0x1 # bit 0 of the block size
|
||||
usedBlock = 0x0
|
||||
|
||||
prevFree = 0x2 # bit 1 of the block size
|
||||
prevUsed = 0x0
|
||||
|
||||
defaultAreaSize = 64*1024 # 1024*10
|
||||
pageSize = if defined(cpu32): 4096 else: 4096*2
|
||||
|
||||
|
||||
proc getNextBlock(adr: pointer, r: int): PBhdr {.inline.} =
|
||||
return cast[PBhdr](cast[TAddress](adr) +% r)
|
||||
|
||||
proc roundupSize(r: int): int = return (r +% memAlign) and not memAlign
|
||||
proc rounddownSize(r: int): int = return r and not memAlign
|
||||
proc roundup(x, v: int): int = return (((not x)+%1) and (v-%1)) +% x
|
||||
|
||||
proc addSize(s: PTLSF, b: Pbhdr) =
|
||||
inc(s.usedSize, (b.size and blockSize) + bhdrOverhead)
|
||||
s.maxSize = max(s.maxSize, s.usedSize)
|
||||
|
||||
proc removeSize(s: PTLSF, b: Pbhdr) =
|
||||
dec(s.usedSize, (b.size and blockSize) + bhdrOverhead)
|
||||
|
||||
# ------------ platform specific code -----------------------------------------
|
||||
|
||||
when defined(posix):
|
||||
const # XXX: make these variables for portability?
|
||||
PROT_READ = 1 # page can be read
|
||||
PROT_WRITE = 2 # page can be written
|
||||
PROT_EXEC = 4 # page can be executed
|
||||
PROT_NONE = 0 # page can not be accessed
|
||||
|
||||
MAP_SHARED = 1 # Share changes
|
||||
MAP_PRIVATE = 2 # Changes are private
|
||||
MAP_TYPE = 0xf # Mask for type of mapping
|
||||
MAP_FIXED = 0x10 # Interpret addr exactly
|
||||
MAP_ANONYMOUS = 0x20 # don't use a file
|
||||
|
||||
MAP_GROWSDOWN = 0x100 # stack-like segment
|
||||
MAP_DENYWRITE = 0x800 # ETXTBSY
|
||||
MAP_EXECUTABLE = 0x1000 # mark it as an executable
|
||||
MAP_LOCKED = 0x2000 # pages are locked
|
||||
MAP_NORESERVE = 0x4000 # don't check for reservations
|
||||
|
||||
proc mmap(adr: pointer, len: int, prot, flags, fildes: cint,
|
||||
off: int): pointer {.header: "<sys/mman.h>".}
|
||||
|
||||
proc getNewArea(size: var int): pointer {.inline.} =
|
||||
size = roundup(size, PageSize)
|
||||
result = mmap(0, size, PROT_READ or PROT_WRITE,
|
||||
MAP_PRIVATE or MAP_ANONYMOUS, -1, 0)
|
||||
if result == nil or result == cast[pointer](-1):
|
||||
raiseOutOfMem()
|
||||
|
||||
elif defined(windows):
|
||||
const
|
||||
MEM_RESERVE = 0x2000
|
||||
MEM_COMMIT = 0x1000
|
||||
MEM_TOP_DOWN = 0x100000
|
||||
PAGE_READWRITE = 0x04
|
||||
|
||||
proc VirtualAlloc(lpAddress: pointer, dwSize: int, flAllocationType,
|
||||
flProtect: int32): pointer {.
|
||||
header: "<windows.h>", stdcall.}
|
||||
|
||||
proc getNewArea(size: var int): pointer {.inline.} =
|
||||
size = roundup(size, PageSize)
|
||||
result = VirtualAlloc(nil, size, MEM_RESERVE or MEM_COMMIT or MEM_TOP_DOWN,
|
||||
PAGE_READWRITE)
|
||||
if result == nil: raiseOutOfMem()
|
||||
|
||||
else:
|
||||
# generic implementation relying on malloc:
|
||||
proc malloc(size: int): pointer {.nodecl, importc.}
|
||||
|
||||
proc getNewArea(size: var int): pointer {.inline.} =
|
||||
size = roundup(size, PageSize)
|
||||
result = malloc(size)
|
||||
if result == nil: raiseOutOfMem()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# helpers
|
||||
|
||||
const
|
||||
table: array[0..255, int8] = [
|
||||
-1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7
|
||||
]
|
||||
|
||||
proc ls_bit(i: int32): int {.inline.} =
|
||||
var
|
||||
a: int = 0
|
||||
x: int = i and -i
|
||||
if x <=% 0xffff:
|
||||
if x <=% ff: a = 0
|
||||
else: a = 8
|
||||
elif x <=% 0xffffff: a = 16
|
||||
else: a = 24
|
||||
return table[x shr a] + a
|
||||
|
||||
proc ms_bit(i: int): int {.inline.} =
|
||||
var
|
||||
a = if i <=% 0xffff: (if i <=% 0xff: 0 else: 8) elif
|
||||
i <=% 0xffffff: 16 else: 24
|
||||
return table[i shr a] + a
|
||||
|
||||
proc set_bit[IX](nr: int, adr: var array[IX, int32]) {.inline.} =
|
||||
adr[nr shr 5] = adr[nr shr 5] or (1 shl (nr and 0x1f))
|
||||
|
||||
proc clear_bit[IX](nr: int, adr: var array[IX, int32]) {.inline.} =
|
||||
adr[nr shr 5] = adr[nr shr 5] and not (1 shl (nr and 0x1f))
|
||||
|
||||
proc mappingSearch(r, fl, sl: var int) {.inline.} =
|
||||
if r < smallBlock:
|
||||
fl = 0
|
||||
sl = r div (smallBlock div maxSli)
|
||||
else:
|
||||
var t = (1 shl (ms_bit(r) - maxLog2Sli)) - 1
|
||||
r = r + t
|
||||
fl = ms_bit(r)
|
||||
sl = (r shl (fl - maxLog2Sli)) - maxSli
|
||||
fl = fl - fliOffset
|
||||
r = r and not t
|
||||
|
||||
proc mappingInsert(r: int, fl, sl: var int) {.inline.} =
|
||||
if r < smallBlock:
|
||||
fl = 0
|
||||
sl = r div (smallBlock div maxSli)
|
||||
else:
|
||||
fl = ms_bit(r)
|
||||
sl = (r shr (fl - maxLog2Sli)) - maxSli
|
||||
fl = fl - fliOffset
|
||||
|
||||
proc findSuitableBlock(t: var TLSF, fl, sl: var int): Pbhdr =
|
||||
var tmp = t.slBitmap[fl] and ((not 0) shl sl)
|
||||
if tmp != 0:
|
||||
sl = ls_bit(tmp)
|
||||
result = t.matrix[fl][sl]
|
||||
else:
|
||||
fl = ls_bit(t.flBitmap and (not 0 shl (fl + 1)))
|
||||
if fl > 0: # likely
|
||||
sl = ls_bit(t.slBitmap[fl])
|
||||
result = t.matrix[fl][sl]
|
||||
|
||||
proc extractBlockHdr(b: Pbhdr, t: var TLSF, fl, sl: int) {.inline.} =
|
||||
t.matrix[fl][sl] = b.freePtr.next
|
||||
if t.matrix[fl][sl] != 0:
|
||||
t.matrix[fl][sl].freePtr.prev = nil
|
||||
else:
|
||||
clear_bit(sl, t.slBitmap[fl])
|
||||
if t.slBitmap[fl] == 0:
|
||||
clear_bit(fl, t.flBitmap)
|
||||
b.freePtr.prev = nil
|
||||
b.freePtr.next = nil
|
||||
|
||||
proc extractBlock(b: Pbhdr, t: var TLSF, fl, sl: int) {.inline.} =
|
||||
if b.freePtr.next != nil:
|
||||
b.freePtr.next.freePtr.prev = b.freePtr.prev
|
||||
if b.freePtr.prev != nil:
|
||||
b.freePtr.prev.freePtr.next = b.freePtr.next
|
||||
if t.matrix[fl][sl] == b:
|
||||
t.matrix[fl][sl] = b.freePtr.next
|
||||
if t.matrix[fl][sl] == nil:
|
||||
clear_bit(sl, t.slBitmap[fl])
|
||||
if t.slBitmap[fl] == 0:
|
||||
clear_bit(fl, t.flBitmap)
|
||||
b.freePtr.prev = nil
|
||||
b.freePtr.next = nil
|
||||
|
||||
proc insertBlock(b: Pbhdr, t: var TLSF, fl, sl: int) {.inline.} =
|
||||
b.freePtr.prev = nil
|
||||
b.freePtr.next = t.matrix[fl][sl]
|
||||
if t.matrix[fl][sl] != 0:
|
||||
t.matrix[fl][sl].freePtr.prev = b
|
||||
t.matrix[fl][sl] = b
|
||||
set_bit(sl, t.slBitmap[fl])
|
||||
set_bit(fl, t.flBitmap)
|
||||
|
||||
proc getBuffer(b: Pbhdr): pointer {.inline.} =
|
||||
result = cast[pointer](addr(b.freePtr))
|
||||
|
||||
proc processArea(area: pointer, size: int): Pbhdr =
|
||||
var
|
||||
b, lb, ib: Pbhdr
|
||||
ai: PAreaInfo
|
||||
ib = cast[Pbhdr](area)
|
||||
if sizeof(TAreaInfo) < minBlockSize:
|
||||
ib.size = minBlockSize or usedBlock or prevUsed
|
||||
else
|
||||
ib.size = roundupSize(sizeof(TAreaInfo)) or usedBlock or prevUsed
|
||||
b = getNextBlock(getBuffer(ib), ib.size and blockSize)
|
||||
b.size = rounddownSize(size - 3 * bhdrOverhead - (ib.size and blockSize)) or
|
||||
usedBlock or prevUsed
|
||||
b.freePtr.prev = nil
|
||||
b.freePtr.next = nil
|
||||
lb = getNextBlock(getBuffer(b), b.size and blockSize)
|
||||
lb.prevHdr = b
|
||||
lb.size = 0 or usedBlock or prevFree
|
||||
ai = cast[PAreaInfo](getBuffer(ib))
|
||||
ai.next = nil
|
||||
ai.theEnd = lb
|
||||
return ib
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Begin of the allocator code
|
||||
|
||||
var
|
||||
mp: pointer # default memory pool.
|
||||
|
||||
proc initMemoryPool(memPoolSize: int, memPool: pointer): int =
|
||||
var
|
||||
t: PLSF
|
||||
b, ib: Pbhdr
|
||||
|
||||
if memPool == nil or memPoolSize < sizeof(TLSF) + bhdrOverhead * 8:
|
||||
writeToStdErr("initMemoryPool(): memory_pool invalid\n")
|
||||
return -1
|
||||
|
||||
if (memPool and ptrMask) != 0:
|
||||
writeToStdErr("initMemoryPool(): memPool must be aligned to a word\n")
|
||||
return -1
|
||||
t = cast[PLSF](memPool)
|
||||
# Check if already initialised
|
||||
if t.signature == tlsfSignature:
|
||||
mp = memPool
|
||||
b = getNextBlock(mp, roundupSize(sizeof(TLSF)))
|
||||
return b.size and blockSize
|
||||
mp = memPool
|
||||
zeroMem(memPool, sizeof(TLSF))
|
||||
|
||||
t.signature = tlsfSignature
|
||||
ib = processArea(getNextBlock(memPool, roundupSize(sizeof(TLSF))),
|
||||
rounddownSize(memPoolSize - sizeof(TLSF)))
|
||||
b = getNextBlock(getBuffer(ib), ib.size and blockSize)
|
||||
freeEx(getBuffer(b), t)
|
||||
t.areaHead = cast[PAreaInfo](getBuffer(ib))
|
||||
|
||||
t.used_size = memPoolSize - (b.size and blockSize)
|
||||
t.max_size = t.used_size
|
||||
return b.size and blockSize
|
||||
|
||||
|
||||
proc addNewArea(area: pointer, areaSize: int, t: var TLSF): int =
|
||||
var
|
||||
p, ptrPrev, ai: PAreaInfo
|
||||
ib0, b0, lb0, ib1, b1, lb1, nextB: Pbhdr
|
||||
|
||||
zeroMem(area, areaSize)
|
||||
p = t.areaHead
|
||||
ptrPrev = 0
|
||||
|
||||
ib0 = processArea(area, areaSize)
|
||||
b0 = getNextBlock(getBuffer(ib0), ib0.size and blockSize)
|
||||
lb0 = getNextBlock(getBuffer(b0), b0.size and blockSize)
|
||||
|
||||
# Before inserting the new area, we have to merge this area with the
|
||||
# already existing ones
|
||||
while p != nil:
|
||||
ib1 = cast[Pbhdr](cast[TAddress](p) -% bhdrOverhead)
|
||||
b1 = getNextBlock(getBuffer(ib1), ib1.size and blockSize)
|
||||
lb1 = p.theEnd
|
||||
|
||||
# Merging the new area with the next physically contigous one
|
||||
if cast[TAddress](ib1) == cast[TAddress](lb0) +% bhdrOverhead:
|
||||
if t.areaHead == p:
|
||||
t.areaHead = p.next
|
||||
p = p.next
|
||||
else:
|
||||
ptrPrev.next = p.next
|
||||
p = p.next
|
||||
b0.size = rounddownSize((b0.size and blockSize) +
|
||||
(ib1.size and blockSize) + 2 * bhdrOverhead) or
|
||||
usedBlock or prevUsed
|
||||
b1.prevHdr = b0
|
||||
lb0 = lb1
|
||||
continue
|
||||
|
||||
# Merging the new area with the previous physically contigous one
|
||||
if getBuffer(lb1) == pointer(ib0):
|
||||
if t.areaHead == p:
|
||||
t.areaHead = p.next
|
||||
p = p.next
|
||||
else:
|
||||
ptrPrev.next = p.next
|
||||
p = p.next
|
||||
lb1->size = rounddownSize((b0.size and blockSize) +
|
||||
(ib0.size and blockSize) + 2 * bhdrOverhead) or
|
||||
usedBlock or (lb1.size and prevState)
|
||||
nextB = getNextBlock(getBuffer(lb1), lb1.size and blockSize)
|
||||
nextB.prevHdr = lb1
|
||||
b0 = lb1
|
||||
ib0 = ib1
|
||||
continue
|
||||
ptrPrev = p
|
||||
p = p.next
|
||||
|
||||
# Inserting the area in the list of linked areas
|
||||
ai = cast[PAreaInfo](getBuffer(ib0))
|
||||
ai.next = t.areaHead
|
||||
ai.theEnd = lb0
|
||||
t.areaHead = ai
|
||||
freeEx(getBuffer(b0), memPool)
|
||||
return (b0.size and blockSize)
|
||||
|
||||
proc mallocEx(asize: int, t: var TLSF): pointer =
|
||||
var
|
||||
b, b2, nextB: Pbhdr
|
||||
fl, sl, tmpSize, size: int
|
||||
|
||||
size = if asize < minBlockSize: minBlockSize else: roundupSize(asize)
|
||||
|
||||
# Rounding up the requested size and calculating fl and sl
|
||||
mappingSearch(size, fl, sl)
|
||||
|
||||
# Searching a free block, recall that this function changes the values
|
||||
# of fl and sl, so they are not longer valid when the function fails
|
||||
b = findSuitableBlock(tlsf, fl, sl)
|
||||
if b == nil:
|
||||
# Growing the pool size when needed
|
||||
# size plus enough room for the required headers:
|
||||
var areaSize = max(size + bhdrOverhead * 8, defaultAreaSize)
|
||||
var area = getNewArea(areaSize)
|
||||
addNewArea(area, areaSize, t)
|
||||
# Rounding up the requested size and calculating fl and sl
|
||||
mappingSearch(size, fl, sl)
|
||||
# Searching a free block
|
||||
b = findSuitableBlock(t, fl, sl)
|
||||
if b == nil:
|
||||
raiseOutOfMem()
|
||||
|
||||
extractBlockHdr(b, t, fl, sl)
|
||||
|
||||
#-- found:
|
||||
nextB = getNextBlock(getBuffer(b), b.size and blockSize)
|
||||
# Should the block be split?
|
||||
tmpSize = (b.size and blockSize) - size
|
||||
if tmpSize >= sizeof(Tbhdr):
|
||||
dec(tmpSize, bhdrOverhead)
|
||||
b2 = getNextBlock(getBuffer(b), size)
|
||||
b2.size = tmpSize or freeBlock or prevUsed
|
||||
nextB.prevHdr = b2
|
||||
mappingInsert(tmpSize, fl, sl)
|
||||
insertBlock(b2, t, fl, sl)
|
||||
|
||||
b.size = size or (b.size and prevState)
|
||||
else:
|
||||
nextB.size = nextB.size and not prevFree
|
||||
b.size = b.size and not freeBlock # Now it's used
|
||||
|
||||
addSize(t, b)
|
||||
return getBuffer(b)
|
||||
|
||||
|
||||
proc freeEx(p: pointer, t: var TLSF) =
|
||||
var
|
||||
fl = 0
|
||||
sl = 0
|
||||
b, tmpB: Pbhdr
|
||||
|
||||
assert(p != nil)
|
||||
b = cast[Pbhdr](cast[TAddress](p) -% bhdrOverhead)
|
||||
b.size = b.size or freeBlock
|
||||
|
||||
removeSize(t, b)
|
||||
b.freePtr.prev = nil
|
||||
b.freePtr.next = nil
|
||||
tmpB = getNextBlock(getBuffer(b), b.size and blockSize)
|
||||
if tmpB.size and freeBlock != 0:
|
||||
mappingInsert(tmpB.size and blockSize, fl, sl)
|
||||
extractBlock(tmpB, t, fl, sl)
|
||||
inc(b.size, (tmpB.size and blockSize) + bhdrOverhead)
|
||||
if (b.size and prevFree) != 0:
|
||||
tmpB = b.prevHdr
|
||||
mappingInsert(tmpB.size and blockSize, fl, sl)
|
||||
extractBlock(tmpB, t, fl, sl)
|
||||
inc(tmpB.size, (b.size and blockSize) + bhdrOverhead)
|
||||
b = tmpB
|
||||
mappingInsert(b.size and blockSize, fl, sl)
|
||||
insertBlock(b, t, fl, sl)
|
||||
|
||||
tmpB = getNextBlock(getBuffer(b), b.size and blockSize)
|
||||
tmpB.size = tmpB.size or prevFree
|
||||
tmpB.prevHdr = b
|
||||
|
||||
proc reallocEx(p: pointer, newSize: int, t: var TLSF): pointer =
|
||||
var
|
||||
cpsize, fl, sl, tmpSize: int
|
||||
b, tmpB, nextB: Pbhdr
|
||||
|
||||
assert(p != nil)
|
||||
assert(newSize > 0)
|
||||
|
||||
b = cast[Pbhdr](cast[TAddress](p) -% bhdrOverhead)
|
||||
nextB = getNextBlock(getBuffer(b), b.size and blockSize)
|
||||
newSize = if newSize < minBlockSize: minBlockSize else: roundupSize(newSize)
|
||||
tmpSize = b.size and blockSize
|
||||
if newSize <= tmpSize:
|
||||
removeSize(t, b)
|
||||
if (nextB.size and freeBlock) != 0:
|
||||
mappingInsert(nextB.size and blockSize, fl, sl)
|
||||
extractBlock(nextB, t, fl, sl)
|
||||
inc(tmpSize, (nextB.size and blockSize) + bhdrOverhead)
|
||||
nextB = getNextBlock(getBuffer(nextB), nextB.size and blockSize)
|
||||
# We always reenter this free block because tmpSize will
|
||||
# be greater then sizeof(Tbhdr)
|
||||
dec(tmpSize, newSize)
|
||||
if tmpSize >= sizeof(Tbhdr):
|
||||
dec(tmpSize, bhdrOverhead)
|
||||
tmpB = getNextBlock(getBuffer(b), newSize)
|
||||
tmpB.size = tmpSize or freeBlock or prevUsed
|
||||
nextB.prevHdr = tmpB
|
||||
nextB.size = nextB.size or prevFree
|
||||
mappingInsert(tmpSize, fl, sl)
|
||||
insertBlock(tmpB, t, fl, sl)
|
||||
b.size = newSize or (b.size and prevState)
|
||||
addSize(t, b)
|
||||
return getBuffer(b)
|
||||
|
||||
if (nextB.size and freeBlock) != 0:
|
||||
if newSize <= tmpSize + (nextB.size and blockSize):
|
||||
removeSize(t, b)
|
||||
mappingInsert(nextB.size and blockSize, fl, sl)
|
||||
extractBlock(nextB, t, fl, sl)
|
||||
inc(b.size, (nextB.size and blockSize) + bhdrOverhead)
|
||||
nextB = getNextBlock(getBuffer(b), b.size and blockSize)
|
||||
nextB.prevHdr = b
|
||||
nextB.size = nextB.size and not prevFree
|
||||
tmpSize = (b.size and blockSize) - newSize
|
||||
if tmpSize >= sizeof(Tbhdr):
|
||||
dec(tmpSize, bhdrOverhead)
|
||||
tmpB = getNextBlock(getBuffer(b), newSize)
|
||||
tmpB.size = tmpSize or freeBlock or prevUsed
|
||||
nextB.prevHdr = tmpB
|
||||
nextB.size = nextB.size or prevFree
|
||||
mappingInsert(tmpSize, fl, sl)
|
||||
insertBlock(tmpB, t, fl, sl)
|
||||
b.size = newSize or (b.size and prevState)
|
||||
addSize(t, b)
|
||||
return getBuffer(b)
|
||||
|
||||
var ptrAux = mallocEx(newSize, t)
|
||||
cpsize = if (b.size and blockSize) > newSize: newSize else:
|
||||
(b.size and blockSize)
|
||||
copyMem(ptrAux, p, cpsize)
|
||||
freeEx(p, memPool)
|
||||
return ptrAux
|
||||
|
||||
|
||||
proc ansiCrealloc(p: pointer, newSize: int, t: var TLSF): pointer =
|
||||
if p == nil:
|
||||
if newSize > 0:
|
||||
result = mallocEx(newSize, t)
|
||||
else:
|
||||
result = nil
|
||||
elif newSize <= 0:
|
||||
freeEx(p, t)
|
||||
result = nil
|
||||
else:
|
||||
result = reallocEx(p, newSize, t)
|
||||
|
||||
|
||||
void *tlsf_malloc(size_t size)
|
||||
{
|
||||
void *ret
|
||||
|
||||
#if USE_MMAP || USE_SBRK
|
||||
if (!mp) {
|
||||
size_t areaSize
|
||||
void *area
|
||||
|
||||
areaSize = sizeof(tlsf_t) + BHDR_OVERHEAD * 8 # Just a safety constant
|
||||
areaSize = (areaSize > DEFAULT_areaSize) ? areaSize : DEFAULT_areaSize
|
||||
area = get_new_area(&areaSize)
|
||||
if (area == ((void *) ~0))
|
||||
return NULL # Not enough system memory
|
||||
initMemoryPool(areaSize, area)
|
||||
}
|
||||
#endif
|
||||
|
||||
TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock)
|
||||
|
||||
ret = malloc_ex(size, mp)
|
||||
|
||||
TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock)
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
void tlsf_free(void *p)
|
||||
{
|
||||
TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock)
|
||||
free_ex(p, mp)
|
||||
TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock)
|
||||
}
|
||||
|
||||
void *tlsf_realloc(void *p, size_t size)
|
||||
{
|
||||
void *ret
|
||||
#if USE_MMAP || USE_SBRK
|
||||
if (!mp) {
|
||||
return tlsf_malloc(size)
|
||||
}
|
||||
#endif
|
||||
TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock)
|
||||
ret = realloc_ex(p, size, mp)
|
||||
TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock)
|
||||
return ret
|
||||
}
|
||||
403
lib/nimbase.h
Executable file
403
lib/nimbase.h
Executable file
|
|
@ -0,0 +1,403 @@
|
|||
/*
|
||||
|
||||
Nimrod's Runtime Library
|
||||
(c) Copyright 2006 Andreas Rumpf
|
||||
|
||||
See the file "copying.txt", included in this
|
||||
distribution, for details about the copyright.
|
||||
*/
|
||||
|
||||
#ifndef NIMBASE_H
|
||||
#define NIMBASE_H
|
||||
|
||||
/* calling convention mess ----------------------------------------------- */
|
||||
#if defined(__GNUC__) || defined(__LCC__) || defined(__POCC__)
|
||||
/* these should support C99's inline */
|
||||
/* the test for __POCC__ has to come before the test for _MSC_VER,
|
||||
because PellesC defines _MSC_VER too. This is brain-dead. */
|
||||
# define N_INLINE(rettype, name) inline rettype name
|
||||
#elif defined(__BORLANDC__) || defined(_MSC_VER)
|
||||
/* Borland's compiler is really STRANGE here; note that the __fastcall
|
||||
keyword cannot be before the return type, but __inline cannot be after
|
||||
the return type, so we do not handle this mess in the code generator
|
||||
but rather here. */
|
||||
# define N_INLINE(rettype, name) __inline rettype name
|
||||
#elif defined(__DMC__)
|
||||
# define N_INLINE(rettype, name) inline rettype name
|
||||
#elif defined(__WATCOMC__)
|
||||
# define N_INLINE(rettype, name) __inline rettype name
|
||||
#else /* others are less picky: */
|
||||
# define N_INLINE(rettype, name) rettype __inline name
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# define HAVE_LRINT 1
|
||||
#endif
|
||||
|
||||
/* --------------- how int64 constants should be declared: ----------- */
|
||||
#if defined(__GNUC__) || defined(__LCC__) || \
|
||||
defined(__POCC__) || defined(__DMC__)
|
||||
# define IL64(x) x##LL
|
||||
#else /* works only without LL */
|
||||
# define IL64(x) x
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32) /* only Windows has this mess... */
|
||||
# define N_CDECL(rettype, name) rettype __cdecl name
|
||||
# define N_STDCALL(rettype, name) rettype __stdcall name
|
||||
# define N_SYSCALL(rettype, name) rettype __syscall name
|
||||
# define N_FASTCALL(rettype, name) rettype __fastcall name
|
||||
# define N_SAFECALL(rettype, name) rettype __safecall name
|
||||
/* function pointers with calling convention: */
|
||||
# define N_CDECL_PTR(rettype, name) rettype (__cdecl *name)
|
||||
# define N_STDCALL_PTR(rettype, name) rettype (__stdcall *name)
|
||||
# define N_SYSCALL_PTR(rettype, name) rettype (__syscall *name)
|
||||
# define N_FASTCALL_PTR(rettype, name) rettype (__fastcall *name)
|
||||
# define N_SAFECALL_PTR(rettype, name) rettype (__safecall *name)
|
||||
|
||||
# define N_LIB_EXPORT __declspec(dllexport)
|
||||
# define N_LIB_IMPORT __declspec(dllimport)
|
||||
#else
|
||||
# define N_CDECL(rettype, name) rettype name
|
||||
# define N_STDCALL(rettype, name) rettype name
|
||||
# define N_SYSCALL(rettype, name) rettype name
|
||||
# define N_FASTCALL(rettype, name) rettype name
|
||||
# define N_SAFECALL(rettype, name) rettype name
|
||||
/* function pointers with calling convention: */
|
||||
# define N_CDECL_PTR(rettype, name) rettype (*name)
|
||||
# define N_STDCALL_PTR(rettype, name) rettype (*name)
|
||||
# define N_SYSCALL_PTR(rettype, name) rettype (*name)
|
||||
# define N_FASTCALL_PTR(rettype, name) rettype (*name)
|
||||
# define N_SAFECALL_PTR(rettype, name) rettype (*name)
|
||||
|
||||
# define N_LIB_EXPORT
|
||||
# define N_LIB_IMPORT extern
|
||||
#endif
|
||||
|
||||
#define N_NOCONV(rettype, name) rettype name
|
||||
/* specify no calling convention */
|
||||
#define N_NOCONV_PTR(rettype, name) rettype (*name)
|
||||
|
||||
#define N_CLOSURE(rettype, name) rettype name
|
||||
/* specify no calling convention */
|
||||
#define N_CLOSURE_PTR(rettype, name) rettype (*name)
|
||||
|
||||
|
||||
#if defined(__BORLANDC__) || defined(__WATCOMC__) || \
|
||||
defined(__POCC__) || defined(_MSC_VER)
|
||||
/* these compilers have a fastcall so use it: */
|
||||
# define N_NIMCALL(rettype, name) rettype __fastcall name
|
||||
# define N_NIMCALL_PTR(rettype, name) rettype (__fastcall *name)
|
||||
#else
|
||||
# define N_NIMCALL(rettype, name) rettype name /* no modifier */
|
||||
# define N_NIMCALL_PTR(rettype, name) rettype (*name)
|
||||
#endif
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
/* from float_cast.h: */
|
||||
|
||||
/*
|
||||
** Copyright (C) 2001 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
|
||||
**
|
||||
** Permission to use, copy, modify, distribute, and sell this file for any
|
||||
** purpose is hereby granted without fee, provided that the above copyright
|
||||
** and this permission notice appear in all copies. No representations are
|
||||
** made about the suitability of this software for any purpose. It is
|
||||
** provided "as is" without express or implied warranty.
|
||||
*/
|
||||
|
||||
/* Version 1.1 */
|
||||
|
||||
|
||||
/*============================================================================
|
||||
** On Intel Pentium processors (especially PIII and probably P4), converting
|
||||
** from float to int is very slow. To meet the C specs, the code produced by
|
||||
** most C compilers targeting Pentium needs to change the FPU rounding mode
|
||||
** before the float to int conversion is performed.
|
||||
**
|
||||
** Changing the FPU rounding mode causes the FPU pipeline to be flushed. It
|
||||
** is this flushing of the pipeline which is so slow.
|
||||
**
|
||||
** Fortunately the ISO C99 specifications define the functions lrint, lrintf,
|
||||
** llrint and llrintf which fix this problem as a side effect.
|
||||
**
|
||||
** On Unix-like systems, the configure process should have detected the
|
||||
** presence of these functions. If they weren't found we have to replace them
|
||||
** here with a standard C cast.
|
||||
*/
|
||||
|
||||
/*
|
||||
** The C99 prototypes for lrint and lrintf are as follows:
|
||||
**
|
||||
** long int lrintf (float x);
|
||||
** long int lrint (double x);
|
||||
*/
|
||||
|
||||
#if defined(__LCC__) || defined(__POCC__) \
|
||||
|| (defined(__GNUC__) && defined(WIN32))
|
||||
/* Linux' GCC does not seem to have these. Why? */
|
||||
# define HAVE_LRINT
|
||||
# define HAVE_LRINTF
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LRINT) && defined(HAVE_LRINTF)
|
||||
|
||||
/* These defines enable functionality introduced with the 1999 ISO C
|
||||
** standard. They must be defined before the inclusion of math.h to
|
||||
** engage them. If optimisation is enabled, these functions will be
|
||||
** inlined. With optimisation switched off, you have to link in the
|
||||
** maths library using -lm.
|
||||
*/
|
||||
|
||||
# define _ISOC9X_SOURCE 1
|
||||
# define _ISOC99_SOURCE 1
|
||||
# define __USE_ISOC9X 1
|
||||
# define __USE_ISOC99 1
|
||||
# include <math.h>
|
||||
|
||||
#elif (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) \
|
||||
&& !defined(__BORLANDC__)
|
||||
|
||||
# include <math.h>
|
||||
|
||||
/* Win32 doesn't seem to have these functions.
|
||||
** Therefore implement inline versions of these functions here.
|
||||
*/
|
||||
static N_INLINE(long int, lrint)(double flt) {
|
||||
long int intgr;
|
||||
_asm {
|
||||
fld flt
|
||||
fistp intgr
|
||||
};
|
||||
return intgr;
|
||||
}
|
||||
|
||||
static N_INLINE(long int, lrintf)(float flt) {
|
||||
long int intgr;
|
||||
_asm {
|
||||
fld flt
|
||||
fistp intgr
|
||||
};
|
||||
return intgr;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
# include <math.h>
|
||||
|
||||
# ifndef lrint
|
||||
# define lrint(dbl) ((long int)(dbl))
|
||||
# endif
|
||||
# ifndef lrintf
|
||||
# define lrintf(flt) ((long int)(flt))
|
||||
# endif
|
||||
|
||||
#endif /* defined(HAVE_LRINT) && defined(HAVE_LRINTF) */
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
/* compiler symbols:
|
||||
__BORLANDC__
|
||||
_MSC_VER
|
||||
__WATCOMC__
|
||||
__LCC__
|
||||
__GNUC__
|
||||
__DMC__
|
||||
__POCC__
|
||||
*/
|
||||
|
||||
/* C99 compiler? */
|
||||
#if (defined(__STD_VERSION__) && (__STD_VERSION__ >= 199901))
|
||||
# define HAVE_STDINT_H
|
||||
#endif
|
||||
|
||||
#if defined(__LCC__) || defined(__GNUC__) || defined(__DMC__) \
|
||||
|| defined(__POCC__)
|
||||
# define HAVE_STDINT_H
|
||||
#endif
|
||||
|
||||
/* bool types (C++ has it): */
|
||||
#ifdef __cplusplus
|
||||
# ifndef NIM_TRUE
|
||||
# define NIM_TRUE true
|
||||
# endif
|
||||
# ifndef NIM_FALSE
|
||||
# define NIM_FALSE false
|
||||
# endif
|
||||
# define NIM_BOOL bool
|
||||
#else
|
||||
# ifdef bool
|
||||
# define NIM_BOOL bool
|
||||
# else
|
||||
typedef unsigned char NIM_BOOL;
|
||||
# endif
|
||||
# ifndef NIM_TRUE
|
||||
# define NIM_TRUE ((NIM_BOOL) 1)
|
||||
# endif
|
||||
# ifndef NIM_FALSE
|
||||
# define NIM_FALSE ((NIM_BOOL) 0)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define NIM_NIL ((void*)0) /* C's NULL is fucked up in some C compilers, so
|
||||
the generated code does not rely on it anymore */
|
||||
|
||||
#if defined(HAVE_STDINT_H)
|
||||
# include <stdint.h>
|
||||
typedef int8_t NS8;
|
||||
typedef int16_t NS16;
|
||||
typedef int32_t NS32;
|
||||
typedef int64_t NS64;
|
||||
typedef uint64_t NU64;
|
||||
typedef uint8_t NU8;
|
||||
typedef uint16_t NU16;
|
||||
typedef uint32_t NU32;
|
||||
#elif defined(__BORLANDC__) || defined(__DMC__) \
|
||||
|| defined(__WATCOMC__) || defined(_MSC_VER)
|
||||
typedef signed char NS8;
|
||||
typedef signed short int NS16;
|
||||
typedef signed int NS32;
|
||||
/* XXX: Float128? */
|
||||
typedef unsigned char NU8;
|
||||
typedef unsigned short int NU16;
|
||||
typedef unsigned __int64 NU64;
|
||||
typedef __int64 NS64;
|
||||
typedef unsigned int NU32;
|
||||
#else
|
||||
typedef signed char NS8;
|
||||
typedef signed short int NS16;
|
||||
typedef signed int NS32;
|
||||
/* XXX: Float128? */
|
||||
typedef unsigned char NU8;
|
||||
typedef unsigned short int NU16;
|
||||
typedef unsigned long long int NU64;
|
||||
typedef long long int NS64;
|
||||
typedef unsigned int NU32;
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && (defined(AMD64) || defined(_M_AMD64))
|
||||
/* Microsoft C is brain-dead in this case; long is still not an int64 */
|
||||
typedef unsigned long long int NU;
|
||||
typedef signed long long int NS;
|
||||
#else
|
||||
typedef unsigned long int NU; /* note: int would be wrong for AMD64 */
|
||||
typedef signed long int NS;
|
||||
#endif
|
||||
|
||||
typedef float NF32;
|
||||
typedef double NF64;
|
||||
typedef double NF;
|
||||
|
||||
typedef char NIM_CHAR;
|
||||
typedef char* NCSTRING;
|
||||
|
||||
#ifdef NIM_BIG_ENDIAN
|
||||
# define NIM_IMAN 1
|
||||
#else
|
||||
# define NIM_IMAN 0
|
||||
#endif
|
||||
|
||||
static N_INLINE(NS32, float64ToInt32)(double val) {
|
||||
val = val + 68719476736.0*1.5;
|
||||
/* 2^36 * 1.5, (52-_shiftamt=36) uses limited precisicion to floor */
|
||||
return ((NS32*)&val)[NIM_IMAN] >> 16; /* 16.16 fixed point representation */
|
||||
}
|
||||
|
||||
static N_INLINE(NS32, float32ToInt32)(float val) {
|
||||
return float64ToInt32((double)val);
|
||||
}
|
||||
|
||||
#define zeroMem(a, size) memset(a, 0, size)
|
||||
#define equalMem(a, b, size) (memcmp(a, b, size) == 0)
|
||||
|
||||
#define STRING_LITERAL(name, str, length) \
|
||||
static const struct { \
|
||||
NS len, space; \
|
||||
NIM_CHAR data[length + 1]; \
|
||||
} name = {length, length, str}
|
||||
|
||||
typedef struct TStringDesc* string;
|
||||
|
||||
/* declared size of a sequence: */
|
||||
#if defined(__GNUC__)
|
||||
# define SEQ_DECL_SIZE /* empty is correct! */
|
||||
#else
|
||||
# define SEQ_DECL_SIZE 1000000
|
||||
#endif
|
||||
|
||||
#define ALLOC_0(size) calloc(1, size)
|
||||
#define DL_ALLOC_0(size) dlcalloc(1, size)
|
||||
|
||||
#define GenericSeqSize sizeof(TGenericSeq)
|
||||
#define paramCount() cmdCount
|
||||
|
||||
#ifndef NAN
|
||||
# define NAN (0.0 / 0.0)
|
||||
#endif
|
||||
|
||||
#ifndef INF
|
||||
# ifdef INFINITY
|
||||
# define INF INFINITY
|
||||
# elif defined(HUGE_VAL)
|
||||
# define INF HUGE_VAL
|
||||
# else
|
||||
# define INF (1.0 / 0.0)
|
||||
# endif
|
||||
#endif
|
||||
/*
|
||||
typedef struct TSafePoint TSafePoint;
|
||||
struct TSafePoint {
|
||||
NS exc;
|
||||
NCSTRING excname;
|
||||
NCSTRING msg;
|
||||
TSafePoint* prev;
|
||||
jmp_buf context;
|
||||
}; */
|
||||
|
||||
typedef struct TFrame TFrame;
|
||||
struct TFrame {
|
||||
TFrame* prev;
|
||||
NCSTRING procname;
|
||||
NS line;
|
||||
NCSTRING filename;
|
||||
NS len;
|
||||
};
|
||||
|
||||
extern TFrame* volatile framePtr;
|
||||
/*extern TSafePoint* volatile excHandler; */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
struct NimException {
|
||||
TSafePoint sp;
|
||||
|
||||
NimException(NS aExc, NCSTRING aExcname, NCSTRING aMsg) {
|
||||
sp.exc = aExc; sp.excname = aExcname; sp.msg = aMsg;
|
||||
sp.prev = excHandler;
|
||||
excHandler = &sp;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef struct TStringDesc {
|
||||
NS len;
|
||||
NS space;
|
||||
NIM_CHAR data[1]; /* SEQ_DECL_SIZE]; */
|
||||
} TStringDesc;
|
||||
|
||||
typedef struct {
|
||||
NS len, space;
|
||||
} TGenericSeq;
|
||||
|
||||
typedef TGenericSeq* PGenericSeq;
|
||||
|
||||
#endif
|
||||
39
lib/optparse.nim
Executable file
39
lib/optparse.nim
Executable file
|
|
@ -0,0 +1,39 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
|
||||
## This module provides a command line parser.
|
||||
## It supports one iterator over all command line options.
|
||||
|
||||
#interface
|
||||
|
||||
{.push debugger: off.}
|
||||
|
||||
import
|
||||
os
|
||||
|
||||
proc findSep(s: string): int {.nostatic.} =
|
||||
for i in 0 .. high(s)-1:
|
||||
if s[i] in {'=', ':'}: return i
|
||||
return high(s)+1
|
||||
|
||||
iterator getopt*(): tuple[string, string] =
|
||||
# returns a (cmd, arg) tuple.
|
||||
for k in 1 .. ParamCount():
|
||||
var param = paramStr(k)
|
||||
if param[0] == '-':
|
||||
var j = findSep(param)
|
||||
cmd = copy(param, 0, j-1)
|
||||
arg = copy(param, j+1)
|
||||
else:
|
||||
cmd = ""
|
||||
arg = param
|
||||
yield cmd, arg
|
||||
|
||||
{.pop.}
|
||||
939
lib/os.nim
Executable file
939
lib/os.nim
Executable file
|
|
@ -0,0 +1,939 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
## Basic operating system facilities like retrieving environment variables,
|
||||
## reading command line arguments, working with directories, running shell
|
||||
## commands, etc. This module is -- like any other basic library --
|
||||
## platform independant.
|
||||
|
||||
{.push debugger:off.}
|
||||
|
||||
import
|
||||
strutils, times
|
||||
|
||||
# copied from excpt.nim, because I don't want to make this template public
|
||||
template newException(exceptn, message: expr): expr =
|
||||
block: # open a new scope
|
||||
var
|
||||
e: ref exceptn
|
||||
new(e)
|
||||
e.msg = message
|
||||
e
|
||||
|
||||
when defined(windows) or defined(OS2) or defined(DOS):
|
||||
{.define: doslike.} # DOS-like filesystem
|
||||
|
||||
when defined(Nimdoc): # only for proper documentation:
|
||||
const
|
||||
CurDir* = '.'
|
||||
## The constant string used by the operating system to refer to the
|
||||
## current directory.
|
||||
##
|
||||
## For example: '.' for POSIX or ':' for the classic Macintosh.
|
||||
|
||||
ParDir* = ".."
|
||||
## The constant string used by the operating system to refer to the parent
|
||||
## directory.
|
||||
##
|
||||
## For example: ".." for POSIX or "::" for the classic Macintosh.
|
||||
|
||||
DirSep* = '/'
|
||||
## The character used by the operating system to separate pathname
|
||||
## components, for example, '/' for POSIX or ':' for the classic
|
||||
## Macintosh.
|
||||
##
|
||||
## Note that knowing this is not sufficient to be able to parse or
|
||||
## concatenate pathnames -- use `splitPath` and `joinPath` instead --
|
||||
## but it is occasionally useful.
|
||||
|
||||
AltSep* = '/'
|
||||
## An alternative character used by the operating system to separate
|
||||
## pathname components, or the same as `DirSep` if only one separator
|
||||
## character exists. This is set to '/' on Windows systems where `DirSep`
|
||||
## is a backslash.
|
||||
|
||||
PathSep* = ':'
|
||||
## The character conventionally used by the operating system to separate
|
||||
## search patch components (as in PATH), such as ':' for POSIX or ';' for
|
||||
## Windows.
|
||||
|
||||
FileSystemCaseSensitive* = True
|
||||
## True if the file system is case sensitive, false otherwise. Used by
|
||||
## `cmpPaths` to compare filenames properly.
|
||||
|
||||
elif defined(macos):
|
||||
const
|
||||
curdir* = ':'
|
||||
pardir* = "::"
|
||||
dirsep* = ':'
|
||||
altsep* = dirsep
|
||||
pathsep* = ','
|
||||
FileSystemCaseSensitive* = false
|
||||
|
||||
# MacOS paths
|
||||
# ===========
|
||||
# MacOS directory separator is a colon ":" which is the only character not
|
||||
# allowed in filenames.
|
||||
#
|
||||
# A path containing no colon or which begins with a colon is a partial path.
|
||||
# E.g. ":kalle:petter" ":kalle" "kalle"
|
||||
#
|
||||
# All other paths are full (absolute) paths. E.g. "HD:kalle:" "HD:"
|
||||
# When generating paths, one is safe if one ensures that all partial paths
|
||||
# begin with a colon, and all full paths end with a colon.
|
||||
# In full paths the first name (e g HD above) is the name of a mounted
|
||||
# volume.
|
||||
# These names are not unique, because, for instance, two diskettes with the
|
||||
# same names could be inserted. This means that paths on MacOS is not
|
||||
# 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
|
||||
# grandparent etc.
|
||||
elif defined(doslike):
|
||||
const
|
||||
curdir* = '.'
|
||||
pardir* = ".."
|
||||
dirsep* = '\\' # seperator within paths
|
||||
altsep* = '/'
|
||||
pathSep* = ';' # seperator between paths
|
||||
FileSystemCaseSensitive* = false
|
||||
elif defined(PalmOS) or defined(MorphOS):
|
||||
const
|
||||
dirsep* = '/'
|
||||
altsep* = dirsep
|
||||
PathSep* = ';'
|
||||
pardir* = ".."
|
||||
FileSystemCaseSensitive* = false
|
||||
elif defined(RISCOS):
|
||||
const
|
||||
dirsep* = '.'
|
||||
altsep* = '.'
|
||||
pardir* = ".." # is this correct?
|
||||
pathSep* = ','
|
||||
FileSystemCaseSensitive* = true
|
||||
else: # UNIX-like operating system
|
||||
const
|
||||
curdir* = '.'
|
||||
pardir* = ".."
|
||||
dirsep* = '/'
|
||||
altsep* = dirsep
|
||||
pathSep* = ':'
|
||||
FileSystemCaseSensitive* = true
|
||||
|
||||
const
|
||||
ExtSep* = '.'
|
||||
## The character which separates the base filename from the extension;
|
||||
## for example, the '.' in ``os.nim``.
|
||||
|
||||
proc getApplicationDir*(): string {.noSideEffect.}
|
||||
## Gets the directory of the application's executable.
|
||||
|
||||
proc getApplicationFilename*(): string {.noSideEffect.}
|
||||
## Gets the filename of the application's executable.
|
||||
|
||||
proc getCurrentDir*(): string {.noSideEffect.}
|
||||
## Gets the current working directory.
|
||||
|
||||
proc setCurrentDir*(newDir: string) {.inline.}
|
||||
## Sets the current working directory; `EOS` is raised if
|
||||
## `newDir` cannot been set.
|
||||
|
||||
proc getHomeDir*(): string {.noSideEffect.}
|
||||
## Gets the home directory of the current user.
|
||||
|
||||
proc getConfigDir*(): string {.noSideEffect.}
|
||||
## Gets the config directory of the current user for applications.
|
||||
|
||||
proc expandFilename*(filename: string): string
|
||||
## Returns the full path of `filename`, "" on error.
|
||||
|
||||
proc ExistsFile*(filename: string): bool
|
||||
## Returns true if the file exists, false otherwise.
|
||||
|
||||
proc JoinPath*(head, tail: string): string {.noSideEffect.}
|
||||
## Joins two directory names to one.
|
||||
##
|
||||
## For example on Unix::
|
||||
##
|
||||
## JoinPath("usr", "lib")
|
||||
##
|
||||
## results in::
|
||||
##
|
||||
## "usr/lib"
|
||||
##
|
||||
## If head is the empty string, tail is returned.
|
||||
## If tail is the empty string, head is returned.
|
||||
|
||||
proc `/` * (head, tail: string): string {.noSideEffect.} =
|
||||
## The same as ``joinPath(head, tail)``
|
||||
return joinPath(head, tail)
|
||||
|
||||
proc JoinPath*(parts: openarray[string]): string {.noSideEffect.}
|
||||
## The same as `JoinPath(head, tail)`, but works with any number
|
||||
## of directory parts.
|
||||
|
||||
proc SplitPath*(path: string, head, tail: var string) {.noSideEffect.}
|
||||
## Splits a directory into (head, tail), so that
|
||||
## ``JoinPath(head, tail) == path``.
|
||||
##
|
||||
## Example: After ``SplitPath("usr/local/bin", head, tail)``,
|
||||
## `head` is "usr/local" and `tail` is "bin".
|
||||
## Example: After ``SplitPath("usr/local/bin/", head, tail)``,
|
||||
## `head` is "usr/local/bin" and `tail` is "".
|
||||
|
||||
proc parentDir*(path: string): string {.noSideEffect.}
|
||||
## Returns the parent directory of `path`.
|
||||
##
|
||||
## This is often the same as the ``head`` result of ``splitPath``.
|
||||
## If there is no parent, ``path`` is returned.
|
||||
## Example: ``parentDir("/usr/local/bin") == "/usr/local"``.
|
||||
## Example: ``parentDir("/usr/local/bin/") == "/usr/local"``.
|
||||
|
||||
proc `/../` * (head, tail: string): string {.noSideEffect.} =
|
||||
## The same as ``parentDir(head) / tail``
|
||||
return parentDir(head) / tail
|
||||
|
||||
proc UnixToNativePath*(path: string): string {.noSideEffect.}
|
||||
## Converts an UNIX-like path to a native one.
|
||||
##
|
||||
## On an UNIX system this does nothing. Else it converts
|
||||
## '/', '.', '..' to the appropriate things.
|
||||
|
||||
proc SplitFilename*(filename: string, name, extension: var string) {.
|
||||
noSideEffect.}
|
||||
## Splits a filename into (name, extension), so that
|
||||
## ``name & extension == filename``.
|
||||
##
|
||||
## Example: After ``SplitFilename("usr/local/nimrodc.html", name, ext)``,
|
||||
## `name` is "usr/local/nimrodc" and `ext` is ".html".
|
||||
## It the file has no extension, extention is the empty string.
|
||||
|
||||
proc extractDir*(path: string): string {.noSideEffect.}
|
||||
## Extracts the directory of a given path. This is the `head`
|
||||
## result of `splitPath`.
|
||||
|
||||
proc extractFilename*(path: string): string {.noSideEffect.}
|
||||
## Extracts the filename of a given `path`. This the the `tail`
|
||||
## result of `splitPath`.
|
||||
# XXX: this is not true: /usr/lib/ --> filename should be empty!
|
||||
|
||||
proc cmpPaths*(pathA, pathB: string): int {.noSideEffect.}
|
||||
## Compares two paths.
|
||||
##
|
||||
## On a case-sensitive filesystem this is done
|
||||
## case-sensitively otherwise case-insensitively. Returns:
|
||||
##
|
||||
## | 0 iff pathA == pathB
|
||||
## | < 0 iff pathA < pathB
|
||||
## | > 0 iff pathA > pathB
|
||||
|
||||
proc AppendFileExt*(filename, ext: string): string {.noSideEffect.}
|
||||
## Appends the file extension `ext` to the `filename`, even if
|
||||
## the `filename` already has an extension.
|
||||
##
|
||||
## `Ext` should be given without the leading '.', because some
|
||||
## filesystems may use a different character.
|
||||
## (Although I know of none such beast.)
|
||||
|
||||
proc ChangeFileExt*(filename, ext: string): string {.noSideEffect.}
|
||||
## Changes the file extension to `ext`.
|
||||
##
|
||||
## If the `filename` has no extension, `ext` will be added.
|
||||
## If `ext` == "" then the filename will get no extension.
|
||||
## `Ext` should be given without the leading '.', because some
|
||||
## filesystems may use a different character. (Although I know
|
||||
## 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
|
||||
## Executes a shell command.
|
||||
##
|
||||
## The syntax of the command is unspecified and depends on the used
|
||||
## shell. The proc returns the error code of the shell when it has finished.
|
||||
|
||||
# procs operating on a high level for files:
|
||||
proc copyFile*(dest, source: string)
|
||||
## Copies a file from `dest` to `source`. If this fails,
|
||||
## `EOS` is raised.
|
||||
|
||||
proc moveFile*(dest, source: string)
|
||||
## Moves a file from `dest` to `source`. If this fails, `EOS` is raised.
|
||||
|
||||
proc removeFile*(file: string)
|
||||
## Removes the `file`. If this fails, `EOS` is raised.
|
||||
|
||||
proc removeDir*(dir: string)
|
||||
## Removes the directory `dir` including all subdirectories or files
|
||||
## in `dir` (recursively). If this fails, `EOS` is raised.
|
||||
|
||||
proc createDir*(dir: string)
|
||||
## Creates the directory `dir`.
|
||||
##
|
||||
## The directory may contain several
|
||||
## subdirectories that do not exist yet. The full path is created. If this
|
||||
## fails, `EOS` is raised. It does NOT fail if the path already exists
|
||||
## because for most usages this does not indicate an error.
|
||||
|
||||
proc existsDir*(dir: string): bool
|
||||
## Returns true iff the directory `dir` exists. If `dir` is a file, false
|
||||
## is returned.
|
||||
|
||||
proc getLastModificationTime*(file: string): TTime
|
||||
## Gets the time of the `file`'s last modification.
|
||||
|
||||
# procs dealing with environment variables:
|
||||
proc putEnv*(key, val: string)
|
||||
## Sets the value of the environment variable named `key` to `val`.
|
||||
## If an error occurs, `EInvalidEnvVar` is raised.
|
||||
|
||||
proc getEnv*(key: string): string
|
||||
## Gets the value of the environment variable named `key`.
|
||||
##
|
||||
## If the variable does not exist, "" is returned. To distinguish
|
||||
## whether a variable exists or it's value is just "", call
|
||||
## `existsEnv(key)`.
|
||||
|
||||
proc existsEnv*(key: string): bool
|
||||
## Checks whether the environment variable named `key` exists.
|
||||
## Returns true if it exists, false otherwise.
|
||||
|
||||
# procs dealing with command line arguments:
|
||||
proc paramCount*(): int
|
||||
## Returns the number of command line arguments given to the
|
||||
## application.
|
||||
|
||||
proc paramStr*(i: int): string
|
||||
## Returns the `i`-th command line arguments given to the
|
||||
## application.
|
||||
##
|
||||
## `i` should be in the range `1..paramCount()`, else
|
||||
## the `EOutOfIndex` exception is raised.
|
||||
|
||||
# implementation
|
||||
|
||||
proc UnixToNativePath(path: string): string =
|
||||
when defined(unix):
|
||||
result = path
|
||||
else:
|
||||
var start: int
|
||||
if path[0] == '/':
|
||||
# an absolute path
|
||||
when defined(doslike):
|
||||
result = r"C:\"
|
||||
elif defined(macos):
|
||||
result = "" # must not start with ':'
|
||||
else:
|
||||
result = $dirSep
|
||||
start = 1
|
||||
elif path[0] == '.' and path[1] == '/':
|
||||
# current directory
|
||||
result = $curdir
|
||||
start = 2
|
||||
else:
|
||||
result = ""
|
||||
start = 0
|
||||
|
||||
var i = start
|
||||
while i < len(path): # ../../../ --> ::::
|
||||
if path[i] == '.' and path[i+1] == '.' and path[i+2] == '/':
|
||||
# parent directory
|
||||
when defined(macos):
|
||||
if result[high(result)] == ':':
|
||||
add result, ':'
|
||||
else:
|
||||
add result, pardir
|
||||
else:
|
||||
add result, pardir & dirSep
|
||||
inc(i, 3)
|
||||
elif path[i] == '/':
|
||||
add result, dirSep
|
||||
inc(i)
|
||||
else:
|
||||
add result, $path[i]
|
||||
inc(i)
|
||||
|
||||
# interface to C library:
|
||||
|
||||
type
|
||||
TStat {.importc: "struct stat".} = record
|
||||
st_dev: int16
|
||||
st_ino: int16
|
||||
st_mode: int16
|
||||
st_nlink: int16
|
||||
st_uid: int16
|
||||
st_gid: int16
|
||||
st_rdev: int32
|
||||
st_size: int32
|
||||
st_atime: TTime
|
||||
st_mtime: TTime
|
||||
st_ctime: TTime
|
||||
|
||||
var
|
||||
errno {.importc: "errno", 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: "chdir", header: dirHeader.}
|
||||
|
||||
when defined(unix):
|
||||
proc mkdir(dir: CString, theAccess: cint): cint {.
|
||||
importc: "mkdir", header: dirHeader.}
|
||||
proc realpath(name, resolved: CString): CString {.
|
||||
importc: "realpath", header: "<stdlib.h>".}
|
||||
proc getcwd(buf: CString, buflen: cint): CString {.
|
||||
importc: "getcwd", header: "<unistd.h>".}
|
||||
elif defined(windows):
|
||||
proc mkdir(dir: CString): cint {.
|
||||
importc: "mkdir", header: dirHeader.}
|
||||
proc fullpath(buffer, file: CString, size: int): CString {.
|
||||
importc: "_fullpath", header: "<stdlib.h>".}
|
||||
proc getcwd(buf: CString, buflen: cint): CString {.
|
||||
importc: "getcwd", header: "<direct.h>".}
|
||||
|
||||
proc CreateDirectory(pathName: cstring, security: Pointer): cint {.
|
||||
importc: "CreateDirectory", header: "<windows.h>".}
|
||||
proc GetLastError(): cint {.importc, header: "<windows.h>".}
|
||||
else:
|
||||
{.error: "os library not ported to your OS. Please help!".}
|
||||
|
||||
|
||||
proc rmdir(dir: CString): cint {.importc: "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.}
|
||||
# some C procs return a buffer that has to be freed with free(),
|
||||
# so we define it here
|
||||
proc strlen(str: CString): int {.importc: "strlen", nodecl.}
|
||||
|
||||
proc stat(f: CString, res: var TStat): cint {.
|
||||
importc: "stat", header: "<sys/stat.h>".}
|
||||
|
||||
proc sameFile*(path1, path2: string): bool =
|
||||
## Returns True if both pathname arguments refer to the same file or
|
||||
## directory (as indicated by device number and i-node number).
|
||||
## Raises an exception if an os.stat() call on either pathname fails.
|
||||
var
|
||||
a, b: TStat
|
||||
if stat(path1, a) < 0 or stat(path2, b) < 0:
|
||||
raise newException(EOS, "stat() call failed")
|
||||
return int(a.st_dev) == b.st_dev and int(a.st_ino) == b.st_ino
|
||||
|
||||
when defined(windows):
|
||||
proc getModuleFilename(handle: int32, buf: CString, size: int32): int32 {.
|
||||
importc: "GetModuleFileName", header: "<windows.h>".}
|
||||
|
||||
proc getLastModificationTime(file: string): TTime =
|
||||
var
|
||||
res: TStat
|
||||
discard stat(file, res)
|
||||
return res.st_mtime
|
||||
|
||||
proc setCurrentDir(newDir: string) =
|
||||
if chdir(newDir) != 0:
|
||||
raise newException(EOS, "cannot change the working directory to '$1'" %
|
||||
newDir)
|
||||
|
||||
when defined(linux) or defined(solaris) or defined(bsd):
|
||||
proc readlink(link, buf: cstring, size: int): int {.
|
||||
header: "<unistd.h>", cdecl.}
|
||||
|
||||
proc getApplAux(procPath: string): string =
|
||||
result = newString(256)
|
||||
var len = readlink(procPath, result, 256)
|
||||
if len > 256:
|
||||
result = newString(len+1)
|
||||
len = readlink(procPath, result, len)
|
||||
setlen(result, len)
|
||||
|
||||
when defined(solaris) or defined(bsd):
|
||||
proc getpid(): int {.importc, header: "<unistd.h>", cdecl.}
|
||||
|
||||
proc getApplicationFilename(): string =
|
||||
# Linux: /proc/<pid>/exe
|
||||
# Solaris:
|
||||
# /proc/<pid>/object/a.out (filename only)
|
||||
# /proc/<pid>/path/a.out (complete pathname)
|
||||
# *BSD (and maybe Darwing too):
|
||||
# /proc/<pid>/file
|
||||
when defined(windows):
|
||||
result = newString(256)
|
||||
var len = getModuleFileName(0, result, 256)
|
||||
setlen(result, int(len))
|
||||
elif defined(linux):
|
||||
result = getApplAux("/proc/self/exe")
|
||||
elif defined(solaris):
|
||||
result = getApplAux("/proc/" & $getpid() & "/path/a.out")
|
||||
elif defined(bsd):
|
||||
result = getApplAux("/proc/" & $getpid() & "file")
|
||||
else:
|
||||
# little heuristic that may work on other POSIX-like systems:
|
||||
result = getEnv("_")
|
||||
if len(result) == 0:
|
||||
result = ParamStr(0) # POSIX guaranties that this contains the executable
|
||||
# as it has been executed by the calling process
|
||||
if len(result) > 0 and result[0] != DirSep: # not an absolute path?
|
||||
# iterate over any path in the $PATH environment variable
|
||||
for p in split(getEnv("PATH"), {PathSep}):
|
||||
var x = joinPath(p, result)
|
||||
if ExistsFile(x): return x
|
||||
|
||||
{.push warnings: off.}
|
||||
proc getApplicationDir(): string =
|
||||
var tail: string
|
||||
splitPath(getApplicationFilename(), result, tail)
|
||||
{.pop.}
|
||||
|
||||
proc getCurrentDir(): string =
|
||||
const
|
||||
bufsize = 512 # should be enough
|
||||
result = newString(bufsize)
|
||||
if getcwd(result, bufsize) != nil:
|
||||
setlen(result, strlen(result))
|
||||
else:
|
||||
raise newException(EOS, "getcwd failed")
|
||||
|
||||
proc JoinPath(head, tail: string): string =
|
||||
if len(head) == 0:
|
||||
result = tail
|
||||
elif head[len(head)-1] in {DirSep, AltSep}:
|
||||
if tail[0] in {DirSep, AltSep}:
|
||||
result = head & copy(tail, 1)
|
||||
else:
|
||||
result = head & tail
|
||||
else:
|
||||
if tail[0] in {DirSep, AltSep}:
|
||||
result = head & tail
|
||||
else:
|
||||
result = head & DirSep & tail
|
||||
|
||||
proc JoinPath(parts: openarray[string]): string =
|
||||
result = parts[0]
|
||||
for i in 1..high(parts):
|
||||
result = JoinPath(result, parts[i])
|
||||
|
||||
proc parentDir(path: string): string =
|
||||
var
|
||||
sepPos = -1
|
||||
q = 1
|
||||
if path[len(path)-1] in {dirsep, altsep}:
|
||||
q = 2
|
||||
for i in countdown(len(path)-q, 0):
|
||||
if path[i] in {dirsep, altsep}:
|
||||
sepPos = i
|
||||
break
|
||||
if sepPos >= 0:
|
||||
result = copy(path, 0, sepPos-1)
|
||||
else:
|
||||
result = path
|
||||
|
||||
proc SplitPath(path: string, head, tail: var string) =
|
||||
var
|
||||
sepPos = -1
|
||||
for i in countdown(len(path)-1, 0):
|
||||
if path[i] in {dirsep, altsep}:
|
||||
sepPos = i
|
||||
break
|
||||
if sepPos >= 0:
|
||||
head = copy(path, 0, sepPos-1)
|
||||
tail = copy(path, sepPos+1)
|
||||
else:
|
||||
head = ""
|
||||
tail = path # make a string copy here
|
||||
|
||||
# helper:
|
||||
proc searchExtPos(s: string): int =
|
||||
result = -1
|
||||
for i in countdown(len(s)-1, 0):
|
||||
if s[i] == extsep:
|
||||
result = i
|
||||
break
|
||||
elif s[i] in {dirsep, altsep}:
|
||||
break # do not skip over path
|
||||
|
||||
proc SplitFilename(filename: string, name, extension: var string) =
|
||||
var
|
||||
extPos = searchExtPos(filename)
|
||||
if extPos >= 0:
|
||||
name = copy(filename, 0, extPos-1)
|
||||
extension = copy(filename, extPos)
|
||||
else:
|
||||
name = filename # make a string copy here
|
||||
extension = ""
|
||||
|
||||
proc normExt(ext: string): string =
|
||||
if ext == "" or ext[0] == extSep: result = ext # no copy needed here
|
||||
else: result = extSep & ext
|
||||
|
||||
proc ChangeFileExt(filename, ext: string): string =
|
||||
var
|
||||
extPos = searchExtPos(filename)
|
||||
if extPos < 0: result = filename & normExt(ext)
|
||||
else: result = copy(filename, 0, extPos-1) & normExt(ext)
|
||||
|
||||
proc AppendFileExt(filename, ext: string): string =
|
||||
var
|
||||
extPos = searchExtPos(filename)
|
||||
if extPos < 0: result = filename & normExt(ext)
|
||||
else: result = filename #make a string copy here
|
||||
|
||||
# some more C things:
|
||||
|
||||
proc csystem(cmd: CString): cint {.importc: "system", noDecl.}
|
||||
# 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: "putenv", 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):
|
||||
type
|
||||
TFindData {.importc: "struct _finddata_t".} = record
|
||||
attrib {.importc: "attrib".}: cint
|
||||
time_create {.importc: "time_create".}: cint
|
||||
time_access {.importc: "time_access".}: cint
|
||||
time_write {.importc: "time_write".}: cint
|
||||
size {.importc: "size".}: cint
|
||||
name {.importc: "name".}: array[0..259, char]
|
||||
|
||||
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:
|
||||
type
|
||||
TFindData {.importc: "glob_t".} = record
|
||||
gl_pathc: int # count of paths matched by pattern
|
||||
gl_pathv: ptr array[0..1000_000, CString] # list of matched path names
|
||||
gl_offs: int # slots to reserve at beginning of gl_pathv
|
||||
PFindData = ptr TFindData
|
||||
|
||||
proc glob(pattern: cstring, flags: cint, errfunc: pointer,
|
||||
pglob: PFindData): cint {.
|
||||
importc: "glob", header: "<glob.h>".}
|
||||
|
||||
proc globfree(pglob: PFindData) {.
|
||||
importc: "globfree", header: "<glob.h>".}
|
||||
|
||||
proc cremove(filename: CString): cint {.importc: "remove", noDecl.}
|
||||
proc crename(oldname, newname: CString): cint {.importc: "rename", noDecl.}
|
||||
|
||||
when defined(Windows):
|
||||
proc cCopyFile(lpExistingFileName, lpNewFileName: CString,
|
||||
bFailIfExists: cint): cint {.
|
||||
importc: "CopyFile", header: "<windows.h>".}
|
||||
# cMoveFile(lpExistingFileName, lpNewFileName: CString): int
|
||||
# {.importc: "MoveFile", noDecl, header: "<winbase.h>".}
|
||||
# cRemoveFile(filename: CString, cmo: int)
|
||||
# {.importc: "DeleteFile", noDecl, header: "<winbase.h>".}
|
||||
else:
|
||||
# generic version of cCopyFile which works for any platform:
|
||||
proc cCopyFile(lpExistingFileName, lpNewFileName: CString,
|
||||
bFailIfExists: cint): cint =
|
||||
const
|
||||
bufSize = 8192 # 8K buffer
|
||||
var
|
||||
dest, src: TFile
|
||||
if not openFile(src, $lpExistingFilename): return -1
|
||||
if not openFile(dest, $lpNewFilename, fmWrite):
|
||||
closeFile(src)
|
||||
return -1
|
||||
var
|
||||
buf: Pointer = alloc(bufsize)
|
||||
bytesread, byteswritten: int
|
||||
while True:
|
||||
bytesread = readBuffer(src, buf, bufsize)
|
||||
byteswritten = writeBuffer(dest, buf, bytesread)
|
||||
if bytesread != bufSize: break
|
||||
if byteswritten == bytesread: result = 0
|
||||
else: result = -1
|
||||
dealloc(buf)
|
||||
closeFile(src)
|
||||
closeFile(dest)
|
||||
|
||||
|
||||
proc moveFile(dest, source: string) =
|
||||
if crename(source, dest) != 0:
|
||||
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) =
|
||||
if cremove(file) != 0:
|
||||
raise newException(EOS, "cannot remove file '$1'" % file)
|
||||
|
||||
proc removeDir(dir: string) =
|
||||
if rmdir(dir) != 0:
|
||||
raise newException(EOS, "cannot remove directory '$1'" % dir)
|
||||
|
||||
proc createDir(dir: string) =
|
||||
when defined(unix):
|
||||
if mkdir(dir, 0o711) != 0 and int(errno) != EEXIST:
|
||||
raise newException(EOS, "cannot create directory '$1'" % 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 =
|
||||
return csystem(command)
|
||||
|
||||
var
|
||||
envComputed: bool = false
|
||||
environment {.noStatic.}: seq[string] = []
|
||||
|
||||
when defined(windows):
|
||||
# because we support Windows GUI applications, things get really
|
||||
# messy here...
|
||||
proc GetEnvironmentStrings(): Pointer {.
|
||||
importc: "GetEnvironmentStrings", header: "<windows.h>".}
|
||||
proc FreeEnvironmentStrings(env: Pointer) {.
|
||||
importc: "FreeEnvironmentStrings", header: "<windows.h>".}
|
||||
proc strEnd(cstr: CString, c = 0): CString {.importc: "strchr", nodecl.}
|
||||
|
||||
proc getEnvVarsC() {.noStatic.} =
|
||||
if not envComputed:
|
||||
var
|
||||
env = cast[CString](getEnvironmentStrings())
|
||||
e = env
|
||||
if e == nil: return # an error occured
|
||||
while True:
|
||||
var eend = strEnd(e)
|
||||
add environment, $e
|
||||
e = cast[CString](cast[TAddress](eend)+1)
|
||||
if eend[1] == '\0': break
|
||||
envComputed = true
|
||||
FreeEnvironmentStrings(env)
|
||||
|
||||
else:
|
||||
var
|
||||
gEnv {.importc: "gEnv".}: ptr array [0..10_000, CString]
|
||||
|
||||
proc getEnvVarsC() {.noStatic.} =
|
||||
# retrieves the variables of char** env of C's main proc
|
||||
if not envComputed:
|
||||
var
|
||||
i: int = 0
|
||||
while True:
|
||||
if gEnv[i] == nil: break
|
||||
add environment, $gEnv[i]
|
||||
inc(i)
|
||||
envComputed = true
|
||||
|
||||
proc findEnvVar(key: string): int =
|
||||
getEnvVarsC()
|
||||
var temp = key & '='
|
||||
for i in 0..high(environment):
|
||||
if findSubStr(temp, environment[i]) == 0: return i
|
||||
return -1
|
||||
|
||||
proc getEnv(key: string): string =
|
||||
var i = findEnvVar(key)
|
||||
if i >= 0:
|
||||
return copy(environment[i], findSubStr("=", environment[i])+1)
|
||||
else:
|
||||
var env = cgetenv(key)
|
||||
if env == nil: return ""
|
||||
result = $env
|
||||
|
||||
proc existsEnv(key: string): bool =
|
||||
if cgetenv(key) != nil: return true
|
||||
else: return findEnvVar(key) >= 0
|
||||
|
||||
iterator iterOverEnvironment*(): tuple[string, string] =
|
||||
## Iterate over all environments varialbes. In the first component of the
|
||||
## tuple is the name of the current variable stored, in the second its value.
|
||||
getEnvVarsC()
|
||||
for i in 0..high(environment):
|
||||
var p = findSubStr("=", environment[i])
|
||||
yield (copy(environment[i], 0, p-1), copy(environment[i], p+1))
|
||||
|
||||
proc putEnv(key, val: string) =
|
||||
# Note: by storing the string in the environment sequence,
|
||||
# we gurantee that we don't free the memory before the program
|
||||
# ends (this is needed for POSIX compliance). It is also needed so that
|
||||
# the process itself may access its modified environment variables!
|
||||
var indx = findEnvVar(key)
|
||||
if indx >= 0:
|
||||
environment[indx] = key & '=' & val
|
||||
else:
|
||||
add environment, (key & '=' & val)
|
||||
indx = high(environment)
|
||||
if cputenv(environment[indx]) != 0:
|
||||
raise newException(EOS, "attempt to set an invalid environment variable")
|
||||
|
||||
iterator walkFiles*(pattern: string): string =
|
||||
## Iterate over all the files that match the `pattern`.
|
||||
##
|
||||
## `pattern` is OS dependant, but at least the "\*.ext"
|
||||
## notation is supported.
|
||||
when defined(windows):
|
||||
var
|
||||
f: TFindData
|
||||
res: int
|
||||
res = findfirst(pattern, addr(f))
|
||||
if res != -1:
|
||||
while true:
|
||||
yield $f.name
|
||||
if int(findnext(res, addr(f))) == -1: break
|
||||
findclose(res)
|
||||
else: # here we use glob
|
||||
var
|
||||
f: TFindData
|
||||
res: int
|
||||
f.gl_offs = 0
|
||||
f.gl_pathc = 0
|
||||
f.gl_pathv = nil
|
||||
res = glob(pattern, 0, nil, addr(f))
|
||||
if res != 0: raise newException(EOS, "walkFiles() failed")
|
||||
for i in 0.. f.gl_pathc - 1:
|
||||
assert(f.gl_pathv[i] != nil)
|
||||
yield $f.gl_pathv[i]
|
||||
globfree(addr(f))
|
||||
|
||||
{.push warnings:off.}
|
||||
proc ExistsFile(filename: string): bool =
|
||||
var
|
||||
res: TStat
|
||||
return stat(filename, res) >= 0
|
||||
{.pop.}
|
||||
|
||||
proc cmpPaths(pathA, pathB: string): int =
|
||||
if FileSystemCaseSensitive:
|
||||
result = cmp(pathA, pathB)
|
||||
else:
|
||||
result = cmpIgnoreCase(pathA, pathB)
|
||||
|
||||
proc extractDir(path: string): string =
|
||||
var
|
||||
tail: string
|
||||
splitPath(path, result, tail)
|
||||
|
||||
proc extractFilename(path: string): string =
|
||||
var
|
||||
head: string
|
||||
splitPath(path, head, result)
|
||||
|
||||
proc expandFilename(filename: string): string =
|
||||
# returns the full path of 'filename'; "" on error
|
||||
var
|
||||
res: CString
|
||||
when defined(unix):
|
||||
res = realpath(filename, nil)
|
||||
else:
|
||||
res = fullpath(nil, filename, 0)
|
||||
if res == nil:
|
||||
result = "" # an error occured
|
||||
else:
|
||||
result = $res
|
||||
free(res)
|
||||
|
||||
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 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':
|
||||
var a = ""
|
||||
while c[i] >= '\1' and c[i] <= ' ': inc(i) # skip whitespace
|
||||
case c[i]
|
||||
of '\'', '\"':
|
||||
var delim = c[i]
|
||||
inc(i) # skip ' or "
|
||||
while c[i] != '\0' and c[i] != delim:
|
||||
add a, c[i]
|
||||
inc(i)
|
||||
if c[i] != '\0': inc(i)
|
||||
else:
|
||||
while c[i] > ' ':
|
||||
add a, c[i]
|
||||
inc(i)
|
||||
add ownArgv, a
|
||||
inc(ownArgc)
|
||||
|
||||
proc paramStr(i: int): string =
|
||||
parseCmdLine()
|
||||
if i < ownArgc and i >= 0:
|
||||
return ownArgv[i]
|
||||
raise newException(EInvalidIndex, "invalid index")
|
||||
|
||||
proc paramCount(): int =
|
||||
parseCmdLine()
|
||||
result = ownArgc-1
|
||||
|
||||
else:
|
||||
proc GetHomeDir(): string = return getEnv("HOME") & "/"
|
||||
proc GetConfigDir(): string = return getEnv("HOME") & "/"
|
||||
|
||||
var
|
||||
cmdCount {.importc: "cmdCount".}: int
|
||||
cmdLine {.importc: "cmdLine".}: cstringArray
|
||||
|
||||
proc paramStr(i: int): string =
|
||||
if i < cmdCount and i >= 0: return $cmdLine[i]
|
||||
raise newException(EInvalidIndex, "invalid index")
|
||||
|
||||
proc paramCount(): int = return cmdCount-1
|
||||
|
||||
{.pop.}
|
||||
1818
lib/posix/posix.nim
Executable file
1818
lib/posix/posix.nim
Executable file
File diff suppressed because it is too large
Load diff
35
lib/powerpc.asm.in
Executable file
35
lib/powerpc.asm.in
Executable file
|
|
@ -0,0 +1,35 @@
|
|||
; This contains the CPU-dependant variants of some routines.
|
||||
; (C) 2005 Andreas Rumpf
|
||||
; This code was inspired by the Freepascal compiler's sources
|
||||
; All routines here have the _cdecl calling convention because
|
||||
; that is the only convention any C compiler supports.
|
||||
|
||||
\python{
|
||||
def c(name):
|
||||
if os.name == 'posix':
|
||||
return name
|
||||
else:
|
||||
return "_" + name
|
||||
}
|
||||
|
||||
segment code
|
||||
|
||||
global \c{cpu_inc_locked}
|
||||
global \c{cpu_dec_locked}
|
||||
|
||||
\c{cpu_dec_locked}:
|
||||
; input: address of arg in r3
|
||||
.LDecLockedLoop:
|
||||
lwarx r10,0,r3
|
||||
subi r10,r10,1
|
||||
stwcx. r10,0,r3
|
||||
bne- .LDecLockedLoop
|
||||
cntlzw r3,r10
|
||||
srwi r3,r3,5
|
||||
|
||||
\c{cpu_inc_locked}:
|
||||
.LIncLockedLoop:
|
||||
lwarx r10,0,r3
|
||||
addi r10,r10,1
|
||||
stwcx. r10,0,r3
|
||||
bne- .LIncLockedLoop
|
||||
1009
lib/process.nim
Executable file
1009
lib/process.nim
Executable file
File diff suppressed because it is too large
Load diff
205
lib/ptrset.nim
Executable file
205
lib/ptrset.nim
Executable file
|
|
@ -0,0 +1,205 @@
|
|||
# This implements a new pointer set. Access time O(1). For 32 bit systems, we
|
||||
# currently need 3 memory accesses.
|
||||
|
||||
const
|
||||
PageSize = 1024 * sizeof(int)
|
||||
MemAlignment = 8 # minimal memory block that can be allocated
|
||||
BitsPerUnit = sizeof(int)*8
|
||||
# a "unit" is a word, i.e. 4 bytes
|
||||
# on a 32 bit system; I do not use the term "word" because under 32-bit
|
||||
# Windows it is sometimes only 16 bits
|
||||
|
||||
BitsPerPage = PageSize div MemAlignment
|
||||
UnitsPerPage = BitsPerPage div BitsPerUnit
|
||||
# how many units do we need to describe a page:
|
||||
# on 32 bit systems this is only 16 (!)
|
||||
|
||||
type
|
||||
PPointer = ptr pointer
|
||||
|
||||
TCollectorData = int
|
||||
TCell = record
|
||||
refcount: TCollectorData # the refcount and bit flags
|
||||
typ: PNimType
|
||||
stackcount: int # stack counter for debugging
|
||||
drefc: int # real reference counter for debugging
|
||||
|
||||
PCell = ptr TCell
|
||||
|
||||
proc cellToUsr(cell: PCell): pointer {.inline.} =
|
||||
# convert object (=pointer to refcount) to pointer to userdata
|
||||
result = cast[pointer](cast[TAddress](cell)+%TAddress(sizeof(TCell)))
|
||||
|
||||
proc usrToCell(usr: pointer): PCell {.inline.} =
|
||||
# convert pointer to userdata to object (=pointer to refcount)
|
||||
result = cast[PCell](cast[TAddress](usr)-%TAddress(sizeof(TCell)))
|
||||
|
||||
proc gcAlloc(size: int): pointer =
|
||||
result = alloc0(size)
|
||||
if result == nil: raiseOutOfMem()
|
||||
|
||||
# ------------------ Zero count table (ZCT) and any table (AT) -------------
|
||||
|
||||
# this that has to equals zero, otherwise we have to round up UnitsPerPage:
|
||||
when BitsPerPage mod BitsPerUnit != 0:
|
||||
{.error: "(BitsPerPage mod BitsPerUnit) should be zero!".}
|
||||
|
||||
# ------------------- cell set handling ------------------------------
|
||||
# A cellset consists of a hash table of page descriptors. A page
|
||||
# descriptor has a bit for
|
||||
# every Memalignment'th byte in the page.
|
||||
# However, only bits corresponding to addresses that start memory blocks
|
||||
# are set.
|
||||
# Page descriptors are also linked to a list; the list
|
||||
# is used for easy traversing of all page descriptors; this allows a
|
||||
# fast iterator.
|
||||
# We use a specialized hashing scheme; the formula is :
|
||||
# hash = Page bitand max
|
||||
# We use linear probing with the formular: (5*h)+1
|
||||
# Thus we likely get no collisions at all if the pages are given to us
|
||||
# in a sequential manner by the operating system!
|
||||
const
|
||||
bitsPerNode = 10 # we use 10 bits per node; this means 3 memory accesses on
|
||||
# 32 bit systems
|
||||
|
||||
type
|
||||
PPageDesc = ptr TPageDesc
|
||||
|
||||
TBitIndex = range[0..UnitsPerPage-1]
|
||||
|
||||
TPageDesc = record
|
||||
next: PPageDesc # all nodes are connected with this pointer
|
||||
key: TAddress # start address at bit 0
|
||||
bits: array[TBitIndex, int] # a bit vector
|
||||
|
||||
PPageDescArray = ptr array[0..1000_000, PPageDesc]
|
||||
TCellSet = record
|
||||
counter, max: int
|
||||
head: PPageDesc
|
||||
data: PPageDescArray
|
||||
|
||||
TSetNode = record
|
||||
n: array[0.. (1 shl bitsPerNode)-1, PSetNode]
|
||||
PSetNode = ptr TSetNode
|
||||
|
||||
const
|
||||
InitCellSetSize = 1024 # must be a power of two!
|
||||
|
||||
proc CellSetInit(s: var TCellSet) =
|
||||
s.data = gcAlloc(InitCellSetSize * sizeof(PPageDesc))
|
||||
s.max = InitCellSetSize-1
|
||||
s.counter = 0
|
||||
s.head = nil
|
||||
|
||||
proc CellSetDeinit(s: var TCellSet) =
|
||||
var it = s.head
|
||||
while it != nil:
|
||||
var n = it.next
|
||||
dealloc(it)
|
||||
it = n
|
||||
s.head = nil # play it safe here
|
||||
dealloc(s.data)
|
||||
s.data = nil
|
||||
s.counter = 0
|
||||
|
||||
proc CellSetGet(t: TCellSet, key: TAddress): PPageDesc =
|
||||
var h = cast[int](key) and t.max
|
||||
while t.data[h] != nil:
|
||||
if t.data[h].key == key: return t.data[h]
|
||||
h = nextTry(h, t.max)
|
||||
return nil
|
||||
|
||||
proc CellSetRawInsert(t: TCellSet, data: PPageDescArray,
|
||||
desc: PPageDesc) =
|
||||
var h = cast[int](desc.key) and t.max
|
||||
while data[h] != nil:
|
||||
assert(data[h] != desc)
|
||||
h = nextTry(h, t.max)
|
||||
assert(data[h] == nil)
|
||||
data[h] = desc
|
||||
|
||||
proc CellSetEnlarge(t: var TCellSet) =
|
||||
var
|
||||
n: PPageDescArray
|
||||
oldMax = t.max
|
||||
t.max = ((t.max+1)*2)-1
|
||||
n = gcAlloc((t.max + 1) * sizeof(PPageDesc))
|
||||
for i in 0 .. oldmax:
|
||||
if t.data[i] != nil:
|
||||
CellSetRawInsert(t, n, t.data[i])
|
||||
dealloc(t.data)
|
||||
t.data = n
|
||||
|
||||
proc CellSetPut(t: var TCellSet, key: TAddress): PPageDesc =
|
||||
var h = cast[int](key) and t.max
|
||||
while true:
|
||||
var x = t.data[h]
|
||||
if x == nil: break
|
||||
if x.key == key: return x
|
||||
h = nextTry(h, t.max)
|
||||
|
||||
if (t.max+1) * 2 < t.counter * 3: CellSetEnlarge(t)
|
||||
inc(t.counter)
|
||||
h = cast[int](key) and t.max
|
||||
while t.data[h] != nil: h = nextTry(h, t.max)
|
||||
assert(t.data[h] == nil)
|
||||
# the new page descriptor goes into result
|
||||
result = gcAlloc(sizeof(TPageDesc))
|
||||
result.next = t.head
|
||||
result.key = key
|
||||
t.head = result
|
||||
t.data[h] = result
|
||||
|
||||
# ---------- slightly higher level procs ----------------------------------
|
||||
|
||||
proc in_Operator(s: TCellSet, cell: PCell): bool =
|
||||
var
|
||||
u: TAddress
|
||||
t: PPageDesc
|
||||
u = cast[TAddress](cell)
|
||||
t = CellSetGet(s, u /% PageSize)
|
||||
if t != nil:
|
||||
u = (u %% PageSize) /% MemAlignment
|
||||
result = (t.bits[u /% BitsPerUnit] and (1 shl (u %% BitsPerUnit))) != 0
|
||||
else:
|
||||
result = false
|
||||
|
||||
proc incl(s: var TCellSet, cell: PCell) =
|
||||
var
|
||||
u: TAddress
|
||||
t: PPageDesc
|
||||
u = cast[TAddress](cell)
|
||||
t = CellSetPut(s, u /% PageSize)
|
||||
u = (u %% PageSize) /% MemAlignment
|
||||
t.bits[u /% BitsPerUnit] = t.bits[u /% BitsPerUnit] or
|
||||
(1 shl (u %% BitsPerUnit))
|
||||
|
||||
proc excl(s: var TCellSet, cell: PCell) =
|
||||
var
|
||||
u: TAddress
|
||||
t: PPageDesc
|
||||
u = cast[TAddress](cell)
|
||||
t = CellSetGet(s, u /% PageSize)
|
||||
if t != nil:
|
||||
u = (u %% PageSize) /% MemAlignment
|
||||
t.bits[u %% BitsPerUnit] = (t.bits[u /% BitsPerUnit] and
|
||||
not (1 shl (u %% BitsPerUnit)))
|
||||
|
||||
iterator elements(t: TCellSet): PCell {.inline.} =
|
||||
# while traversing it is forbidden to add pointers to the tree!
|
||||
var r = t.head
|
||||
while r != nil:
|
||||
var i = 0
|
||||
while i <= high(r.bits):
|
||||
var w = r.bits[i] # taking a copy of r.bits[i] here is correct, because
|
||||
# modifying operations are not allowed during traversation
|
||||
var j = 0
|
||||
while w != 0: # test all remaining bits for zero
|
||||
if (w and 1) != 0: # the bit is set!
|
||||
yield cast[PCell]((r.key *% PageSize) +%
|
||||
(i*%BitsPerUnit+%j) *% MemAlignment)
|
||||
inc(j)
|
||||
w = w shr 1
|
||||
inc(i)
|
||||
r = r.next
|
||||
|
||||
233
lib/repr.nim
Executable file
233
lib/repr.nim
Executable file
|
|
@ -0,0 +1,233 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
# The generic ``repr`` procedure. It is an invaluable debugging tool.
|
||||
|
||||
#proc cstrToNimStrDummy(s: cstring): string {.inline.} =
|
||||
# result = cast[string](cstrToNimStr(s))
|
||||
|
||||
proc reprInt(x: int64): string {.compilerproc.} = return $x
|
||||
proc reprFloat(x: float): string {.compilerproc.} = return $x
|
||||
|
||||
proc reprPointer(x: pointer): string {.compilerproc.} =
|
||||
var buf: array [0..59, char]
|
||||
c_sprintf(buf, "%p", x)
|
||||
return $buf
|
||||
|
||||
proc reprStrAux(result: var string, s: string) =
|
||||
if cast[pointer](s) == nil:
|
||||
add result "nil"
|
||||
return
|
||||
add result, reprPointer(cast[pointer](s)) & "\""
|
||||
for c in items(s):
|
||||
case c
|
||||
of '"': add result "\\\""
|
||||
of '\\': add result, "\\\\" # BUGFIX: forgotten
|
||||
of '\10': add result, "\\10\"\n\"" # " \n " # better readability
|
||||
of '\128' .. '\255', '\0'..'\9', '\11'..'\31':
|
||||
add result, "\\" & reprInt(ord(c))
|
||||
else: result.add(c)
|
||||
add result, "\""
|
||||
|
||||
proc reprStr(s: string): string {.compilerproc.} =
|
||||
result = ""
|
||||
reprStrAux(result, s)
|
||||
|
||||
proc reprBool(x: bool): string {.compilerproc.} =
|
||||
if x: result = "true"
|
||||
else: result = "false"
|
||||
|
||||
proc reprChar(x: char): string {.compilerproc.} =
|
||||
result = "\'"
|
||||
case x
|
||||
of '"': add result, "\\\""
|
||||
of '\\': add result, "\\\\"
|
||||
of '\128' .. '\255', '\0'..'\31': add result, "\\" & reprInt(ord(x))
|
||||
else: add result, x
|
||||
add result, "\'"
|
||||
|
||||
proc reprEnum(e: int, typ: PNimType): string {.compilerproc.} =
|
||||
if e <% typ.node.len: # BUGFIX
|
||||
result = $typ.node.sons[e].name
|
||||
else:
|
||||
result = $e & " (invalid data!)"
|
||||
|
||||
type
|
||||
pbyteArray = ptr array[0.. 0xffff, byte]
|
||||
|
||||
proc addSetElem(result: var string, elem: int, typ: PNimType) =
|
||||
case typ.kind
|
||||
of tyEnum: add result, reprEnum(elem, typ)
|
||||
of tyBool: add result, reprBool(bool(elem))
|
||||
of tyChar: add result, reprChar(chr(elem))
|
||||
of tyRange: addSetElem(result, elem, typ.base)
|
||||
of tyInt..tyInt64: add result, reprInt(elem)
|
||||
else: # data corrupt --> inform the user
|
||||
add result, " (invalid data!)"
|
||||
|
||||
proc reprSetAux(result: var string, p: pointer, typ: PNimType) =
|
||||
# "typ.slots.len" field is for sets the "first" field
|
||||
var elemCounter = 0 # we need this flag for adding the comma at
|
||||
# the right places
|
||||
add result, "{"
|
||||
var u: int64
|
||||
case typ.size
|
||||
of 1: u = ze64(cast[ptr int8](p)^)
|
||||
of 2: u = ze64(cast[ptr int16](p)^)
|
||||
of 4: u = ze64(cast[ptr int32](p)^)
|
||||
of 8: u = ze64(cast[ptr int64](p)^)
|
||||
else:
|
||||
var a = cast[pbyteArray](p)^
|
||||
for i in 0 .. typ.size*8-1:
|
||||
if (a[i div 8] and (1 shl (i mod 8))) != 0:
|
||||
if elemCounter > 0: add result, ", "
|
||||
addSetElem(result, i+typ.node.len, typ.base)
|
||||
inc(elemCounter)
|
||||
if typ.size <= 8:
|
||||
for i in 0..sizeof(int64)*8-1:
|
||||
if (u and (1 shl i)) != 0:
|
||||
if elemCounter > 0: add result, ", "
|
||||
addSetElem(result, i+typ.node.len, typ.base)
|
||||
inc(elemCounter)
|
||||
add result, "}"
|
||||
|
||||
proc reprSet(p: pointer, typ: PNimType): string {.compilerproc.} =
|
||||
result = ""
|
||||
reprSetAux(result, p, typ)
|
||||
|
||||
type
|
||||
TReprClosure = record # we cannot use a global variable here
|
||||
# as this wouldn't be thread-safe
|
||||
marked: TCellSet
|
||||
recdepth: int # do not recurse endless
|
||||
indent: int # indentation
|
||||
|
||||
proc initReprClosure(cl: var TReprClosure) =
|
||||
CellSetInit(cl.marked)
|
||||
cl.recdepth = -1 # default is to display everything!
|
||||
cl.indent = 0
|
||||
|
||||
proc deinitReprClosure(cl: var TReprClosure) =
|
||||
CellSetDeinit(cl.marked)
|
||||
|
||||
proc reprBreak(result: var string, cl: TReprClosure) =
|
||||
add result, "\n"
|
||||
for i in 0..cl.indent-1: add result, ' '
|
||||
|
||||
proc reprAux(result: var string, p: pointer, typ: PNimType,
|
||||
cl: var TReprClosure)
|
||||
|
||||
proc reprArray(result: var string, p: pointer, typ: PNimType,
|
||||
cl: var TReprClosure) =
|
||||
add result, "["
|
||||
var bs = typ.base.size
|
||||
for i in 0..typ.size div bs - 1:
|
||||
if i > 0: add result, ", "
|
||||
reprAux(result, cast[pointer](cast[TAddress](p) + i*bs), typ.base, cl)
|
||||
add result, "]"
|
||||
|
||||
proc reprSequence(result: var string, p: pointer, typ: PNimType,
|
||||
cl: var TReprClosure) =
|
||||
if p == nil:
|
||||
add result, "nil"
|
||||
return
|
||||
result.add(reprPointer(p) & "[")
|
||||
var bs = typ.base.size
|
||||
for i in 0..cast[PGenericSeq](p).len-1:
|
||||
if i > 0: add result, ", "
|
||||
reprAux(result, cast[pointer](cast[TAddress](p) + GenericSeqSize + i*bs),
|
||||
typ.Base, cl)
|
||||
add result, "]"
|
||||
|
||||
|
||||
proc reprRecordAux(result: var string, p: pointer, n: ptr TNimNode,
|
||||
cl: var TReprClosure) =
|
||||
case n.kind
|
||||
of nkNone: assert(false)
|
||||
of nkSlot:
|
||||
add result, $n.name
|
||||
add result, " = "
|
||||
reprAux(result, cast[pointer](cast[TAddress](p) + n.offset), n.typ, cl)
|
||||
of nkList:
|
||||
for i in 0..n.len-1:
|
||||
if i > 0: add result, ",\n"
|
||||
reprRecordAux(result, p, n.sons[i], cl)
|
||||
of nkCase:
|
||||
var m = selectBranch(p, n)
|
||||
reprAux(result, cast[pointer](cast[TAddress](p) + n.offset), n.typ, cl)
|
||||
if m != nil: reprRecordAux(result, p, m, cl)
|
||||
|
||||
proc reprRecord(result: var string, p: pointer, typ: PNimType,
|
||||
cl: var TReprClosure) =
|
||||
add result, "["
|
||||
reprRecordAux(result, p, typ.node, cl)
|
||||
add result, "]"
|
||||
|
||||
proc reprRef(result: var string, p: pointer, typ: PNimType,
|
||||
cl: var TReprClosure) =
|
||||
# we know that p is not nil here:
|
||||
var cell = usrToCell(p)
|
||||
add result, "ref " & reprPointer(p)
|
||||
if cell notin cl.marked:
|
||||
# only the address is shown:
|
||||
incl(cl.marked, cell)
|
||||
add result, " --> "
|
||||
reprAux(result, p, typ.base, cl)
|
||||
|
||||
proc reprAux(result: var string, p: pointer, typ: PNimType,
|
||||
cl: var TReprClosure) =
|
||||
if cl.recdepth == 0:
|
||||
add result, "..."
|
||||
return
|
||||
dec(cl.recdepth)
|
||||
case typ.kind
|
||||
of tySet: reprSetAux(result, p, typ)
|
||||
of tyArray: reprArray(result, p, typ, cl)
|
||||
of tyRecord: reprRecord(result, p, typ, cl)
|
||||
of tyObject: # result = reprRecord(p, typ, cl)
|
||||
var t = cast[ptr PNimType](p)^
|
||||
reprRecord(result, p, t, cl)
|
||||
of tyRef, tyPtr:
|
||||
assert(p != nil)
|
||||
if cast[ppointer](p)^ == nil: add result, "nil"
|
||||
else: reprRef(result, cast[ppointer](p)^, typ, cl)
|
||||
of tySequence:
|
||||
reprSequence(result, cast[ppointer](p)^, typ, cl)
|
||||
of tyInt: add result, $(cast[ptr int](p)^)
|
||||
of tyInt8: add result, $int(cast[ptr Int8](p)^)
|
||||
of tyInt16: add result, $int(cast[ptr Int16](p)^)
|
||||
of tyInt32: add result, $int(cast[ptr Int32](p)^)
|
||||
of tyInt64: add result, $(cast[ptr Int64](p)^)
|
||||
of tyFloat: add result, $(cast[ptr float](p)^)
|
||||
of tyFloat32: add result, $(cast[ptr float32](p)^)
|
||||
of tyFloat64: add result, $(cast[ptr float64](p)^)
|
||||
of tyEnum: add result, reprEnum(cast[ptr int](p)^, typ)
|
||||
of tyBool: add result, reprBool(cast[ptr bool](p)^)
|
||||
of tyChar: add result, reprChar(cast[ptr char](p)^)
|
||||
of tyString: reprStrAux(result, cast[ptr string](p)^)
|
||||
of tyCString: reprStrAux(result, $(cast[ptr cstring](p)^))
|
||||
of tyRange: reprAux(result, p, typ.base, cl)
|
||||
of tyProc, tyPointer:
|
||||
if cast[ppointer](p)^ == nil: add result, "nil"
|
||||
else: add result, reprPointer(cast[ppointer](p)^)
|
||||
else:
|
||||
add result, "(invalid data!)"
|
||||
inc(cl.recdepth)
|
||||
|
||||
proc reprAny(p: pointer, typ: PNimType): string =
|
||||
var
|
||||
cl: TReprClosure
|
||||
initReprClosure(cl)
|
||||
result = ""
|
||||
if typ.kind in {tyObject, tyRecord, tyArray, tySet}:
|
||||
reprAux(result, p, typ, cl)
|
||||
else:
|
||||
reprAux(result, addr(p), typ, cl)
|
||||
add result, "\n"
|
||||
deinitReprClosure(cl)
|
||||
88
lib/sets.nim
Executable file
88
lib/sets.nim
Executable file
|
|
@ -0,0 +1,88 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
# set handling
|
||||
|
||||
type
|
||||
TMyByte = int8
|
||||
TNimSet = array [0..4*2048-1, TMyByte]
|
||||
|
||||
# implementation:
|
||||
|
||||
proc countBits(n: int32): int {.exportc: "countBits".}
|
||||
# We use a prototype here, not in "cntbits.nim", because that is included
|
||||
# in math.nim too. So when linking with math.nim it'd give a duplicated
|
||||
# symbol error which we avoid by renaming here.
|
||||
|
||||
include cntbits
|
||||
|
||||
proc unionSets(res: var TNimSet, a, b: TNimSet, len: int) {.
|
||||
compilerproc, inline.} =
|
||||
for i in countup(0, len-1): res[i] = toU8(ze(a[i]) or ze(b[i]))
|
||||
|
||||
proc diffSets(res: var TNimSet, a, b: TNimSet, len: int) {.
|
||||
compilerproc, inline.} =
|
||||
for i in countup(0, len-1): res[i] = toU8(ze(a[i]) and not ze(b[i]))
|
||||
|
||||
proc intersectSets(res: var TNimSet, a, b: TNimSet, len: int) {.
|
||||
compilerproc, inline.} =
|
||||
for i in countup(0, len-1): res[i] = toU8(ze(a[i]) and ze(b[i]))
|
||||
|
||||
proc symdiffSets(res: var TNimSet, a, b: TNimSet, len: int) {.
|
||||
compilerproc, inline.} =
|
||||
for i in countup(0, len-1): res[i] = toU8(ze(a[i]) xor ze(b[i]))
|
||||
|
||||
proc containsSets(a, b: TNimSet, len: int): bool {.compilerproc, inline.} =
|
||||
# s1 <= s2 ?
|
||||
for i in countup(0, len-1):
|
||||
if (ze(a[i]) and not ze(b[i])) != 0: return false
|
||||
return true
|
||||
|
||||
proc containsSubsets(a, b: TNimSet, len: int): bool {.compilerproc, inline.} =
|
||||
# s1 < s2 ?
|
||||
result = false # assume they are equal
|
||||
for i in countup(0, len-1):
|
||||
if (ze(a[i]) and not ze(b[i])) != 0: return false
|
||||
if ze(a[i]) != ze(b[i]): result = true # they are not equal
|
||||
|
||||
proc equalSets(a, b: TNimSet, len: int): bool {.compilerproc, inline.} =
|
||||
for i in countup(0, len-1):
|
||||
if ze(a[i]) != ze(b[i]): return false
|
||||
return true
|
||||
|
||||
proc cardSet(s: TNimSet, len: int): int {.compilerproc, inline.} =
|
||||
result = 0
|
||||
for i in countup(0, len-1):
|
||||
inc(result, countBits(ze(s[i])))
|
||||
|
||||
const
|
||||
WORD_SIZE = sizeof(TMyByte)*8
|
||||
|
||||
proc inSet(s: TNimSet, elem: int): bool {.compilerproc, inline.} =
|
||||
return (s[elem /% WORD_SIZE] and (1 shl (elem %% WORD_SIZE))) != 0
|
||||
|
||||
proc inclSets(s: var TNimSet, e: int) {.compilerproc, inline.} =
|
||||
s[e /% WORD_SIZE] = toU8(s[e /% WORD_SIZE] or (1 shl (e %% WORD_SIZE)))
|
||||
|
||||
proc inclRange(s: var TNimSet, first, last: int) {.compilerproc.} =
|
||||
# not very fast, but it is seldom used
|
||||
for i in countup(first, last): inclSets(s, i)
|
||||
|
||||
proc smallInclRange(s: var int, first, last: int) {.compilerproc.} =
|
||||
# not very fast, but it is seldom used
|
||||
for i in countup(first, last):
|
||||
s = s or (1 shl (i %% sizeof(int)*8))
|
||||
|
||||
proc exclSets(s: var TNimSet, e: int) {.compilerproc, inline.} =
|
||||
s[e /% WORD_SIZE] = toU8(s[e /% WORD_SIZE] and
|
||||
not (1 shl (e %% WORD_SIZE)))
|
||||
|
||||
proc smallContainsSubsets(a, b: int): bool {.compilerProc, inline.} =
|
||||
# not used by new code generator
|
||||
return ((a and not b) != 0) and (a != b)
|
||||
627
lib/strutils.nim
Executable file
627
lib/strutils.nim
Executable file
|
|
@ -0,0 +1,627 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
|
||||
|
||||
## This module contains various string utility routines.
|
||||
## See the module `regexprs` for regular expression support.
|
||||
|
||||
{.push debugger:off .} # the user does not want to trace a part
|
||||
# of the standard library!
|
||||
|
||||
# copied from excpt.nim, because I don't want to make this template public
|
||||
template newException(exceptn, message: expr): expr =
|
||||
block: # open a new scope
|
||||
var
|
||||
e: ref exceptn
|
||||
new(e)
|
||||
e.msg = message
|
||||
e
|
||||
|
||||
type
|
||||
TCharSet* = set[char] # for compability for Nim
|
||||
|
||||
const
|
||||
Whitespace* = {' ', '\t', '\v', '\r', '\l', '\f'}
|
||||
## All the characters that count as whitespace.
|
||||
|
||||
strStart* = 0 # this is only for bootstraping
|
||||
# XXX: remove this someday
|
||||
nl* = "\n" # this is only for bootstraping XXX: remove this somehow
|
||||
|
||||
proc strip*(s: string): string {.noSideEffect.}
|
||||
## Strips leading and trailing whitespace from `s`.
|
||||
|
||||
proc toLower*(s: string): string {.noSideEffect.}
|
||||
## Converts `s` into lower case. This works only for the letters A-Z.
|
||||
## See `charsets.nativeToLower` for a version that is locale-dependant.
|
||||
|
||||
proc toLower*(c: Char): Char {.noSideEffect.}
|
||||
## Converts `c` into lower case. This works only for the letters A-Z.
|
||||
## See `charsets.nativeToLower()` for a version that is locale-dependant.
|
||||
|
||||
proc toUpper*(s: string): string {.noSideEffect.}
|
||||
## Converts `s` into upper case. This works only for the letters a-z.
|
||||
## See `charsets.nativeToUpper()` for a version that is locale-dependant.
|
||||
|
||||
proc toUpper*(c: Char): Char {.noSideEffect.}
|
||||
## Converts `c` into upper case. This works only for the letters a-z.
|
||||
## See `charsets.nativeToUpper()` for a version that is locale-dependant.
|
||||
|
||||
proc capitalize*(s: string): string {.noSideEffect.}
|
||||
## Converts the first character of `s` into upper case.
|
||||
## This works only for the letters a-z.
|
||||
|
||||
proc normalize*(s: string): string {.noSideEffect.}
|
||||
## Normalizes the string `s`. That means to convert it to lower case and
|
||||
## remove any '_'. This is needed for Nimrod identifiers for example.
|
||||
|
||||
proc findSubStr*(sub, s: string, start: int = 0): int {.noSideEffect.}
|
||||
## Searches for `sub` in `s` starting at position `start`. Searching is
|
||||
## case-sensitive. If `sub` is not in `s`, -1 is returned.
|
||||
|
||||
proc findSubStr*(sub: char, s: string, start: int = 0): int {.noSideEffect.}
|
||||
## Searches for `sub` in `s` starting at position `start`. Searching is
|
||||
## case-sensitive. If `sub` is not in `s`, -1 is returned.
|
||||
|
||||
proc replaceStr*(s, sub, by: string): string {.noSideEffect.}
|
||||
## Replaces `sub` in `s` by the string `by`.
|
||||
|
||||
proc deleteStr*(s: var string, first, last: int)
|
||||
## Deletes in `s` the characters at position `first`..`last`. This modifies
|
||||
## `s` itself, it does not return a copy.
|
||||
|
||||
proc toOctal*(c: char): string
|
||||
## Converts a character `c` to its octal representation. The resulting
|
||||
## string may not have a leading zero. Its length is always exactly 3.
|
||||
|
||||
iterator split*(s: string, seps: set[char] = Whitespace): string =
|
||||
## Splits the string `s` into substrings.
|
||||
##
|
||||
## Substrings are separated by a substring containing only `seps`.
|
||||
## The seperator substrings are not returned in `sub`, nor are they part
|
||||
## of `sub`.
|
||||
## Examples::
|
||||
##
|
||||
## for word in split(" this is an example "):
|
||||
## writeln(stdout, word)
|
||||
##
|
||||
## Results in::
|
||||
##
|
||||
## "this"
|
||||
## "is"
|
||||
## "an"
|
||||
## "example"
|
||||
##
|
||||
## for word in split(";;this;is;an;;example;;;", {';'}):
|
||||
## writeln(stdout, word)
|
||||
##
|
||||
## produces in the same output.
|
||||
var
|
||||
first: int = 0
|
||||
last: int = 0
|
||||
assert(not ('\0' in seps))
|
||||
while last < len(s):
|
||||
while s[last] in seps: inc(last)
|
||||
first = last
|
||||
while last < len(s) and s[last] not_in seps: inc(last) # BUGFIX!
|
||||
yield copy(s, first, last-1)
|
||||
|
||||
proc splitSeq*(s: string, seps: set[char] = Whitespace): seq[string] {.
|
||||
noSideEffect.}
|
||||
## The same as `split`, but is a proc that returns a sequence of substrings.
|
||||
|
||||
proc cmpIgnoreCase*(a, b: string): int {.noSideEffect.}
|
||||
## Compares two strings in a case insensitive manner. Returns:
|
||||
##
|
||||
## | 0 iff a == b
|
||||
## | < 0 iff a < b
|
||||
## | > 0 iff a > b
|
||||
|
||||
proc cmpIgnoreStyle*(a, b: string): int {.noSideEffect.}
|
||||
## Compares two strings normalized (i.e. case and
|
||||
## underscores do not matter). Returns:
|
||||
##
|
||||
## | 0 iff a == b
|
||||
## | < 0 iff a < b
|
||||
## | > 0 iff a > b
|
||||
|
||||
proc in_Operator*(s: string, c: char): bool {.noSideEffect.}
|
||||
## Same as `findSubStr(c, s) >= 0`.
|
||||
|
||||
proc in_Operator*(s, sub: string): bool {.noSideEffect.}
|
||||
## Same as `findSubStr(sub, s) >= 0`.
|
||||
|
||||
proc toHex*(x: BiggestInt, len: int): string {.noSideEffect.}
|
||||
## Converts `x` to its hexadecimal representation. The resulting string
|
||||
## will be exactly `len` characters long. No prefix like ``0x``
|
||||
## is generated. `x` is treated as unsigned value.
|
||||
|
||||
proc intToStr*(x: int, minchars: int = 1): string
|
||||
## Converts `x` to its decimal representation. The resulting string
|
||||
## will be minimally `minchars` characters long. This is achieved by
|
||||
## adding leading zeros.
|
||||
|
||||
proc ParseInt*(s: string): int {.noSideEffect.}
|
||||
## Parses a decimal integer value contained in `s`. If `s` is not
|
||||
## a valid integer, `EInvalidValue` is raised.
|
||||
# XXX: make this biggestint!
|
||||
|
||||
proc ParseFloat*(s: string): float {.noSideEffect.}
|
||||
## Parses a decimal floating point value contained in `s`. If `s` is not
|
||||
## a valid floating point number, `EInvalidValue` is raised.
|
||||
# XXX: make this biggestfloat.
|
||||
|
||||
# the stringify and format operators:
|
||||
proc toString*[Ty](x: Ty): string
|
||||
## This generic proc is the same as the stringify operator `$`.
|
||||
|
||||
proc `%` *(formatstr: string, a: openarray[string]): string {.noSideEffect.}
|
||||
## The substitution operator performs string substitutions in `formatstr`
|
||||
## and returns the modified `formatstr`.
|
||||
##
|
||||
## This is best explained by an example::
|
||||
##
|
||||
## "$1 eats $2." % ["The cat", "fish"]
|
||||
##
|
||||
## Results in::
|
||||
##
|
||||
## "The cat eats fish."
|
||||
##
|
||||
## The substitution variables (the thing after the ``$``)
|
||||
## are enumerated from 1 to 9.
|
||||
## Substitution variables can also be words (that is
|
||||
## ``[A-Za-z_]+[A-Za-z0-9_]*``) in which case the arguments in `a` with even
|
||||
## indices are keys and with odd indices are the corresponding values. Again
|
||||
## an example::
|
||||
##
|
||||
## "$animal eats $food." % ["animal", "The cat", "food", "fish"]
|
||||
##
|
||||
## Results in::
|
||||
##
|
||||
## "The cat eats fish."
|
||||
##
|
||||
## The variables are compared with `cmpIgnoreStyle`. `EInvalidValue` is
|
||||
## raised if an ill-formed format string has been passed to the `%` operator.
|
||||
|
||||
proc `%` *(formatstr, a: string): string {.noSideEffect.}
|
||||
## This is the same as `formatstr % [a]`.
|
||||
|
||||
proc repeatChar*(count: int, c: Char = ' '): string
|
||||
## Returns a string of length `count` consisting only of
|
||||
## the character `c`.
|
||||
|
||||
proc startsWith*(s, prefix: string): bool {.noSideEffect.}
|
||||
## Returns true iff ``s`` starts with ``prefix``.
|
||||
## If ``prefix == ""`` true is returned.
|
||||
|
||||
proc endsWith*(s, suffix: string): bool {.noSideEffect.}
|
||||
## Returns true iff ``s`` ends with ``suffix``.
|
||||
## If ``suffix == ""`` true is returned.
|
||||
|
||||
# implementation
|
||||
|
||||
proc allCharsInSet*(s: string, theSet: TCharSet): bool =
|
||||
## returns true iff each character of `s` is in the set `theSet`.
|
||||
for c in items(s):
|
||||
if not (c in theSet): return false
|
||||
return true
|
||||
|
||||
proc c_strcmp(a, b: CString): int {.importc: "strcmp", nodecl.}
|
||||
|
||||
proc startsWith(s, prefix: string): bool =
|
||||
var i = 0
|
||||
while true:
|
||||
if prefix[i] == '\0': return true
|
||||
if s[i] != prefix[i]: return false
|
||||
inc(i)
|
||||
|
||||
proc endsWith(s, suffix: string): bool =
|
||||
var
|
||||
i = 0
|
||||
j = len(s) - len(suffix)
|
||||
while true:
|
||||
if suffix[i] == '\0': return true
|
||||
if s[i+j] != suffix[i]: return false
|
||||
inc(i)
|
||||
|
||||
proc repeatChar(count: int, c: Char = ' '): string =
|
||||
result = newString(count)
|
||||
for i in 0..count-1:
|
||||
result[i] = c
|
||||
|
||||
proc intToStr(x: int, minchars: int = 1): string =
|
||||
result = $abs(x)
|
||||
for i in 1 .. minchars - len(result):
|
||||
result = '0' & result
|
||||
if x < 0:
|
||||
result = '-' & result
|
||||
|
||||
proc toString[Ty](x: Ty): string = return $x
|
||||
|
||||
proc toOctal(c: char): string =
|
||||
var
|
||||
val: int
|
||||
result = newString(3)
|
||||
val = ord(c)
|
||||
for i in countdown(2, 0):
|
||||
result[i] = Chr(val mod 8 + ord('0'))
|
||||
val = val div 8
|
||||
|
||||
proc `%`(formatstr: string, a: string): string =
|
||||
return formatstr % [a]
|
||||
|
||||
proc findNormalized(x: string, inArray: openarray[string]): int =
|
||||
var i = 0
|
||||
while i < high(inArray):
|
||||
if cmpIgnoreStyle(x, inArray[i]) == 0: return i
|
||||
inc(i, 2) # incrementing by 1 would probably result in a
|
||||
# security whole ...
|
||||
return -1
|
||||
|
||||
proc `%`(formatstr: string, a: openarray[string]): string =
|
||||
# the format operator
|
||||
const
|
||||
PatternChars = {'a'..'z', 'A'..'Z', '0'..'9', '\128'..'\255', '_'}
|
||||
result = ""
|
||||
var i = 0
|
||||
while i < len(formatstr):
|
||||
if formatstr[i] == '$':
|
||||
case formatstr[i+1] # again we use the fact that strings
|
||||
# are zero-terminated here
|
||||
of '$':
|
||||
add result, '$'
|
||||
inc(i, 2)
|
||||
of '1'..'9':
|
||||
var j = 0
|
||||
inc(i) # skip $
|
||||
while formatstr[i] in {'0'..'9'}:
|
||||
j = j * 10 + ord(formatstr[i]) - ord('0')
|
||||
inc(i)
|
||||
add result, a[j - 1]
|
||||
of '{':
|
||||
var j = i+1
|
||||
while formatstr[j] notin {'\0', '}'}: inc(j)
|
||||
var x = findNormalized(copy(formatstr, i+2, j-1), a)
|
||||
if x >= 0 and x < high(a): add result, a[x+1]
|
||||
else: raise newException(EInvalidValue, "invalid format string")
|
||||
i = j+1
|
||||
of 'a'..'z', 'A'..'Z', '\128'..'\255', '_':
|
||||
var j = i+1
|
||||
while formatstr[j] in PatternChars: inc(j)
|
||||
var x = findNormalized(copy(formatstr, i+1, j-1), a)
|
||||
if x >= 0 and x < high(a): add result, a[x+1]
|
||||
else: raise newException(EInvalidValue, "invalid format string")
|
||||
i = j
|
||||
else: raise newException(EInvalidValue, "invalid format string")
|
||||
else:
|
||||
add result, formatstr[i]
|
||||
inc(i)
|
||||
|
||||
proc cmpIgnoreCase(a, b: string): int =
|
||||
# makes usage of the fact that strings are zero-terminated
|
||||
var
|
||||
aa, bb: char
|
||||
for i in 0..len(a)-1:
|
||||
aa = toLower(a[i])
|
||||
bb = toLower(b[i])
|
||||
result = ord(aa) - ord(bb)
|
||||
if result != 0: break
|
||||
|
||||
{.push checks: off, line_trace: off .} # this is a hot-spot in the compiler!
|
||||
# thus we compile without checks here
|
||||
|
||||
proc cmpIgnoreStyle(a, b: string): int =
|
||||
var
|
||||
aa, bb: char
|
||||
i = 0
|
||||
j = 0
|
||||
while True:
|
||||
while a[i] == '_': inc(i)
|
||||
while b[j] == '_': inc(j) # BUGFIX: typo
|
||||
aa = toLower(a[i])
|
||||
bb = toLower(b[j])
|
||||
result = ord(aa) - ord(bb)
|
||||
if result != 0 or aa == '\0': break
|
||||
inc(i)
|
||||
inc(j)
|
||||
|
||||
{.pop.}
|
||||
|
||||
# ---------- splitting -----------------------------------------------------
|
||||
|
||||
proc splitSeq(s: string, seps: set[char]): seq[string] =
|
||||
result = []
|
||||
for sub in split(s, seps): add result, sub
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
proc strip(s: string): string =
|
||||
const
|
||||
chars: set[Char] = Whitespace
|
||||
var
|
||||
first = 0
|
||||
last = len(s)-1
|
||||
while s[first] in chars: inc(first)
|
||||
while last >= 0 and s[last] in chars: dec(last)
|
||||
result = copy(s, first, last)
|
||||
|
||||
proc toLower(c: Char): Char =
|
||||
if c in {'A'..'Z'}:
|
||||
result = chr(ord(c) + (ord('a') - ord('A')))
|
||||
else:
|
||||
result = c
|
||||
|
||||
proc toLower(s: string): string =
|
||||
result = newString(len(s))
|
||||
for i in 0..len(s) - 1:
|
||||
result[i] = toLower(s[i])
|
||||
|
||||
proc toUpper(c: Char): Char =
|
||||
if c in {'a'..'z'}:
|
||||
result = Chr(Ord(c) - (Ord('a') - Ord('A')))
|
||||
else:
|
||||
result = c
|
||||
|
||||
proc toUpper(s: string): string =
|
||||
result = newString(len(s))
|
||||
for i in 0..len(s) - 1:
|
||||
result[i] = toUpper(s[i])
|
||||
|
||||
proc capitalize(s: string): string =
|
||||
result = toUpper(s[0]) & copy(s, 1)
|
||||
|
||||
proc normalize(s: string): string =
|
||||
result = ""
|
||||
for i in 0..len(s) - 1:
|
||||
if s[i] in {'A'..'Z'}:
|
||||
add result, Chr(Ord(s[i]) + (Ord('a') - Ord('A')))
|
||||
elif s[i] != '_':
|
||||
add result, s[i]
|
||||
|
||||
type
|
||||
TSkipTable = array[Char, int]
|
||||
|
||||
proc preprocessSub(sub: string, a: var TSkipTable) =
|
||||
var m = len(sub)
|
||||
for i in 0..0xff: a[chr(i)] = m+1
|
||||
for i in 0..m-1: a[sub[i]] = m-i
|
||||
|
||||
proc findSubStrAux(sub, s: string, start: int, a: TSkipTable): int =
|
||||
# fast "quick search" algorithm:
|
||||
var
|
||||
m = len(sub)
|
||||
n = len(s)
|
||||
# search:
|
||||
var j = start
|
||||
while j <= n - m:
|
||||
block match:
|
||||
for k in 0..m-1:
|
||||
if sub[k] != s[k+j]: break match
|
||||
return j
|
||||
inc(j, a[s[j+m]])
|
||||
return -1
|
||||
|
||||
proc findSubStr(sub, s: string, start: int = 0): int =
|
||||
var a: TSkipTable
|
||||
preprocessSub(sub, a)
|
||||
result = findSubStrAux(sub, s, start, a)
|
||||
# slow linear search:
|
||||
#var
|
||||
# i, j, M, N: int
|
||||
#M = len(sub)
|
||||
#N = len(s)
|
||||
#i = start
|
||||
#j = 0
|
||||
#if i >= N:
|
||||
# result = -1
|
||||
#else:
|
||||
# while True:
|
||||
# if s[i] == sub[j]:
|
||||
# Inc(i)
|
||||
# Inc(j)
|
||||
# else:
|
||||
# i = i - j + 1
|
||||
# j = 0
|
||||
# if (j >= M):
|
||||
# return i - M
|
||||
# elif (i >= N):
|
||||
# return -1
|
||||
|
||||
|
||||
proc findSubStr(sub: char, s: string, start: int = 0): int =
|
||||
for i in start..len(s)-1:
|
||||
if sub == s[i]: return i
|
||||
return -1
|
||||
|
||||
proc in_Operator(s: string, c: char): bool =
|
||||
return findSubStr(c, s) >= 0
|
||||
|
||||
proc in_Operator(s, sub: string): bool =
|
||||
return findSubStr(sub, s) >= 0
|
||||
|
||||
proc replaceStr(s, sub, by: string): string =
|
||||
var
|
||||
i, j: int
|
||||
a: TSkipTable
|
||||
result = ""
|
||||
preprocessSub(sub, a)
|
||||
i = 0
|
||||
while true:
|
||||
j = findSubStrAux(sub, s, i, a)
|
||||
if j < 0: break
|
||||
add result, copy(s, i, j - 1)
|
||||
add result, by
|
||||
i = j + len(sub)
|
||||
# copy the rest:
|
||||
add result, copy(s, i)
|
||||
|
||||
proc deleteStr(s: var string, first, last: int) =
|
||||
# example: "abc___uvwxyz\0" (___ is to be deleted)
|
||||
# --> first == 3, last == 5
|
||||
# s[first..] = s[last+1..]
|
||||
var
|
||||
i = first
|
||||
while last+i+1 < len(s):
|
||||
s[i] = s[last+i+1]
|
||||
inc(i)
|
||||
setlen(s, len(s)-(last-first+1))
|
||||
|
||||
# parsing numbers:
|
||||
|
||||
proc sprintf(buf, frmt: CString) {.nodecl, importc: "sprintf", varargs.}
|
||||
|
||||
proc toHex(x: BiggestInt, len: int): string =
|
||||
const
|
||||
HexChars = "0123456789ABCDEF"
|
||||
var
|
||||
shift: BiggestInt
|
||||
result = newString(len)
|
||||
shift = 0
|
||||
for j in countdown(len-1, 0):
|
||||
result[j] = HexChars[toU32(x shr shift) and 0xF]
|
||||
shift = shift + 4
|
||||
|
||||
{.push overflowChecks: on.}
|
||||
# this must be compiled with overflow checking turned on:
|
||||
proc rawParseInt(s: string, index: var int): BiggestInt =
|
||||
# index contains the start position at proc entry; end position will be
|
||||
# an index before the proc returns; index = -1 on error (no number at all)
|
||||
# the problem here is that integers have an asymmetrical range: there is
|
||||
# one more valid negative than prositive integer. Thus we perform the
|
||||
# computation as a negative number and then change the sign at the end.
|
||||
var
|
||||
i: int
|
||||
sign: BiggestInt
|
||||
i = index
|
||||
# a local i is more efficient than accessing an in out parameter
|
||||
sign = -1
|
||||
if s[i] == '+':
|
||||
inc(i)
|
||||
elif s[i] == '-':
|
||||
inc(i)
|
||||
sign = 1
|
||||
if s[i] in {'0'..'9'}:
|
||||
result = 0
|
||||
while s[i] in {'0'..'9'}:
|
||||
result = result * 10 - (ord(s[i]) - ord('0'))
|
||||
inc(i)
|
||||
while s[i] == '_':
|
||||
inc(i) # underscores are allowed and ignored
|
||||
result = result * sign
|
||||
index = i # store index back
|
||||
else:
|
||||
index = -1
|
||||
|
||||
{.pop.} # overflowChecks
|
||||
|
||||
proc parseInt(s: string): int =
|
||||
var
|
||||
index: int
|
||||
res: BiggestInt
|
||||
index = strStart
|
||||
res = rawParseInt(s, index)
|
||||
if index == -1:
|
||||
raise newException(EInvalidValue, "invalid integer: " & s)
|
||||
elif (sizeof(int) <= 4) and
|
||||
((res < low(int)) or (res > high(int))):
|
||||
raise newException(EOverflow, "overflow")
|
||||
else:
|
||||
result = int(res) # convert to smaller integer type
|
||||
|
||||
proc ParseFloat(s: string): float =
|
||||
var
|
||||
hd, esign, sign: float
|
||||
exponent, i: int
|
||||
flags: int
|
||||
result = 0.0
|
||||
i = 0
|
||||
exponent = 0
|
||||
esign = 1.0
|
||||
flags = 0
|
||||
sign = 1.0
|
||||
if s[i] == '+': inc(i)
|
||||
elif s[i] == '-':
|
||||
sign = -1.0
|
||||
inc(i)
|
||||
while s[i] in {'0'..'9'}:
|
||||
# Read integer part
|
||||
flags = flags or 1
|
||||
result = result * 10.0 + toFloat(ord(s[i]) - ord('0'))
|
||||
inc(i)
|
||||
while s[i] == '_': inc(i)
|
||||
# Decimal?
|
||||
if s[i] == '.':
|
||||
hd = 1.0
|
||||
inc(i)
|
||||
while s[i] in {'0'..'9'}:
|
||||
# Read fractional part
|
||||
flags = flags or 2
|
||||
result = result * 10.0 + toFloat(ord(s[i]) - ord('0'))
|
||||
hd = hd * 10.0
|
||||
inc(i)
|
||||
while s[i] == '_': inc(i)
|
||||
result = result / hd # this complicated way preserves precision
|
||||
# Again, read integer and fractional part
|
||||
if flags == 0:
|
||||
raise newException(EInvalidValue, "invalid float:" & s)
|
||||
# Exponent?
|
||||
if s[i] in {'e', 'E'}:
|
||||
inc(i)
|
||||
if s[i] == '+':
|
||||
inc(i)
|
||||
elif s[i] == '-':
|
||||
esign = -1.0
|
||||
inc(i)
|
||||
if s[i] notin {'0'..'9'}:
|
||||
raise newException(EInvalidValue, "invalid float: " & s)
|
||||
while s[i] in {'0'..'9'}:
|
||||
exponent = exponent * 10 + ord(s[i]) - ord('0')
|
||||
inc(i)
|
||||
while s[i] == '_': inc(i)
|
||||
# Calculate Exponent
|
||||
hd = 1.0
|
||||
for j in 1..exponent:
|
||||
hd = hd * 10.0
|
||||
if esign > 0.0: result = result * hd
|
||||
else: result = result / hd
|
||||
# Not all characters are read?
|
||||
if s[i] != '\0': raise newException(EInvalidValue, "invalid float: " & s)
|
||||
# evaluate sign
|
||||
result = result * sign
|
||||
|
||||
proc toOct*(x: BiggestInt, len: int): string =
|
||||
## converts `x` into its octal representation. The resulting string is
|
||||
## always `len` characters long. No leading ``0c`` prefix is generated.
|
||||
var
|
||||
mask, shift: BiggestInt
|
||||
assert(len > 0)
|
||||
result = newString(len)
|
||||
mask = 7
|
||||
shift = 0
|
||||
for j in countdown(len-1, 0):
|
||||
result[j] = chr(int((x and mask) shr shift) + ord('0'))
|
||||
shift = shift + 3
|
||||
mask = mask shl 3
|
||||
|
||||
proc toBin*(x: BiggestInt, len: int): string =
|
||||
## converts `x` into its binary representation. The resulting string is
|
||||
## always `len` characters long. No leading ``0b`` prefix is generated.
|
||||
var
|
||||
mask, shift: BiggestInt
|
||||
assert(len > 0)
|
||||
result = newString(len)
|
||||
mask = 1
|
||||
shift = 0
|
||||
for j in countdown(len-1, 0):
|
||||
result[j] = chr(int((x and mask) shr shift) + ord('0'))
|
||||
shift = shift + 1
|
||||
mask = mask shl 1
|
||||
|
||||
{.pop.}
|
||||
163
lib/sysio.nim
Executable file
163
lib/sysio.nim
Executable file
|
|
@ -0,0 +1,163 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
|
||||
## Nimrod's standard IO library. It contains high-performance
|
||||
## routines for reading and writing data to (buffered) files or
|
||||
## TTYs.
|
||||
|
||||
{.push debugger:off .} # the user does not want to trace a part
|
||||
# of the standard library!
|
||||
|
||||
|
||||
proc fputs(c: cstring, f: TFile) {.importc: "fputs", noDecl.}
|
||||
proc fgets(c: cstring, n: int, f: TFile): cstring {.importc: "fgets", noDecl.}
|
||||
proc fgetc(stream: TFile): int {.importc: "fgetc", nodecl.}
|
||||
proc ungetc(c: int, f: TFile) {.importc: "ungetc", nodecl.}
|
||||
proc putc(c: Char, stream: TFile) {.importc: "putc", nodecl.}
|
||||
proc fprintf(f: TFile, frmt: CString) {.importc: "fprintf", nodecl, varargs.}
|
||||
proc strlen(c: cstring): int {.importc: "strlen", nodecl.}
|
||||
|
||||
proc setvbuf(stream: TFile, buf: pointer, typ, size: cint): cint {.
|
||||
importc, nodecl.}
|
||||
|
||||
proc write(f: TFile, c: cstring) = fputs(c, f)
|
||||
|
||||
var
|
||||
IOFBF {.importc: "_IOFBF", nodecl.}: cint
|
||||
IONBF {.importc: "_IONBF", nodecl.}: cint
|
||||
|
||||
# copied here to remove dependancy on strutils:
|
||||
#proc toNimstr(x: Cstring, len: int): string {.
|
||||
# noSideEffect, importc: "toNimStr".}
|
||||
|
||||
proc rawReadLine(f: TFile, result: var string) {.noStatic.} =
|
||||
# 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
|
||||
var
|
||||
c: cint
|
||||
setLen(result, 0) # reuse the buffer!
|
||||
while True:
|
||||
c = fgetc(f)
|
||||
if c < 0:
|
||||
result = nil
|
||||
break # EOF
|
||||
if c == 10: break # LF
|
||||
if c == 13: # CR
|
||||
c = fgetc(f) # is the next char LF?
|
||||
if c != 10: ungetc(c, f) # no, put the character back
|
||||
break
|
||||
add result, chr(int(c))
|
||||
|
||||
proc readLine(f: TFile): string =
|
||||
result = ""
|
||||
rawReadLine(f, result)
|
||||
|
||||
proc readFile(filename: string): string =
|
||||
var f: TFile
|
||||
try:
|
||||
if openFile(f, filename):
|
||||
var len = getFileSize(f)
|
||||
if len < high(int):
|
||||
result = newString(int(len))
|
||||
if readBuffer(f, addr(result[0]), int(len)) != len:
|
||||
result = nil
|
||||
closeFile(f)
|
||||
else:
|
||||
result = nil
|
||||
except EIO:
|
||||
result = nil
|
||||
|
||||
proc write(f: TFile, s: string) = fputs(s, f)
|
||||
proc write(f: TFile, i: int) = fprintf(f, "%ld", i)
|
||||
proc write(f: TFile, b: bool) =
|
||||
if b: write(f, "true")
|
||||
else: write(f, "false")
|
||||
proc write(f: TFile, r: float) = fprintf(f, "%g", r)
|
||||
proc write(f: TFile, c: Char) = putc(c, f)
|
||||
|
||||
proc EndOfFile(f: TFile): bool =
|
||||
# do not blame me; blame the ANSI C standard this is so brain-damaged
|
||||
var
|
||||
c: int
|
||||
c = fgetc(f)
|
||||
ungetc(c, f)
|
||||
return c == -1
|
||||
|
||||
proc writeln[Ty](f: TFile, x: Ty) =
|
||||
write(f, x)
|
||||
write(f, "\n")
|
||||
proc echo[Ty](x: Ty) = writeln(stdout, x)
|
||||
|
||||
# interface to the C procs:
|
||||
proc fopen(filename, mode: CString): pointer {.importc: "fopen", noDecl.}
|
||||
|
||||
const
|
||||
FormatOpen: array [TFileMode, string] = ["rb", "wb", "w+b", "r+b", "ab"]
|
||||
#"rt", "wt", "w+t", "r+t", "at"
|
||||
# we always use binary here as for Nimrod the OS line ending
|
||||
# should not be translated.
|
||||
|
||||
|
||||
proc OpenFile(f: var TFile, filename: string,
|
||||
mode: TFileMode = fmRead,
|
||||
bufSize: int = -1): Bool =
|
||||
var
|
||||
p: pointer
|
||||
p = fopen(filename, FormatOpen[mode])
|
||||
result = (p != nil)
|
||||
f = cast[TFile](p)
|
||||
if bufSize > 0:
|
||||
if setvbuf(f, nil, IOFBF, bufSize) != 0:
|
||||
raise newException(EOutOfMemory, "out of memory")
|
||||
elif bufSize == 0:
|
||||
discard setvbuf(f, nil, IONBF, 0)
|
||||
|
||||
# C routine that is used here:
|
||||
proc fread(buf: Pointer, size, n: int, f: TFile): int {.
|
||||
importc: "fread", noDecl.}
|
||||
proc fseek(f: TFile, offset: clong, whence: int): int {.
|
||||
importc: "fseek", noDecl.}
|
||||
proc ftell(f: TFile): int {.importc: "ftell", noDecl.}
|
||||
|
||||
proc fwrite(buf: Pointer, size, n: int, f: TFile): int {.
|
||||
importc: "fwrite", noDecl.}
|
||||
# size_t fwrite(const void *ptr, size_t size, size_t n, FILE *stream);
|
||||
|
||||
proc readBuffer(f: TFile, buffer: pointer, len: int): int =
|
||||
result = fread(buffer, 1, len, f)
|
||||
|
||||
proc ReadBytes(f: TFile, a: var openarray[byte], start, len: int): int =
|
||||
result = readBuffer(f, addr(a[start]), len)
|
||||
|
||||
proc ReadChars(f: TFile, a: var openarray[char], start, len: int): int =
|
||||
result = readBuffer(f, addr(a[start]), len)
|
||||
|
||||
proc writeBytes(f: TFile, a: openarray[byte], start, len: int): int =
|
||||
result = writeBuffer(f, addr(a[start]), len)
|
||||
proc writeChars(f: TFile, a: openarray[char], start, len: int): int =
|
||||
result = writeBuffer(f, addr(a[start]), len)
|
||||
proc writeBuffer(f: TFile, buffer: pointer, len: int): int =
|
||||
result = fwrite(buffer, 1, len, f)
|
||||
|
||||
proc setFilePos(f: TFile, pos: int64) =
|
||||
if fseek(f, clong(pos), 0) != 0:
|
||||
raise newException(EIO, "cannot set file position")
|
||||
|
||||
proc getFilePos(f: TFile): int64 =
|
||||
result = ftell(f)
|
||||
if result < 0: raise newException(EIO, "cannot retrieve file position")
|
||||
|
||||
proc getFileSize(f: TFile): int64 =
|
||||
var oldPos = getFilePos(f)
|
||||
discard fseek(f, 0, 2) # seek the end of the file
|
||||
result = getFilePos(f)
|
||||
setFilePos(f, oldPos)
|
||||
|
||||
{.pop.}
|
||||
294
lib/sysstr.nim
Executable file
294
lib/sysstr.nim
Executable file
|
|
@ -0,0 +1,294 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
# string & sequence handling procedures needed by the code generator
|
||||
|
||||
# strings are dynamically resized, have a length field
|
||||
# and are zero-terminated, so they can be casted to C
|
||||
# strings easily
|
||||
# we don't use refcounts because that's a behaviour
|
||||
# the programmer may not want
|
||||
|
||||
type
|
||||
TStringDesc {.importc, nodecl.} = record
|
||||
len, space: int # len and space without counting the terminating zero
|
||||
data: array[0..0, char] # for the '\0' character
|
||||
|
||||
mstring {.importc: "string".} = ptr TStringDesc
|
||||
|
||||
# implementation:
|
||||
|
||||
proc resize(old: int): int {.inline.} =
|
||||
assert(old < 65536 * 4)
|
||||
if old <= 0: return 1
|
||||
elif old < 65536: return old * 2
|
||||
else: return old * 3 div 2 # for large arrays * 3/2 is better
|
||||
|
||||
proc cmpStrings(a, b: mstring): int {.inline, compilerProc.} =
|
||||
if a == b: return 0
|
||||
if a == nil: return -1
|
||||
if b == nil: return 1
|
||||
return c_strcmp(a.data, b.data)
|
||||
|
||||
proc eqStrings(a, b: mstring): bool {.inline, compilerProc.} =
|
||||
if a == b: return true
|
||||
if a == nil or b == nil: return false
|
||||
return a.len == b.len and
|
||||
c_memcmp(a.data, b.data, a.len * sizeof(char)) == 0
|
||||
|
||||
proc rawNewString(space: int): mstring {.compilerProc.} =
|
||||
result = cast[mstring](newObj(addr(strDesc), sizeof(TStringDesc) +
|
||||
space * sizeof(char)))
|
||||
result.len = 0
|
||||
result.space = space
|
||||
result.data[0] = '\0'
|
||||
|
||||
proc mnewString(len: int): mstring {.exportc.} =
|
||||
result = rawNewString(len)
|
||||
result.len = len
|
||||
result.data[len] = '\0'
|
||||
|
||||
proc toNimStr(str: CString, len: int): mstring {.compilerProc.} =
|
||||
result = rawNewString(len)
|
||||
result.len = len
|
||||
c_memcpy(result.data, str, (len+1) * sizeof(Char))
|
||||
result.data[len] = '\0' # IO.readline relies on this!
|
||||
|
||||
proc cstrToNimstr(str: CString): mstring {.compilerProc.} =
|
||||
return toNimstr(str, c_strlen(str))
|
||||
|
||||
proc copyString(src: mstring): mstring {.compilerProc.} =
|
||||
result = rawNewString(src.space)
|
||||
result.len = src.len
|
||||
c_memcpy(result.data, src.data, (src.len + 1) * sizeof(Char))
|
||||
|
||||
proc hashString(s: string): int {.compilerproc.} =
|
||||
# the compiler needs exactly the same hash function!
|
||||
# this used to be used for efficient generation of string case statements
|
||||
var
|
||||
h: int
|
||||
h = 0
|
||||
for i in 0..Len(s)-1:
|
||||
h = h +% Ord(s[i])
|
||||
h = h +% h shl 10
|
||||
h = h xor (h shr 6)
|
||||
h = h +% h shl 3
|
||||
h = h xor (h shr 11)
|
||||
h = h +% h shl 15
|
||||
result = h
|
||||
|
||||
# copy(s: string, start = 0): string
|
||||
# {.extern: "copyStr", noDecl, noSideEffect.}
|
||||
# copy(s: string, start, len: int): string
|
||||
# {.extern: "copyStrLen", noDecl, noSideEffect.}
|
||||
#
|
||||
# setLength(var s: string, newlen: int)
|
||||
# {.extern: "setLengthStr", noDecl, noSideEffect.}
|
||||
|
||||
|
||||
proc copyStrLast(s: mstring, start, last: int): mstring {.exportc.} =
|
||||
var
|
||||
len: int
|
||||
if start >= s.len: return mnewString(0) # BUGFIX
|
||||
if last >= s.len:
|
||||
len = s.len - start # - 1 + 1
|
||||
else:
|
||||
len = last - start + 1
|
||||
result = rawNewString(len)
|
||||
result.len = len
|
||||
c_memcpy(result.data, addr(s.data[start]), len * sizeof(Char))
|
||||
result.data[len] = '\0'
|
||||
|
||||
proc copyStr(s: mstring, start: int): mstring {.exportc.} =
|
||||
return copyStrLast(s, start, s.len-1)
|
||||
|
||||
proc addChar(s: mstring, c: char): mstring {.compilerProc.} =
|
||||
result = s
|
||||
if result.len >= result.space:
|
||||
result.space = resize(result.space)
|
||||
result = cast[mstring](growObj(result,
|
||||
sizeof(TStringDesc) + result.space * sizeof(char)))
|
||||
result.data[result.len] = c
|
||||
result.data[result.len+1] = '\0'
|
||||
inc(result.len)
|
||||
|
||||
# These routines should be used like following:
|
||||
# <Nimrod code>
|
||||
# s &= "hallo " & name & " how do you feel?"
|
||||
#
|
||||
# <generated C code>
|
||||
# {
|
||||
# s = resizeString(s, 6 + name->len + 17);
|
||||
# appendString(s, strLit1);
|
||||
# appendString(s, strLit2);
|
||||
# appendString(s, strLit3);
|
||||
# }
|
||||
#
|
||||
# <Nimrod code>
|
||||
# s = "hallo " & name & " how do you feel?"
|
||||
#
|
||||
# <generated C code>
|
||||
# {
|
||||
# string tmp0;
|
||||
# tmp0 = rawNewString(6 + name->len + 17);
|
||||
# appendString(s, strLit1);
|
||||
# appendString(s, strLit2);
|
||||
# appendString(s, strLit3);
|
||||
# s = tmp0;
|
||||
# }
|
||||
#
|
||||
# <Nimrod code>
|
||||
# s = ""
|
||||
#
|
||||
# <generated C code>
|
||||
# s = rawNewString(0);
|
||||
|
||||
proc resizeString(dest: mstring, addlen: int): mstring {.compilerproc.} =
|
||||
if dest.len + addLen + 1 <= dest.space: # BUGFIX: this is horrible!
|
||||
result = dest
|
||||
else: # slow path:
|
||||
var
|
||||
sp = max(resize(dest.space), dest.len + addLen + 1)
|
||||
result = cast[mstring](growObj(dest, sizeof(TStringDesc) +
|
||||
sp * sizeof(Char)))
|
||||
# DO NOT UPDATE LEN YET: dest.len = newLen
|
||||
result.space = sp
|
||||
|
||||
proc appendString(dest, src: mstring) {.compilerproc, inline.} =
|
||||
c_memcpy(addr(dest.data[dest.len]), src.data, (src.len + 1) * sizeof(Char))
|
||||
inc(dest.len, src.len)
|
||||
|
||||
proc appendChar(dest: mstring, c: char) {.compilerproc, inline.} =
|
||||
dest.data[dest.len] = c
|
||||
dest.data[dest.len+1] = '\0'
|
||||
inc(dest.len)
|
||||
|
||||
proc setLengthStr(s: mstring, newLen: int): mstring {.compilerProc.} =
|
||||
var n = max(newLen, 0)
|
||||
if n <= s.space:
|
||||
result = s
|
||||
else:
|
||||
result = resizeString(s, n)
|
||||
result.len = n
|
||||
result.data[n] = '\0'
|
||||
|
||||
# ----------------- sequences ----------------------------------------------
|
||||
|
||||
proc incrSeq(seq: PGenericSeq, elemSize: int): PGenericSeq {.compilerProc.} =
|
||||
# increments the length by one:
|
||||
# this is needed for supporting the &= operator;
|
||||
#
|
||||
# add seq x generates:
|
||||
# seq = incrSeq(seq, sizeof(x));
|
||||
# seq[seq->len-1] = x;
|
||||
result = seq
|
||||
if result.len >= result.space:
|
||||
var
|
||||
s: TAddress
|
||||
result.space = resize(result.space)
|
||||
result = cast[PGenericSeq](growObj(result, elemSize * result.space +
|
||||
GenericSeqSize))
|
||||
# set new elements to zero:
|
||||
s = cast[TAddress](result)
|
||||
zeroMem(cast[pointer](s + GenericSeqSize + (result.len * elemSize)),
|
||||
(result.space - result.len) * elemSize)
|
||||
# for i in len .. space-1:
|
||||
# seq->data[i] = 0
|
||||
inc(result.len)
|
||||
|
||||
proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
|
||||
compilerProc.} =
|
||||
result = seq
|
||||
if result.space < newLen:
|
||||
var
|
||||
s: TAddress
|
||||
result.space = max(resize(result.space), newLen)
|
||||
result = cast[PGenericSeq](growObj(result, elemSize * result.space +
|
||||
GenericSeqSize))
|
||||
# set new elements to zero (needed for GC):
|
||||
s = cast[TAddress](result)
|
||||
zeroMem(cast[pointer](s + GenericSeqSize + (result.len * elemSize)),
|
||||
(result.space - result.len) * elemSize)
|
||||
# Else: We could decref references, if we had type information here :-(
|
||||
# However, this does not happen often
|
||||
result.len = newLen
|
||||
|
||||
# --------------- other string routines ----------------------------------
|
||||
proc `$`(x: int): string =
|
||||
result = newString(sizeof(x)*4)
|
||||
var i = 0
|
||||
var y = x
|
||||
while True:
|
||||
var d = y div 10
|
||||
result[i] = chr(abs(int(y - d*10)) + ord('0'))
|
||||
inc(i)
|
||||
y = d
|
||||
if y == 0: break
|
||||
if x < 0:
|
||||
result[i] = '-'
|
||||
inc(i)
|
||||
setLen(result, i)
|
||||
# mirror the string:
|
||||
for j in 0..i div 2 - 1:
|
||||
swap(result[j], result[i-j-1])
|
||||
|
||||
{.push warnings: off.}
|
||||
proc `$`(x: float): string =
|
||||
var buf: array [0..59, char]
|
||||
c_sprintf(buf, "%#g", x)
|
||||
return $buf
|
||||
{.pop.}
|
||||
|
||||
proc `$`(x: int64): string =
|
||||
# we don't rely on C's runtime here as some C compiler's
|
||||
# int64 support is weak
|
||||
result = newString(sizeof(x)*4)
|
||||
var i = 0
|
||||
var y = x
|
||||
while True:
|
||||
var d = y div 10
|
||||
result[i] = chr(abs(int(y - d*10)) + ord('0'))
|
||||
inc(i)
|
||||
y = d
|
||||
if y == 0: break
|
||||
if x < 0:
|
||||
result[i] = '-'
|
||||
inc(i)
|
||||
setLen(result, i)
|
||||
# mirror the string:
|
||||
for j in 0..i div 2 - 1:
|
||||
swap(result[j], result[i-j-1])
|
||||
|
||||
proc `$`(x: bool): string =
|
||||
if x: result = "true"
|
||||
else: result = "false"
|
||||
|
||||
proc `$`(x: char): string =
|
||||
result = newString(1)
|
||||
result[0] = x
|
||||
|
||||
proc `$`(x: string): string =
|
||||
# this is useful for generic code!
|
||||
return x
|
||||
|
||||
|
||||
proc binaryStrSearch(x: openarray[string], y: string): int {.compilerproc.} =
|
||||
var
|
||||
a = 0
|
||||
b = len(x)
|
||||
while a < b:
|
||||
var mid = (a + b) div 2
|
||||
if x[mid] < y:
|
||||
a = mid + 1
|
||||
else:
|
||||
b = mid
|
||||
if (a < len(x)) and (x[a] == y):
|
||||
return a
|
||||
else:
|
||||
return -1
|
||||
1184
lib/system.nim
Executable file
1184
lib/system.nim
Executable file
File diff suppressed because it is too large
Load diff
179
lib/times.nim
Executable file
179
lib/times.nim
Executable file
|
|
@ -0,0 +1,179 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
|
||||
## This module contains routines and types for dealing with time.
|
||||
|
||||
{.push debugger:off .} # the user does not want to trace a part
|
||||
# of the standard library!
|
||||
|
||||
import
|
||||
strutils
|
||||
|
||||
type
|
||||
TMonth* = enum ## represents a month
|
||||
mJan, mFeb, mMar, mApr, mMay, mJun, mJul, mAug, mSep, mOct, mNov, mDec
|
||||
TWeekDay* = enum ## represents a weekday
|
||||
dMon, dTue, dWed, dThu, dFri, dSat, dSun
|
||||
|
||||
TTime* {.importc: "time_t".} = record ## abstract type that represents a time
|
||||
|
||||
TTimeInfo* = record ## represents a time in different parts
|
||||
second*: range[0..61] ## The number of seconds after the minute,
|
||||
## normally in the range 0 to 59, but can
|
||||
## be up to 61 to allow for leap seconds.
|
||||
minute*: range[0..59] ## The number of minutes after the hour,
|
||||
## in the range 0 to 59.
|
||||
hour*: range[0..23] ## The number of hours past midnight,
|
||||
## in the range 0 to 23.
|
||||
monthday*: range[1..31] ## The day of the month, in the range 1 to 31.
|
||||
month*: TMonth ## The current month.
|
||||
year*: int ## The current year.
|
||||
weekday*: TWeekDay ## The current day of the week.
|
||||
yearday*: range[0..365] ## The number of days since January 1,
|
||||
## in the range 0 to 365.
|
||||
|
||||
proc getTime*(): TTime ## gets the current calendar time
|
||||
proc getLocalTime*(t: TTime): TTimeInfo
|
||||
## converts the calendar time `t` to broken-time representation,
|
||||
## expressed relative to the user's specified time zone.
|
||||
proc getGMTime*(t: TTime): TTimeInfo
|
||||
## converts the calendar time `t` to broken-down time representation,
|
||||
## expressed in Coordinated Universal Time (UTC).
|
||||
|
||||
proc TimeInfoToTime*(timeInfo: TTimeInfo): TTime
|
||||
## converts a broken-down time structure, expressed as local time, to
|
||||
## calendar time representation. The function ignores the specified
|
||||
## contents of the structure members `weekday` and `yearday` and recomputes
|
||||
## them from the other information in the broken-down time structure.
|
||||
|
||||
proc `$` *(timeInfo: TTimeInfo): string
|
||||
## converts a `TTimeInfo` record to a
|
||||
## string representation.
|
||||
proc `$` *(time: TTime): string
|
||||
## converts a calendar time to a
|
||||
## string representation.
|
||||
|
||||
proc getDateStr*(): string
|
||||
## gets the current date as a string of the format
|
||||
## ``YYYY-MM-DD``.
|
||||
proc getClockStr*(): string
|
||||
## gets the current clock time as a string of the format ``HH:MM:SS``.
|
||||
|
||||
proc `-` *(a, b: TTime): int64
|
||||
## computes the difference of two calendar times. Result is in seconds.
|
||||
|
||||
proc getStartMilsecs*(): int
|
||||
## get the miliseconds from the start of the program
|
||||
|
||||
#implementation
|
||||
|
||||
# C wrapper:
|
||||
type
|
||||
structTM {.importc: "struct tm".} = record
|
||||
second {.importc: "tm_sec".},
|
||||
minute {.importc: "tm_min".},
|
||||
hour {.importc: "tm_hour".},
|
||||
monthday {.importc: "tm_mday".},
|
||||
month {.importc: "tm_mon".},
|
||||
year {.importc: "tm_year".},
|
||||
weekday {.importc: "tm_wday".},
|
||||
yearday {.importc: "tm_yday".},
|
||||
isdst {.importc: "tm_isdst".}: cint
|
||||
|
||||
PTimeInfo = ptr structTM
|
||||
PTime = ptr TTime
|
||||
|
||||
TClock {.importc: "clock_t".} = range[low(int)..high(int)]
|
||||
|
||||
proc localtime(timer: PTime): PTimeInfo {.
|
||||
importc: "localtime", header: "<time.h>".}
|
||||
proc gmtime(timer: PTime): PTimeInfo {.importc: "gmtime", header: "<time.h>".}
|
||||
proc timec(timer: PTime): TTime {.importc: "time", header: "<time.h>".}
|
||||
proc mktime(t: structTM): TTime {.importc: "mktime", header: "<time.h>".}
|
||||
proc asctime(tblock: structTM): CString {.
|
||||
importc: "asctime", header: "<time.h>".}
|
||||
proc ctime(time: PTime): CString {.importc: "ctime", header: "<time.h>".}
|
||||
# strftime(s: CString, maxsize: int, fmt: CString, t: tm): int {.
|
||||
# importc: "strftime", header: "<time.h>".}
|
||||
proc clock(): TClock {.importc: "clock", header: "<time.h>".}
|
||||
proc difftime(a, b: TTime): float {.importc: "difftime", header: "<time.h>".}
|
||||
|
||||
var
|
||||
clocksPerSec {.importc: "CLOCKS_PER_SEC", nodecl.}: int
|
||||
|
||||
|
||||
# our own procs on top of that:
|
||||
proc tmToTimeInfo(tm: structTM): TTimeInfo =
|
||||
const
|
||||
weekDays: array [0..6, TWeekDay] = [
|
||||
dSun, dMon, dTue, dWed, dThu, dFri, dSat]
|
||||
result.second = int(tm.second)
|
||||
result.minute = int(tm.minute)
|
||||
result.hour = int(tm.hour)
|
||||
result.monthday = int(tm.monthday)
|
||||
result.month = TMonth(tm.month)
|
||||
result.year = tm.year + 1900
|
||||
result.weekday = weekDays[int(tm.weekDay)]
|
||||
result.yearday = int(tm.yearday)
|
||||
|
||||
proc timeInfoToTM(t: TTimeInfo): structTM =
|
||||
const
|
||||
weekDays: array [TWeekDay, int] = [1, 2, 3, 4, 5, 6, 0]
|
||||
result.second = t.second
|
||||
result.minute = t.minute
|
||||
result.hour = t.hour
|
||||
result.monthday = t.monthday
|
||||
result.month = ord(t.month)
|
||||
result.year = t.year - 1900
|
||||
result.weekday = weekDays[t.weekDay]
|
||||
result.yearday = t.yearday
|
||||
result.isdst = -1
|
||||
|
||||
proc `-` (a, b: TTime): int64 =
|
||||
return toInt(difftime(a, b)) # XXX: toBiggestInt is needed here, but
|
||||
# Nim does not support it!
|
||||
|
||||
proc getStartMilsecs(): int = return clock() div (clocksPerSec div 1000)
|
||||
proc getTime(): TTime = return timec(nil)
|
||||
proc getLocalTime(t: TTime): TTimeInfo =
|
||||
var a = t
|
||||
result = tmToTimeInfo(localtime(addr(a))^)
|
||||
# copying is needed anyway to provide reentrancity; thus
|
||||
# the convertion is not expensive
|
||||
|
||||
proc getGMTime(t: TTime): TTimeInfo =
|
||||
var a = t
|
||||
result = tmToTimeInfo(gmtime(addr(a))^)
|
||||
# copying is needed anyway to provide reentrancity; thus
|
||||
# the convertion is not expensive
|
||||
|
||||
proc TimeInfoToTime(timeInfo: TTimeInfo): TTime =
|
||||
var cTimeInfo = timeInfo # for C++ we have to make a copy,
|
||||
# because the header of mktime is broken in my version of libc
|
||||
return mktime(timeInfoToTM(cTimeInfo))
|
||||
|
||||
proc getDateStr(): string =
|
||||
var ti = getLocalTime(getTime())
|
||||
result = $ti.year & "-" & intToStr(ord(ti.month)+1, 2) &
|
||||
"-" & intToStr(ti.monthDay, 2)
|
||||
|
||||
proc getClockStr(): string =
|
||||
var ti = getLocalTime(getTime())
|
||||
result = intToStr(ti.hour, 2) & ':' & intToStr(ti.minute, 2) &
|
||||
':' & intToStr(ti.second, 2)
|
||||
|
||||
proc `$`(timeInfo: TTimeInfo): string =
|
||||
return $asctime(timeInfoToTM(timeInfo))
|
||||
|
||||
proc `$`(time: TTime): string =
|
||||
var a = time
|
||||
return $ctime(addr(a))
|
||||
|
||||
{.pop.}
|
||||
221
lib/typeinfo.nim
Executable file
221
lib/typeinfo.nim
Executable file
|
|
@ -0,0 +1,221 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
# type-info module for Nimrod
|
||||
|
||||
include hti
|
||||
|
||||
proc typeid(x: any): PNimType
|
||||
|
||||
type
|
||||
Variant = opaque record
|
||||
# contains the address and a typeinfo
|
||||
a: pointer # an address
|
||||
k: TNimTypeKind
|
||||
|
||||
# conversions to any and from any are inserted by the compiler!
|
||||
# x.attr is supported, as well as x[]!
|
||||
# here is a special iterator for variants:
|
||||
iterator fields(x: variant): (fieldname: string, value: variant) =
|
||||
proc setField(structure: variant, fieldname: string, value: variant)
|
||||
proc getField(structure: variant, fieldname: string)
|
||||
|
||||
# any is implemented as a pair (val: pointer, info: PTypeInfo)
|
||||
# val is for:
|
||||
# an array - its address
|
||||
# a record - its address
|
||||
# an object - its address
|
||||
# a string - the address of the pointer to the string data
|
||||
# a sequence - the address of the pointer to the sequence data
|
||||
# a float - the address of a memory location where the float is stored
|
||||
# this is a given address; storage comes from compiler or is
|
||||
# already there (in a container)
|
||||
# an int - the address of a memory location where the int is stored
|
||||
# storage comes from compiler or is
|
||||
# already there (in a container)
|
||||
# a cstring - the address of an address of an array of chars
|
||||
# a ref - the address of the ref! (not the ref itself!)
|
||||
|
||||
# But this does not work too well...
|
||||
# Better: any is a ref to Object; than we define intObj, floatObj,
|
||||
# etc.; for strings this not needed as they already fit into the
|
||||
# scheme!
|
||||
#
|
||||
|
||||
type
|
||||
TAnyImpl {.exportc: "TAnyImpl".} = record
|
||||
typ {.exportc: "info".}: PNimType
|
||||
val {.exportc: "val".}: pointer
|
||||
|
||||
proc
|
||||
typeKind(p: PNimType): TTypeKind {.inline.}
|
||||
|
||||
getAnyLength(x: any): int
|
||||
|
||||
isContainer(x: any): bool
|
||||
|
||||
writeAny(container: any, index: int, val: any)
|
||||
readAny(container: any, index: int): any
|
||||
|
||||
writeAny(container: any, name: string, val: any)
|
||||
readAny(container: any, name: string): any
|
||||
|
||||
getAttr(container: any, index: int, out name: string, out val: any)
|
||||
|
||||
getEnumStrings(enumeration: any): sequence of string
|
||||
|
||||
anyToInt(x: any): biggestint
|
||||
anyToFloat(x: any): biggestfloat
|
||||
anyToString(x: any): string
|
||||
anyToChar(x: any): char
|
||||
anyToBool(x: any): bool
|
||||
#anyToT{T}(x: any, out result: T)
|
||||
|
||||
# etc...
|
||||
|
||||
#write(a: array of any) # also possible!
|
||||
|
||||
#generic proc
|
||||
# deepCopy{T}(x: T): T
|
||||
|
||||
import
|
||||
strutils
|
||||
|
||||
proc anyToImpl(a: any): TAnyImpl {.inline.} =
|
||||
result = cast{TAnyImpl}(a)
|
||||
|
||||
proc typeKind(p: PNimType): TTypeKind =
|
||||
result = p.typeKind
|
||||
|
||||
type
|
||||
Pint = untraced ref int
|
||||
Pint8 = untraced ref int8
|
||||
Pint16 = untraced ref int16
|
||||
Pint32 = untraced ref int32
|
||||
Pint64 = untraced ref int64
|
||||
Puint = untraced ref uint
|
||||
Puint8 = untraced ref uint8
|
||||
Puint16 = untraced ref uint16
|
||||
Puint32 = untraced ref uint32
|
||||
Puint64 = untraced ref uint64
|
||||
Pfloat = untraced ref float
|
||||
Pfloat32 = untraced ref float32
|
||||
Pfloat64 = untraced ref float64
|
||||
Pstring = untraced ref string
|
||||
Pbool = untraced ref bool
|
||||
Pchar = untraced ref char
|
||||
|
||||
proc anyToInt(x: any): biggestint =
|
||||
var impl = anyToImpl(x)
|
||||
case impl.typ.typeKind
|
||||
of tyInt, tyEnum: result = cast{pint}(x.val)^
|
||||
of tySInt8: result = cast{pint8}(x.val)^
|
||||
of tySInt16: result = cast{pint16}(x.val)^
|
||||
of tySInt32: result = cast{pint32}(x.val)^
|
||||
of tySInt64: result = cast{pint64}(x.val)^
|
||||
of tyUInt: result = cast{puint}(x.val)^
|
||||
of tyUInt8: result = cast{puint8}(x.val)^
|
||||
of tyUInt16: result = cast{puint16}(x.val)^
|
||||
of tyUInt32: result = cast{puint32}(x.val)^
|
||||
of tyUInt64: result = cast{puint64}(x.val)^
|
||||
else: raise EConvertError
|
||||
|
||||
proc anyToFloat(x: any): biggestfloat =
|
||||
var impl = anyToImpl(x)
|
||||
case impl.typ.typeKind
|
||||
of tyReal: result = cast{pfloat}(x.val)^
|
||||
of tyReal32: result = cast{pfloat32}(x.val)^
|
||||
of tyReal64: result = cast{pfloat64}(x.val)^
|
||||
# of tyReal128:
|
||||
else: raise EConvertError
|
||||
|
||||
proc anyToString(x: any): string =
|
||||
var impl = anyToImpl(x)
|
||||
case impl.typ.typeKind
|
||||
of tyString: result = cast{pstring}(x.val)^
|
||||
else: raise EConvertError
|
||||
|
||||
proc anyToChar(x: any): char =
|
||||
var impl = anyToImpl(x)
|
||||
case impl.typ.typeKind
|
||||
of tyChar: result = cast{pchar}(x.val)^
|
||||
else: raise EConvertError
|
||||
|
||||
proc anyToBool(x: any): bool =
|
||||
var impl = anyToImpl(x)
|
||||
case impl.typ.typeKind
|
||||
of tyBool: result = cast{pbool}(x.val)^
|
||||
else: raise EConvertError
|
||||
|
||||
proc getAnyLength(x: any): int =
|
||||
result = anyToImpl(x).typ.len
|
||||
|
||||
const
|
||||
ContainerSet = {tyArray, tyRecord, tyObject, tyOpenArray, tySequence, tyTable}
|
||||
|
||||
proc isContainer(x: any): bool =
|
||||
result = anyToImpl(x).typ.typeKind in ContainerSet
|
||||
|
||||
proc strcmp(a, b: cstring): int {.external: "strcmp", nodecl.}
|
||||
|
||||
proc strToIndex(info: PTypeInfo, str: string): int =
|
||||
for i in 0..typ.len-1:
|
||||
if strcmp(info.slots[i].name, str) == 0:
|
||||
return i
|
||||
raise EConvertError
|
||||
|
||||
proc writeAny(container: any, index: int, val: any) =
|
||||
var x = anyToImpl(container)
|
||||
if index >= 0 and index < container.len:
|
||||
case x.typ.typeKind
|
||||
of tySequence:
|
||||
var u = cast{TAddress}(x.val)
|
||||
genericAssignAux(cast{pointer}(u) +% x.typ.slots[index].offset +%
|
||||
GenericSeqSize,
|
||||
anyToImpl(val).val, u.typ.baseType)
|
||||
of tyArray:
|
||||
of tyRecord, tyObject:
|
||||
else: raise EConvertError
|
||||
else:
|
||||
raise EIndexError
|
||||
|
||||
|
||||
proc readAny(container: any, index: int): any =
|
||||
var x = anyToImpl(container)
|
||||
if x.typ.typeKind in ContainerSet:
|
||||
if index >= 0 and index < container.len:
|
||||
# XXX
|
||||
|
||||
else:
|
||||
raise EIndexError
|
||||
else:
|
||||
raise EConvertError
|
||||
|
||||
proc writeAny(container: any, name: string, val: any) =
|
||||
result = writeAny(container, strToIndex(anyToImpl(container).typ), val)
|
||||
|
||||
proc readAny(container: any, name: string): any =
|
||||
result = readAny(container, strToIndex(anyToImpl(container).typ))
|
||||
|
||||
proc getAttr(container: any, index: int, out name: string, out val: any) =
|
||||
var x = anyToImpl(container)
|
||||
if x.typ.typeKind in ContainerSet:
|
||||
val = readAny(container, index)
|
||||
name = $x.typ.slots[index].name
|
||||
else:
|
||||
raise EConvertError
|
||||
|
||||
proc getEnumStrings(enumeration: any): sequence of string =
|
||||
result = []
|
||||
var x = anyToImpl(enumeration)
|
||||
if x.typ.typekind == tyEnum:
|
||||
for i in 0 .. x.typ.len-1:
|
||||
result &= $x.typ.slots[i].name
|
||||
else:
|
||||
raise EConvertError
|
||||
103
lib/unicode.nim
Executable file
103
lib/unicode.nim
Executable file
|
|
@ -0,0 +1,103 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
type
|
||||
TUniChar* = int32 ## type that can hold any Unicode character
|
||||
TUniChar16* = int16 ##
|
||||
|
||||
template ones(n) = ((1 shl n)-1)
|
||||
|
||||
proc uniCharLen*(s: string): int =
|
||||
## returns the number of Unicode characters of the string `s`.
|
||||
var i = 0
|
||||
while i < len(s):
|
||||
if ord(s[i]) <= 127:
|
||||
inc(i)
|
||||
elif ord(s[i]) shr 5 == 0b110:
|
||||
inc(i, 2)
|
||||
elif ord(s[i]) shr 4 == 0b1110:
|
||||
inc(i, 3)
|
||||
elif ord(s[i]) shr 3 == 0b11110:
|
||||
inc(i, 4)
|
||||
else:
|
||||
assert(false)
|
||||
inc(result)
|
||||
|
||||
proc uniCharAt*(s: string, i: int): TUniChar =
|
||||
if ord(s[i]) <= 127:
|
||||
result = ord(s[i])
|
||||
elif ord(s[i]) shr 5 == 0b110:
|
||||
assert(ord(s[i+1]) shr 6 == 0b10)
|
||||
result = (ord(s[i]) and ones(5)) shl 6 or (ord(s[i+1]) and ones(6))
|
||||
elif ord(s[i]) shr 4 == 0b1110:
|
||||
assert(ord(s[i+1]) shr 6 == 0b10)
|
||||
assert(ord(s[i+2]) shr 6 == 0b10)
|
||||
result = (ord(s[i]) and ones(4)) shl 12 or
|
||||
(ord(s[i+1]) and ones(6)) shl 6 or
|
||||
(ord(s[i+2]) and ones(6))
|
||||
elif ord(s[i]) shr 3 == 0b11110:
|
||||
assert(ord(s[i+1]) shr 6 == 0b10)
|
||||
assert(ord(s[i+2]) shr 6 == 0b10)
|
||||
assert(ord(s[i+3]) shr 6 == 0b10)
|
||||
result = (ord(s[i]) and ones(3)) shl 18 or
|
||||
(ord(s[i+1]) and ones(6)) shl 12 or
|
||||
(ord(s[i+2]) and ones(6)) shl 6 or
|
||||
(ord(s[i+3]) and ones(6))
|
||||
else:
|
||||
assert(false)
|
||||
|
||||
iterator unichars*(s: string): TUniChar =
|
||||
## iterates over any unicode character of the string `s`. Fastest possible
|
||||
## method.
|
||||
var
|
||||
i = 0
|
||||
result: TUniChar
|
||||
while i < len(s):
|
||||
if ord(s[i]) <= 127:
|
||||
result = ord(s[i])
|
||||
inc(i)
|
||||
elif ord(s[i]) shr 5 == 0b110:
|
||||
result = (ord(s[i]) and ones(5)) shl 6 or (ord(s[i+1]) and ones(6))
|
||||
inc(i, 2)
|
||||
elif ord(s[i]) shr 4 == 0b1110:
|
||||
result = (ord(s[i]) and ones(4)) shl 12 or
|
||||
(ord(s[i+1]) and ones(6)) shl 6 or
|
||||
(ord(s[i+2]) and ones(6))
|
||||
inc(i, 3)
|
||||
elif ord(s[i]) shr 3 == 0b11110:
|
||||
result = (ord(s[i]) and ones(3)) shl 18 or
|
||||
(ord(s[i+1]) and ones(6)) shl 12 or
|
||||
(ord(s[i+2]) and ones(6)) shl 6 or
|
||||
(ord(s[i+3]) and ones(6))
|
||||
inc(i, 4)
|
||||
else:
|
||||
assert(false)
|
||||
yield result
|
||||
|
||||
proc utf8toLocale*(s: string): string
|
||||
proc localeToUtf8*(s: string): string
|
||||
|
||||
proc utf8toUtf16*(s: string): seq[TUniChar16]
|
||||
proc utf8toUcs4*(s: string): seq[TUniChar] =
|
||||
result = []
|
||||
for u in unichars(s):
|
||||
|
||||
proc ucs4ToUtf8(s: seq[TUnichar]): string
|
||||
proc utf16ToUtf8(s: seq[TUnichar16]): string
|
||||
proc ucs4toUft16(s: seq[TUnichar]): seq[TUnichar16]
|
||||
proc uft16toUcs4(s: seq[Tunichar16]): seq[TUnichar]
|
||||
|
||||
proc cmpUnicode*(a, b: string): int =
|
||||
## treats `a` and `b` as UTF-8 strings and compares them. Returns:
|
||||
## | < 0 iff a < b
|
||||
## | > 0 iff a > b
|
||||
## | == 0 iff a == b
|
||||
## This routine is useful for sorting UTF-8 strings.
|
||||
return -1
|
||||
|
||||
2656
lib/windows/mmsystem.nim
Executable file
2656
lib/windows/mmsystem.nim
Executable file
File diff suppressed because it is too large
Load diff
230
lib/windows/nb30.nim
Executable file
230
lib/windows/nb30.nim
Executable file
|
|
@ -0,0 +1,230 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
# NetBIOS 3.0 interface unit
|
||||
|
||||
# This unit contains the definitions for portable NetBIOS 3.0 support.
|
||||
|
||||
import # Data structure templates
|
||||
Windows
|
||||
|
||||
const
|
||||
NCBNAMSZ* = 16 # absolute length of a net name
|
||||
MAX_LANA* = 254 # lana's in range 0 to MAX_LANA inclusive
|
||||
|
||||
type # Network Control Block
|
||||
PNCB* = ptr TNCB
|
||||
TNCBPostProc* = proc (P: PNCB)
|
||||
TNCB* = record # Structure returned to the NCB command NCBASTAT is ADAPTER_STATUS followed
|
||||
# by an array of NAME_BUFFER structures.
|
||||
ncb_command*: Char # command code
|
||||
ncb_retcode*: Char # return code
|
||||
ncb_lsn*: Char # local session number
|
||||
ncb_num*: Char # number of our network name
|
||||
ncb_buffer*: cstring # address of message buffer
|
||||
ncb_length*: int16 # size of message buffer
|
||||
ncb_callname*: array[0..NCBNAMSZ - 1, char] # blank-padded name of remote
|
||||
ncb_name*: array[0..NCBNAMSZ - 1, char] # our blank-padded netname
|
||||
ncb_rto*: Char # rcv timeout/retry count
|
||||
ncb_sto*: Char # send timeout/sys timeout
|
||||
ncb_post*: TNCBPostProc # POST routine address
|
||||
ncb_lana_num*: Char # lana (adapter) number
|
||||
ncb_cmd_cplt*: Char # 0xff => commmand pending
|
||||
ncb_reserve*: array[0..9, Char] # reserved, used by BIOS
|
||||
ncb_event*: THandle # HANDLE to Win32 event which
|
||||
# will be set to the signalled
|
||||
# state when an ASYNCH command
|
||||
# completes
|
||||
|
||||
PAdapterStatus* = ptr TAdapterStatus
|
||||
TAdapterStatus* = record
|
||||
adapter_address*: array[0..5, Char]
|
||||
rev_major*: Char
|
||||
reserved0*: Char
|
||||
adapter_type*: Char
|
||||
rev_minor*: Char
|
||||
duration*: int16
|
||||
frmr_recv*: int16
|
||||
frmr_xmit*: int16
|
||||
iframe_recv_err*: int16
|
||||
xmit_aborts*: int16
|
||||
xmit_success*: DWORD
|
||||
recv_success*: DWORD
|
||||
iframe_xmit_err*: int16
|
||||
recv_buff_unavail*: int16
|
||||
t1_timeouts*: int16
|
||||
ti_timeouts*: int16
|
||||
reserved1*: DWORD
|
||||
free_ncbs*: int16
|
||||
max_cfg_ncbs*: int16
|
||||
max_ncbs*: int16
|
||||
xmit_buf_unavail*: int16
|
||||
max_dgram_size*: int16
|
||||
pending_sess*: int16
|
||||
max_cfg_sess*: int16
|
||||
max_sess*: int16
|
||||
max_sess_pkt_size*: int16
|
||||
name_count*: int16
|
||||
|
||||
PNameBuffer* = ptr TNameBuffer
|
||||
TNameBuffer* = record
|
||||
name*: array[0..NCBNAMSZ - 1, Char]
|
||||
name_num*: Char
|
||||
name_flags*: Char
|
||||
|
||||
|
||||
const # values for name_flags bits.
|
||||
NAME_FLAGS_MASK* = 0x00000087
|
||||
GROUP_NAME* = 0x00000080
|
||||
UNIQUE_NAME* = 0x00000000
|
||||
REGISTERING* = 0x00000000
|
||||
REGISTERED* = 0x00000004
|
||||
DEREGISTERED* = 0x00000005
|
||||
DUPLICATE* = 0x00000006
|
||||
DUPLICATE_DEREG* = 0x00000007
|
||||
|
||||
type # Structure returned to the NCB command NCBSSTAT is SESSION_HEADER followed
|
||||
# by an array of SESSION_BUFFER structures. If the NCB_NAME starts with an
|
||||
# asterisk then an array of these structures is returned containing the
|
||||
# status for all names.
|
||||
PSessionHeader* = ptr TSessionHeader
|
||||
TSessionHeader* = record
|
||||
sess_name*: Char
|
||||
num_sess*: Char
|
||||
rcv_dg_outstanding*: Char
|
||||
rcv_any_outstanding*: Char
|
||||
|
||||
PSessionBuffer* = ptr TSessionBuffer
|
||||
TSessionBuffer* = record
|
||||
lsn*: Char
|
||||
state*: Char
|
||||
local_name*: array[0..NCBNAMSZ - 1, Char]
|
||||
remote_name*: array[0..NCBNAMSZ - 1, Char]
|
||||
rcvs_outstanding*: Char
|
||||
sends_outstanding*: Char
|
||||
|
||||
|
||||
const # Values for state
|
||||
LISTEN_OUTSTANDING* = 0x00000001
|
||||
CALL_PENDING* = 0x00000002
|
||||
SESSION_ESTABLISHED* = 0x00000003
|
||||
HANGUP_PENDING* = 0x00000004
|
||||
HANGUP_COMPLETE* = 0x00000005
|
||||
SESSION_ABORTED* = 0x00000006
|
||||
|
||||
type # Structure returned to the NCB command NCBENUM.
|
||||
# On a system containing lana's 0, 2 and 3, a structure with
|
||||
# length =3, lana[0]=0, lana[1]=2 and lana[2]=3 will be returned.
|
||||
PLanaEnum* = ptr TLanaEnum
|
||||
TLanaEnum* = record # Structure returned to the NCB command NCBFINDNAME is FIND_NAME_HEADER followed
|
||||
# by an array of FIND_NAME_BUFFER structures.
|
||||
len*: Char # Number of valid entries in lana[]
|
||||
lana*: array[0..MAX_LANA, Char]
|
||||
|
||||
PFindNameHeader* = ptr TFindNameHeader
|
||||
TFindNameHeader* = record
|
||||
node_count*: int16
|
||||
reserved*: Char
|
||||
unique_group*: Char
|
||||
|
||||
PFindNameBuffer* = ptr TFindNameBuffer
|
||||
TFindNameBuffer* = record # Structure provided with NCBACTION. The purpose of NCBACTION is to provide
|
||||
# transport specific extensions to netbios.
|
||||
len*: Char
|
||||
access_control*: Char
|
||||
frame_control*: Char
|
||||
destination_addr*: array[0..5, Char]
|
||||
source_addr*: array[0..5, Char]
|
||||
routing_info*: array[0..17, Char]
|
||||
|
||||
PActionHeader* = ptr TActionHeader
|
||||
TActionHeader* = record
|
||||
transport_id*: int32
|
||||
action_code*: int16
|
||||
reserved*: int16
|
||||
|
||||
|
||||
const # Values for transport_id
|
||||
ALL_TRANSPORTS* = "M\0\0\0"
|
||||
MS_NBF* = "MNBF" # Special values and constants
|
||||
|
||||
const # NCB Command codes
|
||||
NCBCALL* = 0x00000010 # NCB CALL
|
||||
NCBLISTEN* = 0x00000011 # NCB LISTEN
|
||||
NCBHANGUP* = 0x00000012 # NCB HANG UP
|
||||
NCBSEND* = 0x00000014 # NCB SEND
|
||||
NCBRECV* = 0x00000015 # NCB RECEIVE
|
||||
NCBRECVANY* = 0x00000016 # NCB RECEIVE ANY
|
||||
NCBCHAINSEND* = 0x00000017 # NCB CHAIN SEND
|
||||
NCBDGSEND* = 0x00000020 # NCB SEND DATAGRAM
|
||||
NCBDGRECV* = 0x00000021 # NCB RECEIVE DATAGRAM
|
||||
NCBDGSENDBC* = 0x00000022 # NCB SEND BROADCAST DATAGRAM
|
||||
NCBDGRECVBC* = 0x00000023 # NCB RECEIVE BROADCAST DATAGRAM
|
||||
NCBADDNAME* = 0x00000030 # NCB ADD NAME
|
||||
NCBDELNAME* = 0x00000031 # NCB DELETE NAME
|
||||
NCBRESET* = 0x00000032 # NCB RESET
|
||||
NCBASTAT* = 0x00000033 # NCB ADAPTER STATUS
|
||||
NCBSSTAT* = 0x00000034 # NCB SESSION STATUS
|
||||
NCBCANCEL* = 0x00000035 # NCB CANCEL
|
||||
NCBADDGRNAME* = 0x00000036 # NCB ADD GROUP NAME
|
||||
NCBENUM* = 0x00000037 # NCB ENUMERATE LANA NUMBERS
|
||||
NCBUNLINK* = 0x00000070 # NCB UNLINK
|
||||
NCBSENDNA* = 0x00000071 # NCB SEND NO ACK
|
||||
NCBCHAINSENDNA* = 0x00000072 # NCB CHAIN SEND NO ACK
|
||||
NCBLANSTALERT* = 0x00000073 # NCB LAN STATUS ALERT
|
||||
NCBACTION* = 0x00000077 # NCB ACTION
|
||||
NCBFINDNAME* = 0x00000078 # NCB FIND NAME
|
||||
NCBTRACE* = 0x00000079 # NCB TRACE
|
||||
ASYNCH* = 0x00000080 # high bit set = asynchronous
|
||||
# NCB Return codes
|
||||
NRC_GOODRET* = 0x00000000 # good return
|
||||
# also returned when ASYNCH request accepted
|
||||
NRC_BUFLEN* = 0x00000001 # illegal buffer length
|
||||
NRC_ILLCMD* = 0x00000003 # illegal command
|
||||
NRC_CMDTMO* = 0x00000005 # command timed out
|
||||
NRC_INCOMP* = 0x00000006 # message incomplete, issue another command
|
||||
NRC_BADDR* = 0x00000007 # illegal buffer address
|
||||
NRC_SNUMOUT* = 0x00000008 # session number out of range
|
||||
NRC_NORES* = 0x00000009 # no resource available
|
||||
NRC_SCLOSED* = 0x0000000A # session closed
|
||||
NRC_CMDCAN* = 0x0000000B # command cancelled
|
||||
NRC_DUPNAME* = 0x0000000D # duplicate name
|
||||
NRC_NAMTFUL* = 0x0000000E # name table full
|
||||
NRC_ACTSES* = 0x0000000F # no deletions, name has active sessions
|
||||
NRC_LOCTFUL* = 0x00000011 # local session table full
|
||||
NRC_REMTFUL* = 0x00000012 # remote session table full
|
||||
NRC_ILLNN* = 0x00000013 # illegal name number
|
||||
NRC_NOCALL* = 0x00000014 # no callname
|
||||
NRC_NOWILD* = 0x00000015 # cannot put * in NCB_NAME
|
||||
NRC_INUSE* = 0x00000016 # name in use on remote adapter
|
||||
NRC_NAMERR* = 0x00000017 # name deleted
|
||||
NRC_SABORT* = 0x00000018 # session ended abnormally
|
||||
NRC_NAMCONF* = 0x00000019 # name conflict detected
|
||||
NRC_IFBUSY* = 0x00000021 # interface busy, IRET before retrying
|
||||
NRC_TOOMANY* = 0x00000022 # too many commands outstanding, retry later
|
||||
NRC_BRIDGE* = 0x00000023 # NCB_lana_num field invalid
|
||||
NRC_CANOCCR* = 0x00000024 # command completed while cancel occurring
|
||||
NRC_CANCEL* = 0x00000026 # command not valid to cancel
|
||||
NRC_DUPENV* = 0x00000030 # name defined by anther local process
|
||||
NRC_ENVNOTDEF* = 0x00000034 # environment undefined. RESET required
|
||||
NRC_OSRESNOTAV* = 0x00000035 # required OS resources exhausted
|
||||
NRC_MAXAPPS* = 0x00000036 # max number of applications exceeded
|
||||
NRC_NOSAPS* = 0x00000037 # no saps available for netbios
|
||||
NRC_NORESOURCES* = 0x00000038 # requested resources are not available
|
||||
NRC_INVADDRESS* = 0x00000039 # invalid ncb address or length > segment
|
||||
NRC_INVDDID* = 0x0000003B # invalid NCB DDID
|
||||
NRC_LOCKFAIL* = 0x0000003C # lock of user area failed
|
||||
NRC_OPENERR* = 0x0000003F # NETBIOS not loaded
|
||||
NRC_SYSTEM* = 0x00000040 # system error
|
||||
NRC_PENDING* = 0x000000FF # asynchronous command is not yet finished
|
||||
# main user entry point for NetBIOS 3.0
|
||||
# Usage: Result = Netbios( pncb );
|
||||
|
||||
proc Netbios*(P: PNCB): Char{.stdcall, dynlib: "netapi32.dll",
|
||||
importc: "Netbios".}
|
||||
# implementation
|
||||
208
lib/windows/ole2.nim
Executable file
208
lib/windows/ole2.nim
Executable file
|
|
@ -0,0 +1,208 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
import
|
||||
windows
|
||||
|
||||
const
|
||||
GUID_NULL*: TGUID = (D1: 0x00000000, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000])
|
||||
IID_IUnknown*: TGUID = (D1: 0x00000000, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IClassFactory*: TGUID = (D1: 0x00000001, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IMarshal*: TGUID = (D1: 0x00000003, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IMalloc*: TGUID = (D1: 0x00000002, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IStdMarshalInfo*: TGUID = (D1: 0x00000018, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IExternalConnection*: TGUID = (D1: 0x00000019, D2: 0x00000000,
|
||||
D3: 0x00000000, D4: [0x000000C0, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000046])
|
||||
IID_IEnumUnknown*: TGUID = (D1: 0x00000100, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IBindCtx*: TGUID = (D1: 0x0000000E, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IEnumMoniker*: TGUID = (D1: 0x00000102, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IRunnableObject*: TGUID = (D1: 0x00000126, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IRunningObjectTable*: TGUID = (D1: 0x00000010, D2: 0x00000000,
|
||||
D3: 0x00000000, D4: [0x000000C0, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000046])
|
||||
IID_IPersist*: TGUID = (D1: 0x0000010C, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IPersistStream*: TGUID = (D1: 0x00000109, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IMoniker*: TGUID = (D1: 0x0000000F, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IEnumString*: TGUID = (D1: 0x00000101, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IStream*: TGUID = (D1: 0x0000000C, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IEnumStatStg*: TGUID = (D1: 0x0000000D, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IStorage*: TGUID = (D1: 0x0000000B, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IPersistFile*: TGUID = (D1: 0x0000010B, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IPersistStorage*: TGUID = (D1: 0x0000010A, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_ILockBytes*: TGUID = (D1: 0x0000000A, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IEnumFormatEtc*: TGUID = (D1: 0x00000103, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IEnumStatData*: TGUID = (D1: 0x00000105, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IRootStorage*: TGUID = (D1: 0x00000012, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IAdviseSink*: TGUID = (D1: 0x0000010F, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IAdviseSink2*: TGUID = (D1: 0x00000125, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IDataObject*: TGUID = (D1: 0x0000010E, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IDataAdviseHolder*: TGUID = (D1: 0x00000110, D2: 0x00000000,
|
||||
D3: 0x00000000, D4: [0x000000C0, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000046])
|
||||
IID_IMessageFilter*: TGUID = (D1: 0x00000016, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IRpcChannelBuffer*: TGUID = (D1: 0xD5F56B60, D2: 0x0000593B,
|
||||
D3: 0x0000101A, D4: [0x000000B5, 0x00000069, 0x00000008, 0x00000000,
|
||||
0x0000002B, 0x0000002D, 0x000000BF, 0x0000007A])
|
||||
IID_IRpcProxyBuffer*: TGUID = (D1: 0xD5F56A34, D2: 0x0000593B, D3: 0x0000101A, D4: [
|
||||
0x000000B5, 0x00000069, 0x00000008, 0x00000000, 0x0000002B, 0x0000002D,
|
||||
0x000000BF, 0x0000007A])
|
||||
IID_IRpcStubBuffer*: TGUID = (D1: 0xD5F56AFC, D2: 0x0000593B, D3: 0x0000101A, D4: [
|
||||
0x000000B5, 0x00000069, 0x00000008, 0x00000000, 0x0000002B, 0x0000002D,
|
||||
0x000000BF, 0x0000007A])
|
||||
IID_IPSFactoryBuffer*: TGUID = (D1: 0xD5F569D0, D2: 0x0000593B,
|
||||
D3: 0x0000101A, D4: [0x000000B5, 0x00000069, 0x00000008, 0x00000000,
|
||||
0x0000002B, 0x0000002D, 0x000000BF, 0x0000007A])
|
||||
IID_ICreateTypeInfo*: TGUID = (D1: 0x00020405, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_ICreateTypeLib*: TGUID = (D1: 0x00020406, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IDispatch*: TGUID = (D1: 0x00020400, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IEnumVariant*: TGUID = (D1: 0x00020404, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_ITypeComp*: TGUID = (D1: 0x00020403, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_ITypeInfo*: TGUID = (D1: 0x00020401, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_ITypeLib*: TGUID = (D1: 0x00020402, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IErrorInfo*: TGUID = (D1: 0x1CF2B120, D2: 0x0000547D, D3: 0x0000101B, D4: [
|
||||
0x0000008E, 0x00000065, 0x00000008, 0x00000000, 0x0000002B, 0x0000002B,
|
||||
0x000000D1, 0x00000019])
|
||||
IID_ICreateErrorInfo*: TGUID = (D1: 0x22F03340, D2: 0x0000547D,
|
||||
D3: 0x0000101B, D4: [0x0000008E, 0x00000065, 0x00000008, 0x00000000,
|
||||
0x0000002B, 0x0000002B, 0x000000D1, 0x00000019])
|
||||
IID_ISupportErrorInfo*: TGUID = (D1: 0xDF0B3D60, D2: 0x0000548F,
|
||||
D3: 0x0000101B, D4: [0x0000008E, 0x00000065, 0x00000008, 0x00000000,
|
||||
0x0000002B, 0x0000002B, 0x000000D1, 0x00000019])
|
||||
IID_IOleAdviseHolder*: TGUID = (D1: 0x00000111, D2: 0x00000000,
|
||||
D3: 0x00000000, D4: [0x000000C0, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000046])
|
||||
IID_IOleCache*: TGUID = (D1: 0x0000011E, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IOleCache2*: TGUID = (D1: 0x00000128, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IOleCacheControl*: TGUID = (D1: 0x00000129, D2: 0x00000000,
|
||||
D3: 0x00000000, D4: [0x000000C0, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000046])
|
||||
IID_IParseDisplayName*: TGUID = (D1: 0x0000011A, D2: 0x00000000,
|
||||
D3: 0x00000000, D4: [0x000000C0, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000046])
|
||||
IID_IOleContainer*: TGUID = (D1: 0x0000011B, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IOleClientSite*: TGUID = (D1: 0x00000118, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IOleObject*: TGUID = (D1: 0x00000112, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IOleWindow*: TGUID = (D1: 0x00000114, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IOleLink*: TGUID = (D1: 0x0000011D, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IOleItemContainer*: TGUID = (D1: 0x0000011C, D2: 0x00000000,
|
||||
D3: 0x00000000, D4: [0x000000C0, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000046])
|
||||
IID_IOleInPlaceUIWindow*: TGUID = (D1: 0x00000115, D2: 0x00000000,
|
||||
D3: 0x00000000, D4: [0x000000C0, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000046])
|
||||
IID_IOleInPlaceActiveObject*: TGUID = (D1: 0x00000117, D2: 0x00000000,
|
||||
D3: 0x00000000, D4: [0x000000C0, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000046])
|
||||
IID_IOleInPlaceFrame*: TGUID = (D1: 0x00000116, D2: 0x00000000,
|
||||
D3: 0x00000000, D4: [0x000000C0, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000046])
|
||||
IID_IOleInPlaceObject*: TGUID = (D1: 0x00000113, D2: 0x00000000,
|
||||
D3: 0x00000000, D4: [0x000000C0, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000046])
|
||||
IID_IOleInPlaceSite*: TGUID = (D1: 0x00000119, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IViewObject*: TGUID = (D1: 0x0000010D, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IViewObject2*: TGUID = (D1: 0x00000127, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IDropSource*: TGUID = (D1: 0x00000121, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IDropTarget*: TGUID = (D1: 0x00000122, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
IID_IEnumOleVerb*: TGUID = (D1: 0x00000104, D2: 0x00000000, D3: 0x00000000, D4: [
|
||||
0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000046])
|
||||
860
lib/windows/shellapi.nim
Executable file
860
lib/windows/shellapi.nim
Executable file
|
|
@ -0,0 +1,860 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
# leave out unused functions so the unit can be used on win2000 as well
|
||||
|
||||
#+-------------------------------------------------------------------------
|
||||
#
|
||||
# Microsoft Windows
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
#
|
||||
# File: shellapi.h
|
||||
#
|
||||
# Header translation by Marco van de Voort for Free Pascal Platform
|
||||
# SDK dl'ed January 2002
|
||||
#
|
||||
#--------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# shellapi.h - SHELL.DLL functions, types, and definitions
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
import
|
||||
Windows
|
||||
|
||||
type
|
||||
HDROP* = THandle
|
||||
UINT_PTR* = ptr UINT
|
||||
DWORD_PTR* = ptr DWORD
|
||||
pHICON* = ptr HICON
|
||||
pBool* = ptr BOOL
|
||||
STARTUPINFOW* = record # a guess. Omission should get fixed in Windows.
|
||||
cb*: DWORD
|
||||
lpReserved*: LPTSTR
|
||||
lpDesktop*: LPTSTR
|
||||
lpTitle*: LPTSTR
|
||||
dwX*: DWORD
|
||||
dwY*: DWORD
|
||||
dwXSize*: DWORD
|
||||
dwYSize*: DWORD
|
||||
dwXCountChars*: DWORD
|
||||
dwYCountChars*: DWORD
|
||||
dwFillAttribute*: DWORD
|
||||
dwFlags*: DWORD
|
||||
wShowWindow*: int16
|
||||
cbReserved2*: int16
|
||||
lpReserved2*: LPBYTE
|
||||
hStdInput*: HANDLE
|
||||
hStdOutput*: HANDLE
|
||||
hStdError*: HANDLE
|
||||
|
||||
LPSTARTUPINFOW* = ptr STARTUPINFOW
|
||||
TSTARTUPINFOW* = STARTUPINFOW
|
||||
PSTARTUPINFOW* = ptr STARTUPINFOW #unicode
|
||||
|
||||
proc DragQueryFileA*(arg1: HDROP, arg2: UINT, arg3: LPSTR, arg4: UINT): UINT{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "DragQueryFileA".}
|
||||
proc DragQueryFileW*(arg1: HDROP, arg2: UINT, arg3: LPWSTR, arg4: UINT): UINT{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "DragQueryFileW".}
|
||||
proc DragQueryFile*(arg1: HDROP, arg2: UINT, arg3: LPSTR, arg4: UINT): UINT{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "DragQueryFileA".}
|
||||
proc DragQueryFile*(arg1: HDROP, arg2: UINT, arg3: LPWSTR, arg4: UINT): UINT{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "DragQueryFileW".}
|
||||
proc DragQueryPoint*(arg1: HDROP, arg2: LPPOINT): BOOL{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "DragQueryPoint".}
|
||||
proc DragFinish*(arg1: HDROP){.stdcall, dynlib: "shell32.dll",
|
||||
importc: "DragFinish".}
|
||||
proc DragAcceptFiles*(hwnd: HWND, arg2: BOOL){.stdcall, dynlib: "shell32.dll",
|
||||
importc: "DragAcceptFiles".}
|
||||
proc ShellExecuteA*(HWND: hwnd, lpOperation: LPCSTR, lpFile: LPCSTR,
|
||||
lpParameters: LPCSTR, lpDirectory: LPCSTR, nShowCmd: int32): HInst{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "ShellExecuteA".}
|
||||
proc ShellExecuteW*(hwnd: HWND, lpOperation: LPCWSTR, lpFile: LPCWSTR,
|
||||
lpParameters: LPCWSTR, lpDirectory: LPCWSTR, nShowCmd: int32): HInst{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "ShellExecuteW".}
|
||||
proc ShellExecute*(HWND: hwnd, lpOperation: LPCSTR, lpFile: LPCSTR,
|
||||
lpParameters: LPCSTR, lpDirectory: LPCSTR, nShowCmd: int32): HInst{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "ShellExecuteA".}
|
||||
proc ShellExecute*(hwnd: HWND, lpOperation: LPCWSTR, lpFile: LPCWSTR,
|
||||
lpParameters: LPCWSTR, lpDirectory: LPCWSTR, nShowCmd: int32): HInst{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "ShellExecuteW".}
|
||||
proc FindExecutableA*(lpFile: LPCSTR, lpDirectory: LPCSTR, lpResult: LPSTR): HInst{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "FindExecutableA".}
|
||||
proc FindExecutableW*(lpFile: LPCWSTR, lpDirectory: LPCWSTR, lpResult: LPWSTR): HInst{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "FindExecutableW".}
|
||||
proc FindExecutable*(lpFile: LPCSTR, lpDirectory: LPCSTR, lpResult: LPSTR): HInst{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "FindExecutableA".}
|
||||
proc FindExecutable*(lpFile: LPCWSTR, lpDirectory: LPCWSTR, lpResult: LPWSTR): HInst{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "FindExecutableW".}
|
||||
proc CommandLineToArgvW*(lpCmdLine: LPCWSTR, pNumArgs: ptr int32): pLPWSTR{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "CommandLineToArgvW".}
|
||||
proc ShellAboutA*(HWND: hWnd, szApp: LPCSTR, szOtherStuff: LPCSTR, HICON: hIcon): int32{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "ShellAboutA".}
|
||||
proc ShellAboutW*(HWND: hWnd, szApp: LPCWSTR, szOtherStuff: LPCWSTR,
|
||||
HICON: hIcon): int32{.stdcall, dynlib: "shell32.dll",
|
||||
importc: "ShellAboutW".}
|
||||
proc ShellAbout*(HWND: hWnd, szApp: LPCSTR, szOtherStuff: LPCSTR, HICON: hIcon): int32{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "ShellAboutA".}
|
||||
proc ShellAbout*(HWND: hWnd, szApp: LPCWSTR, szOtherStuff: LPCWSTR, HICON: hIcon): int32{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "ShellAboutW".}
|
||||
proc DuplicateIcon*(hinst: HINST, HICON: hIcon): HIcon{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "DuplicateIcon".}
|
||||
proc ExtractAssociatedIconA*(hInst: HINST, lpIconPath: LPSTR, lpiIcon: LPWORD): HICON{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "ExtractAssociatedIconA".}
|
||||
proc ExtractAssociatedIconW*(hInst: HINST, lpIconPath: LPWSTR, lpiIcon: LPWORD): HICON{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "ExtractAssociatedIconW".}
|
||||
proc ExtractAssociatedIcon*(hInst: HINST, lpIconPath: LPSTR, lpiIcon: LPWORD): HICON{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "ExtractAssociatedIconA".}
|
||||
proc ExtractAssociatedIcon*(hInst: HINST, lpIconPath: LPWSTR, lpiIcon: LPWORD): HICON{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "ExtractAssociatedIconW".}
|
||||
proc ExtractIconA*(hInst: HINST, lpszExeFileName: LPCSTR, nIconIndex: UINT): HICON{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "ExtractIconA".}
|
||||
proc ExtractIconW*(hInst: HINST, lpszExeFileName: LPCWSTR, nIconIndex: UINT): HICON{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "ExtractIconW".}
|
||||
proc ExtractIcon*(hInst: HINST, lpszExeFileName: LPCSTR, nIconIndex: UINT): HICON{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "ExtractIconA".}
|
||||
proc ExtractIcon*(hInst: HINST, lpszExeFileName: LPCWSTR, nIconIndex: UINT): HICON{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "ExtractIconW".}
|
||||
# if(WINVER >= 0x0400)
|
||||
type # init with sizeof(DRAGINFO)
|
||||
DRAGINFOA* = record
|
||||
uSize*: UINT
|
||||
pt*: POINT
|
||||
fNC*: BOOL
|
||||
lpFileList*: LPSTR
|
||||
grfKeyState*: DWORD
|
||||
|
||||
TDRAGINFOA* = DRAGINFOA
|
||||
LPDRAGINFOA* = ptr DRAGINFOA # init with sizeof(DRAGINFO)
|
||||
DRAGINFOW* = record
|
||||
uSize*: UINT
|
||||
pt*: POINT
|
||||
fNC*: BOOL
|
||||
lpFileList*: LPWSTR
|
||||
grfKeyState*: DWORD
|
||||
|
||||
TDRAGINFOW* = DRAGINFOW
|
||||
LPDRAGINFOW* = ptr DRAGINFOW
|
||||
|
||||
when defined(UNICODE):
|
||||
type
|
||||
DRAGINFO* = DRAGINFOW
|
||||
TDRAGINFO* = DRAGINFOW
|
||||
LPDRAGINFO* = LPDRAGINFOW
|
||||
else:
|
||||
type
|
||||
DRAGINFO* = DRAGINFOA
|
||||
TDRAGINFO* = DRAGINFOW
|
||||
LPDRAGINFO* = LPDRAGINFOA
|
||||
const
|
||||
ABM_NEW* = 0x00000000
|
||||
ABM_REMOVE* = 0x00000001
|
||||
ABM_QUERYPOS* = 0x00000002
|
||||
ABM_SETPOS* = 0x00000003
|
||||
ABM_GETSTATE* = 0x00000004
|
||||
ABM_GETTASKBARPOS* = 0x00000005
|
||||
ABM_ACTIVATE* = 0x00000006 # lParam == TRUE/FALSE means activate/deactivate
|
||||
ABM_GETAUTOHIDEBAR* = 0x00000007
|
||||
ABM_SETAUTOHIDEBAR* = 0x00000008 # this can fail at any time. MUST check the result
|
||||
# lParam = TRUE/FALSE Set/Unset
|
||||
# uEdge = what edge
|
||||
ABM_WINDOWPOSCHANGED* = 0x00000009
|
||||
ABM_SETSTATE* = 0x0000000A
|
||||
ABN_STATECHANGE* = 0x00000000 # these are put in the wparam of callback messages
|
||||
ABN_POSCHANGED* = 0x00000001
|
||||
ABN_FULLSCREENAPP* = 0x00000002
|
||||
ABN_WINDOWARRANGE* = 0x00000003 # lParam == TRUE means hide
|
||||
# flags for get state
|
||||
ABS_AUTOHIDE* = 0x00000001
|
||||
ABS_ALWAYSONTOP* = 0x00000002
|
||||
ABE_LEFT* = 0
|
||||
ABE_TOP* = 1
|
||||
ABE_RIGHT* = 2
|
||||
ABE_BOTTOM* = 3
|
||||
|
||||
type
|
||||
AppBarData* = record
|
||||
cbSize*: DWORD
|
||||
hWnd*: HWND
|
||||
uCallbackMessage*: UINT
|
||||
uEdge*: UINT
|
||||
rc*: RECT
|
||||
lParam*: LPARAM # message specific
|
||||
|
||||
TAPPBARDATA* = AppBarData
|
||||
PAPPBARDATA* = ptr AppBarData
|
||||
|
||||
proc SHAppBarMessage*(dwMessage: DWORD, pData: APPBARDATA): UINT_PTR{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHAppBarMessage".}
|
||||
#
|
||||
# EndAppBar
|
||||
#
|
||||
proc DoEnvironmentSubstA*(szString: LPSTR, cchString: UINT): DWORD{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "DoEnvironmentSubstA".}
|
||||
proc DoEnvironmentSubstW*(szString: LPWSTR, cchString: UINT): DWORD{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "DoEnvironmentSubstW".}
|
||||
proc DoEnvironmentSubst*(szString: LPSTR, cchString: UINT): DWORD{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "DoEnvironmentSubstA".}
|
||||
proc DoEnvironmentSubst*(szString: LPWSTR, cchString: UINT): DWORD{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "DoEnvironmentSubstW".}
|
||||
#Macro
|
||||
proc EIRESID*(x: int32): int32
|
||||
proc ExtractIconExA*(lpszFile: LPCSTR, nIconIndex: int32, phiconLarge: pHICON,
|
||||
phiconSmall: pHIcon, nIcons: UINT): UINT{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "ExtractIconExA".}
|
||||
proc ExtractIconExW*(lpszFile: LPCWSTR, nIconIndex: int32, phiconLarge: pHICON,
|
||||
phiconSmall: pHIcon, nIcons: UINT): UINT{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "ExtractIconExW".}
|
||||
proc ExtractIconExA*(lpszFile: LPCSTR, nIconIndex: int32,
|
||||
phiconLarge: var HICON, phiconSmall: var HIcon,
|
||||
nIcons: UINT): UINT{.stdcall, dynlib: "shell32.dll",
|
||||
importc: "ExtractIconExA".}
|
||||
proc ExtractIconExW*(lpszFile: LPCWSTR, nIconIndex: int32,
|
||||
phiconLarge: var HICON, phiconSmall: var HIcon,
|
||||
nIcons: UINT): UINT{.stdcall, dynlib: "shell32.dll",
|
||||
importc: "ExtractIconExW".}
|
||||
proc ExtractIconEx*(lpszFile: LPCSTR, nIconIndex: int32, phiconLarge: pHICON,
|
||||
phiconSmall: pHIcon, nIcons: UINT): UINT{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "ExtractIconExA".}
|
||||
proc ExtractIconEx*(lpszFile: LPCWSTR, nIconIndex: int32, phiconLarge: pHICON,
|
||||
phiconSmall: pHIcon, nIcons: UINT): UINT{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "ExtractIconExW".}
|
||||
proc ExtractIconEx*(lpszFile: LPCSTR, nIconIndex: int32, phiconLarge: var HICON,
|
||||
phiconSmall: var HIcon, nIcons: UINT): UINT{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "ExtractIconExA".}
|
||||
proc ExtractIconEx*(lpszFile: LPCWSTR, nIconIndex: int32,
|
||||
phiconLarge: var HICON, phiconSmall: var HIcon, nIcons: UINT): UINT{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "ExtractIconExW".}
|
||||
#
|
||||
# Shell File Operations
|
||||
#
|
||||
#ifndef FO_MOVE //these need to be kept in sync with the ones in shlobj.h}
|
||||
const
|
||||
FO_MOVE* = 0x00000001
|
||||
FO_COPY* = 0x00000002
|
||||
FO_DELETE* = 0x00000003
|
||||
FO_RENAME* = 0x00000004
|
||||
FOF_MULTIDESTFILES* = 0x00000001
|
||||
FOF_CONFIRMMOUSE* = 0x00000002
|
||||
FOF_SILENT* = 0x00000004 # don't create progress/report
|
||||
FOF_RENAMEONCOLLISION* = 0x00000008
|
||||
FOF_NOCONFIRMATION* = 0x00000010 # Don't prompt the user.
|
||||
FOF_WANTMAPPINGHANDLE* = 0x00000020 # Fill in SHFILEOPSTRUCT.hNameMappings
|
||||
FOF_ALLOWUNDO* = 0x00000040 # Must be freed using SHFreeNameMappings
|
||||
FOF_FILESONLY* = 0x00000080 # on *.*, do only files
|
||||
FOF_SIMPLEPROGRESS* = 0x00000100 # means don't show names of files
|
||||
FOF_NOCONFIRMMKDIR* = 0x00000200 # don't confirm making any needed dirs
|
||||
FOF_NOERRORUI* = 0x00000400 # don't put up error UI
|
||||
FOF_NOCOPYSECURITYATTRIBS* = 0x00000800 # dont copy NT file Security Attributes
|
||||
FOF_NORECURSION* = 0x00001000 # don't recurse into directories.
|
||||
#if (_WIN32_IE >= 0x0500)
|
||||
FOF_NO_CONNECTED_ELEMENTS* = 0x00002000 # don't operate on connected elements.
|
||||
FOF_WANTNUKEWARNING* = 0x00004000 # during delete operation, warn if nuking instead of recycling (partially overrides FOF_NOCONFIRMATION)
|
||||
#endif
|
||||
#if (_WIN32_WINNT >= 0x0501)
|
||||
FOF_NORECURSEREPARSE* = 0x00008000 # treat reparse points as objects, not containers
|
||||
#endif
|
||||
|
||||
type
|
||||
FILEOP_FLAGS* = int16
|
||||
|
||||
const
|
||||
PO_DELETE* = 0x00000013 # printer is being deleted
|
||||
PO_RENAME* = 0x00000014 # printer is being renamed
|
||||
PO_PORTCHANGE* = 0x00000020 # port this printer connected to is being changed
|
||||
# if this id is set, the strings received by
|
||||
# the copyhook are a doubly-null terminated
|
||||
# list of strings. The first is the printer
|
||||
# name and the second is the printer port.
|
||||
PO_REN_PORT* = 0x00000034 # PO_RENAME and PO_PORTCHANGE at same time.
|
||||
# no POF_ flags currently defined
|
||||
|
||||
type
|
||||
PRINTEROP_FLAGS* = int16 #endif}
|
||||
# FO_MOVE
|
||||
# implicit parameters are:
|
||||
# if pFrom or pTo are unqualified names the current directories are
|
||||
# taken from the global current drive/directory settings managed
|
||||
# by Get/SetCurrentDrive/Directory
|
||||
#
|
||||
# the global confirmation settings
|
||||
# only used if FOF_SIMPLEPROGRESS
|
||||
|
||||
type
|
||||
SHFILEOPSTRUCTA* = record
|
||||
hwnd*: HWND
|
||||
wFunc*: UINT
|
||||
pFrom*: LPCSTR
|
||||
pTo*: LPCSTR
|
||||
fFlags*: FILEOP_FLAGS
|
||||
fAnyOperationsAborted*: BOOL
|
||||
hNameMappings*: LPVOID
|
||||
lpszProgressTitle*: LPCSTR # only used if FOF_SIMPLEPROGRESS
|
||||
|
||||
TSHFILEOPSTRUCTA* = SHFILEOPSTRUCTA
|
||||
LPSHFILEOPSTRUCTA* = ptr SHFILEOPSTRUCTA
|
||||
SHFILEOPSTRUCTW* = record
|
||||
hwnd*: HWND
|
||||
wFunc*: UINT
|
||||
pFrom*: LPCWSTR
|
||||
pTo*: LPCWSTR
|
||||
fFlags*: FILEOP_FLAGS
|
||||
fAnyOperationsAborted*: BOOL
|
||||
hNameMappings*: LPVOID
|
||||
lpszProgressTitle*: LPCWSTR
|
||||
|
||||
TSHFILEOPSTRUCTW* = SHFILEOPSTRUCTW
|
||||
LPSHFILEOPSTRUCTW* = ptr SHFILEOPSTRUCTW
|
||||
|
||||
when defined(UNICODE):
|
||||
type
|
||||
SHFILEOPSTRUCT* = SHFILEOPSTRUCTW
|
||||
TSHFILEOPSTRUCT* = SHFILEOPSTRUCTW
|
||||
LPSHFILEOPSTRUCT* = LPSHFILEOPSTRUCTW
|
||||
else:
|
||||
type
|
||||
SHFILEOPSTRUCT* = SHFILEOPSTRUCTA
|
||||
TSHFILEOPSTRUCT* = SHFILEOPSTRUCTA
|
||||
LPSHFILEOPSTRUCT* = LPSHFILEOPSTRUCTA
|
||||
proc SHFileOperationA*(lpFileOp: LPSHFILEOPSTRUCTA): int32{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHFileOperationA".}
|
||||
proc SHFileOperationW*(lpFileOp: LPSHFILEOPSTRUCTW): int32{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHFileOperationW".}
|
||||
proc SHFileOperation*(lpFileOp: LPSHFILEOPSTRUCTA): int32{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHFileOperationA".}
|
||||
proc SHFileOperation*(lpFileOp: LPSHFILEOPSTRUCTW): int32{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHFileOperationW".}
|
||||
proc SHFreeNameMappings*(hNameMappings: THandle){.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHFreeNameMappings".}
|
||||
type
|
||||
SHNAMEMAPPINGA* = record
|
||||
pszOldPath*: LPSTR
|
||||
pszNewPath*: LPSTR
|
||||
cchOldPath*: int32
|
||||
cchNewPath*: int32
|
||||
|
||||
TSHNAMEMAPPINGA* = SHNAMEMAPPINGA
|
||||
LPSHNAMEMAPPINGA* = ptr SHNAMEMAPPINGA
|
||||
SHNAMEMAPPINGW* = record
|
||||
pszOldPath*: LPWSTR
|
||||
pszNewPath*: LPWSTR
|
||||
cchOldPath*: int32
|
||||
cchNewPath*: int32
|
||||
|
||||
TSHNAMEMAPPINGW* = SHNAMEMAPPINGW
|
||||
LPSHNAMEMAPPINGW* = ptr SHNAMEMAPPINGW
|
||||
|
||||
when not(defined(UNICODE)):
|
||||
type
|
||||
SHNAMEMAPPING* = SHNAMEMAPPINGW
|
||||
TSHNAMEMAPPING* = SHNAMEMAPPINGW
|
||||
LPSHNAMEMAPPING* = LPSHNAMEMAPPINGW
|
||||
else:
|
||||
type
|
||||
SHNAMEMAPPING* = SHNAMEMAPPINGA
|
||||
TSHNAMEMAPPING* = SHNAMEMAPPINGA
|
||||
LPSHNAMEMAPPING* = LPSHNAMEMAPPINGA
|
||||
#
|
||||
# End Shell File Operations
|
||||
#
|
||||
#
|
||||
# Begin ShellExecuteEx and family
|
||||
#
|
||||
# ShellExecute() and ShellExecuteEx() error codes
|
||||
# regular WinExec() codes
|
||||
|
||||
const
|
||||
SE_ERR_FNF* = 2 # file not found
|
||||
SE_ERR_PNF* = 3 # path not found
|
||||
SE_ERR_ACCESSDENIED* = 5 # access denied
|
||||
SE_ERR_OOM* = 8 # out of memory
|
||||
SE_ERR_DLLNOTFOUND* = 32 # endif WINVER >= 0x0400
|
||||
# error values for ShellExecute() beyond the regular WinExec() codes
|
||||
SE_ERR_SHARE* = 26
|
||||
SE_ERR_ASSOCINCOMPLETE* = 27
|
||||
SE_ERR_DDETIMEOUT* = 28
|
||||
SE_ERR_DDEFAIL* = 29
|
||||
SE_ERR_DDEBUSY* = 30
|
||||
SE_ERR_NOASSOC* = 31 #if(WINVER >= 0x0400)}
|
||||
# Note CLASSKEY overrides CLASSNAME
|
||||
SEE_MASK_CLASSNAME* = 0x00000001
|
||||
SEE_MASK_CLASSKEY* = 0x00000003 # Note INVOKEIDLIST overrides IDLIST
|
||||
SEE_MASK_IDLIST* = 0x00000004
|
||||
SEE_MASK_INVOKEIDLIST* = 0x0000000C
|
||||
SEE_MASK_ICON* = 0x00000010
|
||||
SEE_MASK_HOTKEY* = 0x00000020
|
||||
SEE_MASK_NOCLOSEPROCESS* = 0x00000040
|
||||
SEE_MASK_CONNECTNETDRV* = 0x00000080
|
||||
SEE_MASK_FLAG_DDEWAIT* = 0x00000100
|
||||
SEE_MASK_DOENVSUBST* = 0x00000200
|
||||
SEE_MASK_FLAG_NO_UI* = 0x00000400
|
||||
SEE_MASK_UNICODE* = 0x00004000
|
||||
SEE_MASK_NO_CONSOLE* = 0x00008000
|
||||
SEE_MASK_ASYNCOK* = 0x00100000
|
||||
SEE_MASK_HMONITOR* = 0x00200000 #if (_WIN32_IE >= 0x0500)
|
||||
SEE_MASK_NOQUERYCLASSSTORE* = 0x01000000
|
||||
SEE_MASK_WAITFORINPUTIDLE* = 0x02000000 #endif (_WIN32_IE >= 0x500)
|
||||
#if (_WIN32_IE >= 0x0560)
|
||||
SEE_MASK_FLAG_LOG_USAGE* = 0x04000000 #endif
|
||||
# (_WIN32_IE >= 0x560)
|
||||
|
||||
type
|
||||
SHELLEXECUTEINFOA* = record
|
||||
cbSize*: DWORD
|
||||
fMask*: ULONG
|
||||
hwnd*: HWND
|
||||
lpVerb*: LPCSTR
|
||||
lpFile*: LPCSTR
|
||||
lpParameters*: LPCSTR
|
||||
lpDirectory*: LPCSTR
|
||||
nShow*: int32
|
||||
hInstApp*: HINST
|
||||
lpIDList*: LPVOID
|
||||
lpClass*: LPCSTR
|
||||
hkeyClass*: HKEY
|
||||
dwHotKey*: DWORD
|
||||
hMonitor*: HANDLE # also: hIcon
|
||||
hProcess*: HANDLE
|
||||
|
||||
TSHELLEXECUTEINFOA* = SHELLEXECUTEINFOA
|
||||
LPSHELLEXECUTEINFOA* = ptr SHELLEXECUTEINFOA
|
||||
SHELLEXECUTEINFOW* = record
|
||||
cbSize*: DWORD
|
||||
fMask*: ULONG
|
||||
hwnd*: HWND
|
||||
lpVerb*: lpcwstr
|
||||
lpFile*: lpcwstr
|
||||
lpParameters*: lpcwstr
|
||||
lpDirectory*: lpcwstr
|
||||
nShow*: int32
|
||||
hInstApp*: HINST
|
||||
lpIDList*: LPVOID
|
||||
lpClass*: LPCWSTR
|
||||
hkeyClass*: HKEY
|
||||
dwHotKey*: DWORD
|
||||
hMonitor*: HANDLE # also: hIcon
|
||||
hProcess*: HANDLE
|
||||
|
||||
TSHELLEXECUTEINFOW* = SHELLEXECUTEINFOW
|
||||
LPSHELLEXECUTEINFOW* = ptr SHELLEXECUTEINFOW
|
||||
|
||||
when defined(UNICODE):
|
||||
type
|
||||
SHELLEXECUTEINFO* = SHELLEXECUTEINFOW
|
||||
TSHELLEXECUTEINFO* = SHELLEXECUTEINFOW
|
||||
LPSHELLEXECUTEINFO* = LPSHELLEXECUTEINFOW
|
||||
else:
|
||||
type
|
||||
SHELLEXECUTEINFO* = SHELLEXECUTEINFOA
|
||||
TSHELLEXECUTEINFO* = SHELLEXECUTEINFOA
|
||||
LPSHELLEXECUTEINFO* = LPSHELLEXECUTEINFOA
|
||||
proc ShellExecuteExA*(lpExecInfo: LPSHELLEXECUTEINFOA): Bool{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "ShellExecuteExA".}
|
||||
proc ShellExecuteExW*(lpExecInfo: LPSHELLEXECUTEINFOW): Bool{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "ShellExecuteExW".}
|
||||
proc ShellExecuteEx*(lpExecInfo: LPSHELLEXECUTEINFOA): Bool{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "ShellExecuteExA".}
|
||||
proc ShellExecuteEx*(lpExecInfo: LPSHELLEXECUTEINFOW): Bool{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "ShellExecuteExW".}
|
||||
proc WinExecErrorA*(HWND: hwnd, error: int32, lpstrFileName: LPCSTR,
|
||||
lpstrTitle: LPCSTR){.stdcall, dynlib: "shell32.dll",
|
||||
importc: "WinExecErrorA".}
|
||||
proc WinExecErrorW*(HWND: hwnd, error: int32, lpstrFileName: LPCWSTR,
|
||||
lpstrTitle: LPCWSTR){.stdcall, dynlib: "shell32.dll",
|
||||
importc: "WinExecErrorW".}
|
||||
proc WinExecError*(HWND: hwnd, error: int32, lpstrFileName: LPCSTR,
|
||||
lpstrTitle: LPCSTR){.stdcall, dynlib: "shell32.dll",
|
||||
importc: "WinExecErrorA".}
|
||||
proc WinExecError*(HWND: hwnd, error: int32, lpstrFileName: LPCWSTR,
|
||||
lpstrTitle: LPCWSTR){.stdcall, dynlib: "shell32.dll",
|
||||
importc: "WinExecErrorW".}
|
||||
type
|
||||
SHCREATEPROCESSINFOW* = record
|
||||
cbSize*: DWORD
|
||||
fMask*: ULONG
|
||||
hwnd*: HWND
|
||||
pszFile*: LPCWSTR
|
||||
pszParameters*: LPCWSTR
|
||||
pszCurrentDirectory*: LPCWSTR
|
||||
hUserToken*: HANDLE
|
||||
lpProcessAttributes*: LPSECURITY_ATTRIBUTES
|
||||
lpThreadAttributes*: LPSECURITY_ATTRIBUTES
|
||||
bInheritHandles*: BOOL
|
||||
dwCreationFlags*: DWORD
|
||||
lpStartupInfo*: LPSTARTUPINFOW
|
||||
lpProcessInformation*: LPPROCESS_INFORMATION
|
||||
|
||||
TSHCREATEPROCESSINFOW* = SHCREATEPROCESSINFOW
|
||||
PSHCREATEPROCESSINFOW* = ptr SHCREATEPROCESSINFOW
|
||||
|
||||
proc SHCreateProcessAsUserW*(pscpi: PSHCREATEPROCESSINFOW): Bool{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHCreateProcessAsUserW".}
|
||||
#
|
||||
# End ShellExecuteEx and family }
|
||||
#
|
||||
#
|
||||
# RecycleBin
|
||||
#
|
||||
# struct for query recycle bin info
|
||||
type
|
||||
SHQUERYRBINFO* = record
|
||||
cbSize*: DWORD
|
||||
i64Size*: int64
|
||||
i64NumItems*: int64
|
||||
|
||||
TSHQUERYRBINFO* = SHQUERYRBINFO
|
||||
LPSHQUERYRBINFO* = ptr SHQUERYRBINFO # flags for SHEmptyRecycleBin
|
||||
|
||||
const
|
||||
SHERB_NOCONFIRMATION* = 0x00000001
|
||||
SHERB_NOPROGRESSUI* = 0x00000002
|
||||
SHERB_NOSOUND* = 0x00000004
|
||||
|
||||
proc SHQueryRecycleBinA*(pszRootPath: LPCSTR, pSHQueryRBInfo: LPSHQUERYRBINFO): HRESULT{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "SHQueryRecycleBinA".}
|
||||
proc SHQueryRecycleBinW*(pszRootPath: LPCWSTR, pSHQueryRBInfo: LPSHQUERYRBINFO): HRESULT{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "SHQueryRecycleBinW".}
|
||||
proc SHQueryRecycleBin*(pszRootPath: LPCSTR, pSHQueryRBInfo: LPSHQUERYRBINFO): HRESULT{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "SHQueryRecycleBinA".}
|
||||
proc SHQueryRecycleBin*(pszRootPath: LPCWSTR, pSHQueryRBInfo: LPSHQUERYRBINFO): HRESULT{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "SHQueryRecycleBinW".}
|
||||
proc SHEmptyRecycleBinA*(hwnd: HWND, pszRootPath: LPCSTR, dwFlags: DWORD): HRESULT{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "SHEmptyRecycleBinA".}
|
||||
proc SHEmptyRecycleBinW*(hwnd: HWND, pszRootPath: LPCWSTR, dwFlags: DWORD): HRESULT{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "SHEmptyRecycleBinW".}
|
||||
proc SHEmptyRecycleBin*(hwnd: HWND, pszRootPath: LPCSTR, dwFlags: DWORD): HRESULT{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "SHEmptyRecycleBinA".}
|
||||
proc SHEmptyRecycleBin*(hwnd: HWND, pszRootPath: LPCWSTR, dwFlags: DWORD): HRESULT{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "SHEmptyRecycleBinW".}
|
||||
#
|
||||
# end of RecycleBin
|
||||
#
|
||||
#
|
||||
# Tray notification definitions
|
||||
#
|
||||
type
|
||||
NOTIFYICONDATAA* = record
|
||||
cbSize*: DWORD
|
||||
hWnd*: HWND
|
||||
uID*: UINT
|
||||
uFlags*: UINT
|
||||
uCallbackMessage*: UINT
|
||||
hIcon*: HICON
|
||||
szTip*: array[0..127, CHAR]
|
||||
dwState*: DWORD
|
||||
dwStateMask*: DWORD
|
||||
szInfo*: array[0..255, CHAR]
|
||||
uTimeout*: UINT # also: uVersion
|
||||
szInfoTitle*: array[0..63, CHAR]
|
||||
dwInfoFlags*: DWORD
|
||||
guidItem*: TGUID
|
||||
|
||||
TNOTIFYICONDATAA* = NOTIFYICONDATAA
|
||||
PNOTIFYICONDATAA* = ptr NOTIFYICONDATAA
|
||||
NOTIFYICONDATAW* = record
|
||||
cbSize*: DWORD
|
||||
hWnd*: HWND
|
||||
uID*: UINT
|
||||
uFlags*: UINT
|
||||
uCallbackMessage*: UINT
|
||||
hIcon*: HICON
|
||||
szTip*: array[0..127, WCHAR]
|
||||
dwState*: DWORD
|
||||
dwStateMask*: DWORD
|
||||
szInfo*: array[0..255, WCHAR]
|
||||
uTimeout*: UINT # also uVersion : UINT
|
||||
szInfoTitle*: array[0..63, CHAR]
|
||||
dwInfoFlags*: DWORD
|
||||
guidItem*: TGUID
|
||||
|
||||
TNOTIFYICONDATAW* = NOTIFYICONDATAW
|
||||
PNOTIFYICONDATAW* = ptr NOTIFYICONDATAW
|
||||
|
||||
when defined(UNICODE):
|
||||
type
|
||||
NOTIFYICONDATA* = NOTIFYICONDATAW
|
||||
TNOTIFYICONDATA* = NOTIFYICONDATAW
|
||||
PNOTIFYICONDATA* = PNOTIFYICONDATAW
|
||||
else:
|
||||
type
|
||||
NOTIFYICONDATA* = NOTIFYICONDATAA
|
||||
TNOTIFYICONDATA* = NOTIFYICONDATAA
|
||||
PNOTIFYICONDATA* = PNOTIFYICONDATAA
|
||||
const
|
||||
NIN_SELECT* = WM_USER + 0
|
||||
NINF_KEY* = 0x00000001
|
||||
NIN_KEYSELECT* = NIN_SELECT or NINF_KEY
|
||||
NIN_BALLOONSHOW* = WM_USER + 2
|
||||
NIN_BALLOONHIDE* = WM_USER + 3
|
||||
NIN_BALLOONTIMEOUT* = WM_USER + 4
|
||||
NIN_BALLOONUSERCLICK* = WM_USER + 5
|
||||
NIM_ADD* = 0x00000000
|
||||
NIM_MODIFY* = 0x00000001
|
||||
NIM_DELETE* = 0x00000002
|
||||
NIM_SETFOCUS* = 0x00000003
|
||||
NIM_SETVERSION* = 0x00000004
|
||||
NOTIFYICON_VERSION* = 3
|
||||
NIF_MESSAGE* = 0x00000001
|
||||
NIF_ICON* = 0x00000002
|
||||
NIF_TIP* = 0x00000004
|
||||
NIF_STATE* = 0x00000008
|
||||
NIF_INFO* = 0x00000010
|
||||
NIF_GUID* = 0x00000020
|
||||
NIS_HIDDEN* = 0x00000001
|
||||
NIS_SHAREDICON* = 0x00000002 # says this is the source of a shared icon
|
||||
# Notify Icon Infotip flags
|
||||
NIIF_NONE* = 0x00000000 # icon flags are mutually exclusive
|
||||
# and take only the lowest 2 bits
|
||||
NIIF_INFO* = 0x00000001
|
||||
NIIF_WARNING* = 0x00000002
|
||||
NIIF_ERROR* = 0x00000003
|
||||
NIIF_ICON_MASK* = 0x0000000F
|
||||
NIIF_NOSOUND* = 0x00000010
|
||||
|
||||
proc Shell_NotifyIconA*(dwMessage: Dword, lpData: PNOTIFYICONDATAA): Bool{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "Shell_NotifyIconA".}
|
||||
proc Shell_NotifyIconW*(dwMessage: Dword, lpData: PNOTIFYICONDATAW): Bool{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "Shell_NotifyIconW".}
|
||||
proc Shell_NotifyIcon*(dwMessage: Dword, lpData: PNOTIFYICONDATAA): Bool{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "Shell_NotifyIconA".}
|
||||
proc Shell_NotifyIcon*(dwMessage: Dword, lpData: PNOTIFYICONDATAW): Bool{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "Shell_NotifyIconW".}
|
||||
#
|
||||
# The SHGetFileInfo API provides an easy way to get attributes
|
||||
# for a file given a pathname.
|
||||
#
|
||||
# PARAMETERS
|
||||
#
|
||||
# pszPath file name to get info about
|
||||
# dwFileAttributes file attribs, only used with SHGFI_USEFILEATTRIBUTES
|
||||
# psfi place to return file info
|
||||
# cbFileInfo size of structure
|
||||
# uFlags flags
|
||||
#
|
||||
# RETURN
|
||||
# TRUE if things worked
|
||||
#
|
||||
# out: icon
|
||||
# out: icon index
|
||||
# out: SFGAO_ flags
|
||||
# out: display name (or path)
|
||||
# out: type name
|
||||
type
|
||||
SHFILEINFOA* = record
|
||||
hIcon*: HICON # out: icon
|
||||
iIcon*: int32 # out: icon index
|
||||
dwAttributes*: DWORD # out: SFGAO_ flags
|
||||
szDisplayName*: array[0..(MAX_PATH) - 1, CHAR] # out: display name (or path)
|
||||
szTypeName*: array[0..79, CHAR] # out: type name
|
||||
|
||||
TSHFILEINFOA* = SHFILEINFOA
|
||||
pSHFILEINFOA* = ptr SHFILEINFOA
|
||||
SHFILEINFOW* = record
|
||||
hIcon*: HICON # out: icon
|
||||
iIcon*: int32 # out: icon index
|
||||
dwAttributes*: DWORD # out: SFGAO_ flags
|
||||
szDisplayName*: array[0..(MAX_PATH) - 1, WCHAR] # out: display name (or path)
|
||||
szTypeName*: array[0..79, WCHAR] # out: type name
|
||||
|
||||
TSHFILEINFOW* = SHFILEINFOW
|
||||
pSHFILEINFOW* = ptr SHFILEINFOW
|
||||
|
||||
when defined(UNICODE):
|
||||
type
|
||||
SHFILEINFO* = SHFILEINFOW
|
||||
TSHFILEINFO* = SHFILEINFOW
|
||||
pFILEINFO* = SHFILEINFOW
|
||||
else:
|
||||
type
|
||||
SHFILEINFO* = SHFILEINFOA
|
||||
TSHFILEINFO* = SHFILEINFOA
|
||||
pFILEINFO* = SHFILEINFOA
|
||||
# NOTE: This is also in shlwapi.h. Please keep in synch.
|
||||
|
||||
const
|
||||
SHGFI_ICON* = 0x00000100 # get Icon
|
||||
SHGFI_DISPLAYNAME* = 0x00000200 # get display name
|
||||
SHGFI_TYPENAME* = 0x00000400 # get type name
|
||||
SHGFI_ATTRIBUTES* = 0x00000800 # get attributes
|
||||
SHGFI_ICONLOCATION* = 0x00001000 # get icon location
|
||||
SHGFI_EXETYPE* = 0x00002000 # return exe type
|
||||
SHGFI_SYSICONINDEX* = 0x00004000 # get system icon index
|
||||
SHGFI_LINKOVERLAY* = 0x00008000 # put a link overlay on icon
|
||||
SHGFI_SELECTED* = 0x00010000 # show icon in selected state
|
||||
SHGFI_ATTR_SPECIFIED* = 0x00020000 # get only specified attributes
|
||||
SHGFI_LARGEICON* = 0x00000000 # get large icon
|
||||
SHGFI_SMALLICON* = 0x00000001 # get small icon
|
||||
SHGFI_OPENICON* = 0x00000002 # get open icon
|
||||
SHGFI_SHELLICONSIZE* = 0x00000004 # get shell size icon
|
||||
SHGFI_PIDL* = 0x00000008 # pszPath is a pidl
|
||||
SHGFI_USEFILEATTRIBUTES* = 0x00000010 # use passed dwFileAttribute
|
||||
SHGFI_ADDOVERLAYS* = 0x00000020 # apply the appropriate overlays
|
||||
SHGFI_OVERLAYINDEX* = 0x00000040 # Get the index of the overlay
|
||||
# in the upper 8 bits of the iIcon
|
||||
|
||||
proc SHGetFileInfoA*(pszPath: LPCSTR, dwFileAttributes: DWORD,
|
||||
psfi: pSHFILEINFOA, cbFileInfo, UFlags: UINT): DWORD{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "SHGetFileInfoA".}
|
||||
proc SHGetFileInfoW*(pszPath: LPCWSTR, dwFileAttributes: DWORD,
|
||||
psfi: pSHFILEINFOW, cbFileInfo, UFlags: UINT): DWORD{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "SHGetFileInfoW".}
|
||||
proc SHGetFileInfo*(pszPath: LPCSTR, dwFileAttributes: DWORD,
|
||||
psfi: pSHFILEINFOA, cbFileInfo, UFlags: UINT): DWORD{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "SHGetFileInfoA".}
|
||||
proc SHGetFileInfoA*(pszPath: LPCSTR, dwFileAttributes: DWORD,
|
||||
psfi: var TSHFILEINFOA, cbFileInfo, UFlags: UINT): DWORD{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "SHGetFileInfoA".}
|
||||
proc SHGetFileInfoW*(pszPath: LPCWSTR, dwFileAttributes: DWORD,
|
||||
psfi: var TSHFILEINFOW, cbFileInfo, UFlags: UINT): DWORD{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "SHGetFileInfoW".}
|
||||
proc SHGetFileInfo*(pszPath: LPCSTR, dwFileAttributes: DWORD,
|
||||
psfi: var TSHFILEINFOA, cbFileInfo, UFlags: UINT): DWORD{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "SHGetFileInfoA".}
|
||||
proc SHGetFileInfo*(pszPath: LPCWSTR, dwFileAttributes: DWORD,
|
||||
psfi: var TSHFILEINFOW, cbFileInfo, UFlags: UINT): DWORD{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "SHGetFileInfoW".}
|
||||
proc SHGetDiskFreeSpaceExA*(pszDirectoryName: LPCSTR,
|
||||
pulFreeBytesAvailableToCaller: pULARGE_INTEGER,
|
||||
pulTotalNumberOfBytes: pULARGE_INTEGER,
|
||||
pulTotalNumberOfFreeBytes: pULARGE_INTEGER): Bool{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "SHGetDiskFreeSpaceExA".}
|
||||
proc SHGetDiskFreeSpaceExW*(pszDirectoryName: LPCWSTR,
|
||||
pulFreeBytesAvailableToCaller: pULARGE_INTEGER,
|
||||
pulTotalNumberOfBytes: pULARGE_INTEGER,
|
||||
pulTotalNumberOfFreeBytes: pULARGE_INTEGER): Bool{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "SHGetDiskFreeSpaceExW".}
|
||||
proc SHGetDiskFreeSpaceEx*(pszDirectoryName: LPCSTR,
|
||||
pulFreeBytesAvailableToCaller: pULARGE_INTEGER,
|
||||
pulTotalNumberOfBytes: pULARGE_INTEGER,
|
||||
pulTotalNumberOfFreeBytes: pULARGE_INTEGER): Bool{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "SHGetDiskFreeSpaceExA".}
|
||||
proc SHGetDiskFreeSpace*(pszDirectoryName: LPCSTR,
|
||||
pulFreeBytesAvailableToCaller: pULARGE_INTEGER,
|
||||
pulTotalNumberOfBytes: pULARGE_INTEGER,
|
||||
pulTotalNumberOfFreeBytes: pULARGE_INTEGER): Bool{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "SHGetDiskFreeSpaceExA".}
|
||||
proc SHGetDiskFreeSpaceEx*(pszDirectoryName: LPCWSTR,
|
||||
pulFreeBytesAvailableToCaller: pULARGE_INTEGER,
|
||||
pulTotalNumberOfBytes: pULARGE_INTEGER,
|
||||
pulTotalNumberOfFreeBytes: pULARGE_INTEGER): Bool{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "SHGetDiskFreeSpaceExW".}
|
||||
proc SHGetDiskFreeSpace*(pszDirectoryName: LPCWSTR,
|
||||
pulFreeBytesAvailableToCaller: pULARGE_INTEGER,
|
||||
pulTotalNumberOfBytes: pULARGE_INTEGER,
|
||||
pulTotalNumberOfFreeBytes: pULARGE_INTEGER): Bool{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "SHGetDiskFreeSpaceExW".}
|
||||
proc SHGetNewLinkInfoA*(pszLinkTo: LPCSTR, pszDir: LPCSTR, pszName: LPSTR,
|
||||
pfMustCopy: pBool, uFlags: UINT): Bool{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHGetNewLinkInfoA".}
|
||||
proc SHGetNewLinkInfoW*(pszLinkTo: LPCWSTR, pszDir: LPCWSTR, pszName: LPWSTR,
|
||||
pfMustCopy: pBool, uFlags: UINT): Bool{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHGetNewLinkInfoW".}
|
||||
proc SHGetNewLinkInfo*(pszLinkTo: LPCSTR, pszDir: LPCSTR, pszName: LPSTR,
|
||||
pfMustCopy: pBool, uFlags: UINT): Bool{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHGetNewLinkInfoA".}
|
||||
proc SHGetNewLinkInfo*(pszLinkTo: LPCWSTR, pszDir: LPCWSTR, pszName: LPWSTR,
|
||||
pfMustCopy: pBool, uFlags: UINT): Bool{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHGetNewLinkInfoW".}
|
||||
const
|
||||
SHGNLI_PIDL* = 0x00000001 # pszLinkTo is a pidl
|
||||
SHGNLI_PREFIXNAME* = 0x00000002 # Make name "Shortcut to xxx"
|
||||
SHGNLI_NOUNIQUE* = 0x00000004 # don't do the unique name generation
|
||||
SHGNLI_NOLNK* = 0x00000008 # don't add ".lnk" extension
|
||||
PRINTACTION_OPEN* = 0
|
||||
PRINTACTION_PROPERTIES* = 1
|
||||
PRINTACTION_NETINSTALL* = 2
|
||||
PRINTACTION_NETINSTALLLINK* = 3
|
||||
PRINTACTION_TESTPAGE* = 4
|
||||
PRINTACTION_OPENNETPRN* = 5
|
||||
PRINTACTION_DOCUMENTDEFAULTS* = 6
|
||||
PRINTACTION_SERVERPROPERTIES* = 7
|
||||
|
||||
proc SHInvokePrinterCommandA*(HWND: hwnd, uAction: UINT, lpBuf1: LPCSTR,
|
||||
lpBuf2: LPCSTR, fModal: Bool): Bool{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHInvokePrinterCommandA".}
|
||||
proc SHInvokePrinterCommandW*(HWND: hwnd, uAction: UINT, lpBuf1: LPCWSTR,
|
||||
lpBuf2: LPCWSTR, fModal: Bool): Bool{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHInvokePrinterCommandW".}
|
||||
proc SHInvokePrinterCommand*(HWND: hwnd, uAction: UINT, lpBuf1: LPCSTR,
|
||||
lpBuf2: LPCSTR, fModal: Bool): Bool{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHInvokePrinterCommandA".}
|
||||
proc SHInvokePrinterCommand*(HWND: hwnd, uAction: UINT, lpBuf1: LPCWSTR,
|
||||
lpBuf2: LPCWSTR, fModal: Bool): Bool{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHInvokePrinterCommandW".}
|
||||
proc SHLoadNonloadedIconOverlayIdentifiers*(): HResult{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHInvokePrinterCommandW".}
|
||||
proc SHIsFileAvailableOffline*(pwszPath: LPCWSTR, pdwStatus: LPDWORD): HRESULT{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "SHIsFileAvailableOffline".}
|
||||
const
|
||||
OFFLINE_STATUS_LOCAL* = 0x00000001 # If open, it's open locally
|
||||
OFFLINE_STATUS_REMOTE* = 0x00000002 # If open, it's open remotely
|
||||
OFFLINE_STATUS_INCOMPLETE* = 0x00000004 # The local copy is currently incomplete.
|
||||
# The file will not be available offline
|
||||
# until it has been synchronized.
|
||||
# sets the specified path to use the string resource
|
||||
# as the UI instead of the file system name
|
||||
|
||||
proc SHSetLocalizedName*(pszPath: LPWSTR, pszResModule: LPCWSTR, idsRes: int32): HRESULT{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "SHSetLocalizedName".}
|
||||
proc SHEnumerateUnreadMailAccountsA*(hKeyUser: HKEY, dwIndex: DWORD,
|
||||
pszMailAddress: LPSTR,
|
||||
cchMailAddress: int32): HRESULT{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHEnumerateUnreadMailAccountsA".}
|
||||
proc SHEnumerateUnreadMailAccountsW*(hKeyUser: HKEY, dwIndex: DWORD,
|
||||
pszMailAddress: LPWSTR,
|
||||
cchMailAddress: int32): HRESULT{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHEnumerateUnreadMailAccountsW".}
|
||||
proc SHEnumerateUnreadMailAccounts*(hKeyUser: HKEY, dwIndex: DWORD,
|
||||
pszMailAddress: LPWSTR,
|
||||
cchMailAddress: int32): HRESULT{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHEnumerateUnreadMailAccountsW".}
|
||||
proc SHGetUnreadMailCountA*(hKeyUser: HKEY, pszMailAddress: LPCSTR,
|
||||
pdwCount: PDWORD, pFileTime: PFILETIME,
|
||||
pszShellExecuteCommand: LPSTR,
|
||||
cchShellExecuteCommand: int32): HRESULT{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHGetUnreadMailCountA".}
|
||||
proc SHGetUnreadMailCountW*(hKeyUser: HKEY, pszMailAddress: LPCWSTR,
|
||||
pdwCount: PDWORD, pFileTime: PFILETIME,
|
||||
pszShellExecuteCommand: LPWSTR,
|
||||
cchShellExecuteCommand: int32): HRESULT{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHGetUnreadMailCountW".}
|
||||
proc SHGetUnreadMailCount*(hKeyUser: HKEY, pszMailAddress: LPCSTR,
|
||||
pdwCount: PDWORD, pFileTime: PFILETIME,
|
||||
pszShellExecuteCommand: LPSTR,
|
||||
cchShellExecuteCommand: int32): HRESULT{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHGetUnreadMailCountA".}
|
||||
proc SHGetUnreadMailCount*(hKeyUser: HKEY, pszMailAddress: LPCWSTR,
|
||||
pdwCount: PDWORD, pFileTime: PFILETIME,
|
||||
pszShellExecuteCommand: LPWSTR,
|
||||
cchShellExecuteCommand: int32): HRESULT{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHGetUnreadMailCountW".}
|
||||
proc SHSetUnreadMailCountA*(pszMailAddress: LPCSTR, dwCount: DWORD,
|
||||
pszShellExecuteCommand: LPCSTR): HRESULT{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHSetUnreadMailCountA".}
|
||||
proc SHSetUnreadMailCountW*(pszMailAddress: LPCWSTR, dwCount: DWORD,
|
||||
pszShellExecuteCommand: LPCWSTR): HRESULT{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHSetUnreadMailCountW".}
|
||||
proc SHSetUnreadMailCount*(pszMailAddress: LPCSTR, dwCount: DWORD,
|
||||
pszShellExecuteCommand: LPCSTR): HRESULT{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHSetUnreadMailCountA".}
|
||||
proc SHSetUnreadMailCount*(pszMailAddress: LPCWSTR, dwCount: DWORD,
|
||||
pszShellExecuteCommand: LPCWSTR): HRESULT{.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHSetUnreadMailCountW".}
|
||||
proc SHGetImageList*(iImageList: int32, riid: TIID, ppvObj: ptr pointer): HRESULT{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "SHGetImageList".}
|
||||
const
|
||||
SHIL_LARGE* = 0 # normally 32x32
|
||||
SHIL_SMALL* = 1 # normally 16x16
|
||||
SHIL_EXTRALARGE* = 2
|
||||
SHIL_SYSSMALL* = 3 # like SHIL_SMALL, but tracks system small icon metric correctly
|
||||
SHIL_LAST* = SHIL_SYSSMALL
|
||||
|
||||
# implementation
|
||||
|
||||
proc EIRESID(x: int32): int32 =
|
||||
result = - int(x)
|
||||
91
lib/windows/shfolder.nim
Executable file
91
lib/windows/shfolder.nim
Executable file
|
|
@ -0,0 +1,91 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# shfolder.dll is distributed standard with IE5.5, so it should ship
|
||||
# with 2000/XP or higher but is likely to be installed on NT/95/98 or
|
||||
# ME as well. It works on all these systems.
|
||||
#
|
||||
# The info found here is also in the registry:
|
||||
# HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\
|
||||
# HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\
|
||||
#
|
||||
# Note that not all CSIDL_* constants are supported by shlfolder.dll,
|
||||
# they should be supported by the shell32.dll, though again not on all
|
||||
# systems.
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
import
|
||||
windows
|
||||
|
||||
const
|
||||
LibName* = "SHFolder.dll"
|
||||
|
||||
const
|
||||
CSIDL_PROGRAMS* = 0x00000002 # %SYSTEMDRIVE%\Program Files
|
||||
CSIDL_PERSONAL* = 0x00000005 # %USERPROFILE%\My Documents
|
||||
CSIDL_FAVORITES* = 0x00000006 # %USERPROFILE%\Favorites
|
||||
CSIDL_STARTUP* = 0x00000007 # %USERPROFILE%\Start menu\Programs\Startup
|
||||
CSIDL_RECENT* = 0x00000008 # %USERPROFILE%\Recent
|
||||
CSIDL_SENDTO* = 0x00000009 # %USERPROFILE%\Sendto
|
||||
CSIDL_STARTMENU* = 0x0000000B # %USERPROFILE%\Start menu
|
||||
CSIDL_MYMUSIC* = 0x0000000D # %USERPROFILE%\Documents\My Music
|
||||
CSIDL_MYVIDEO* = 0x0000000E # %USERPROFILE%\Documents\My Videos
|
||||
CSIDL_DESKTOPDIRECTORY* = 0x00000010 # %USERPROFILE%\Desktop
|
||||
CSIDL_NETHOOD* = 0x00000013 # %USERPROFILE%\NetHood
|
||||
CSIDL_TEMPLATES* = 0x00000015 # %USERPROFILE%\Templates
|
||||
CSIDL_COMMON_STARTMENU* = 0x00000016 # %PROFILEPATH%\All users\Start menu
|
||||
CSIDL_COMMON_PROGRAMS* = 0x00000017 # %PROFILEPATH%\All users\Start menu\Programs
|
||||
CSIDL_COMMON_STARTUP* = 0x00000018 # %PROFILEPATH%\All users\Start menu\Programs\Startup
|
||||
CSIDL_COMMON_DESKTOPDIRECTORY* = 0x00000019 # %PROFILEPATH%\All users\Desktop
|
||||
CSIDL_APPDATA* = 0x0000001A # %USERPROFILE%\Application Data (roaming)
|
||||
CSIDL_PRINTHOOD* = 0x0000001B # %USERPROFILE%\Printhood
|
||||
CSIDL_LOCAL_APPDATA* = 0x0000001C # %USERPROFILE%\Local Settings\Application Data (non roaming)
|
||||
CSIDL_COMMON_FAVORITES* = 0x0000001F # %PROFILEPATH%\All users\Favorites
|
||||
CSIDL_INTERNET_CACHE* = 0x00000020 # %USERPROFILE%\Local Settings\Temporary Internet Files
|
||||
CSIDL_COOKIES* = 0x00000021 # %USERPROFILE%\Cookies
|
||||
CSIDL_HISTORY* = 0x00000022 # %USERPROFILE%\Local settings\History
|
||||
CSIDL_COMMON_APPDATA* = 0x00000023 # %PROFILESPATH%\All Users\Application Data
|
||||
CSIDL_WINDOWS* = 0x00000024 # %SYSTEMROOT%
|
||||
CSIDL_SYSTEM* = 0x00000025 # %SYSTEMROOT%\SYSTEM32 (may be system on 95/98/ME)
|
||||
CSIDL_PROGRAM_FILES* = 0x00000026 # %SYSTEMDRIVE%\Program Files
|
||||
CSIDL_MYPICTURES* = 0x00000027 # %USERPROFILE%\My Documents\My Pictures
|
||||
CSIDL_PROFILE* = 0x00000028 # %USERPROFILE%
|
||||
CSIDL_PROGRAM_FILES_COMMON* = 0x0000002B # %SYSTEMDRIVE%\Program Files\Common
|
||||
CSIDL_COMMON_TEMPLATES* = 0x0000002D # %PROFILEPATH%\All Users\Templates
|
||||
CSIDL_COMMON_DOCUMENTS* = 0x0000002E # %PROFILEPATH%\All Users\Documents
|
||||
CSIDL_COMMON_ADMINTOOLS* = 0x0000002F # %PROFILEPATH%\All Users\Start Menu\Programs\Administrative Tools
|
||||
CSIDL_ADMINTOOLS* = 0x00000030 # %USERPROFILE%\Start Menu\Programs\Administrative Tools
|
||||
CSIDL_COMMON_MUSIC* = 0x00000035 # %PROFILEPATH%\All Users\Documents\my music
|
||||
CSIDL_COMMON_PICTURES* = 0x00000036 # %PROFILEPATH%\All Users\Documents\my pictures
|
||||
CSIDL_COMMON_VIDEO* = 0x00000037 # %PROFILEPATH%\All Users\Documents\my videos
|
||||
CSIDL_CDBURN_AREA* = 0x0000003B # %USERPROFILE%\Local Settings\Application Data\Microsoft\CD Burning
|
||||
CSIDL_PROFILES* = 0x0000003E # %PROFILEPATH%
|
||||
CSIDL_FLAG_CREATE* = 0x00008000 # (force creation of requested folder if it doesn't exist yet)
|
||||
# Original entry points
|
||||
|
||||
proc SHGetFolderPathA*(Ahwnd: HWND, Csidl: int, Token: THandle, Flags: DWord,
|
||||
Path: cstring): HRESULT{.stdcall, dynlib: LibName,
|
||||
importc: "SHGetFolderPathA".}
|
||||
proc SHGetFolderPathW*(Ahwnd: HWND, Csidl: int, Token: THandle, Flags: DWord,
|
||||
Path: cstring): HRESULT{.stdcall, dynlib: LibName,
|
||||
importc: "SHGetFolderPathW".}
|
||||
proc SHGetFolderPath*(Ahwnd: HWND, Csidl: int, Token: THandle, Flags: DWord,
|
||||
Path: cstring): HRESULT{.stdcall, dynlib: LibName,
|
||||
importc: "SHGetFolderPathA".}
|
||||
type
|
||||
PFNSHGetFolderPathA* = proc (Ahwnd: HWND, Csidl: int, Token: THandle,
|
||||
Flags: DWord, Path: cstring): HRESULT{.stdcall.}
|
||||
PFNSHGetFolderPathW* = proc (Ahwnd: HWND, Csidl: int, Token: THandle,
|
||||
Flags: DWord, Path: cstring): HRESULT{.stdcall.}
|
||||
PFNSHGetFolderPath* = PFNSHGetFolderPathA
|
||||
TSHGetFolderPathA* = PFNSHGetFolderPathA
|
||||
TSHGetFolderPathW* = PFNSHGetFolderPathW
|
||||
TSHGetFolderPath* = TSHGetFolderPathA
|
||||
|
||||
23909
lib/windows/windows.nim
Executable file
23909
lib/windows/windows.nim
Executable file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue