Initial import

This commit is contained in:
Andreas Rumpf 2008-06-22 16:14:11 +02:00
commit 405b86068e
324 changed files with 163599 additions and 0 deletions

39
lib/amd64.asm.in Executable file
View 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
View 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
View 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
View 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
View 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)))

View 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.}

View 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

View 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
View 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

File diff suppressed because it is too large Load diff

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
View 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
View 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

File diff suppressed because it is too large Load diff

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
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

46
lib/base/gtk/pangoutils.nim Executable file
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

114
lib/base/regexprs.nim Executable file
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

1143
lib/dlmalloc.h Executable file

File diff suppressed because it is too large Load diff

143
lib/dyncalls.nim Executable file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

35
lib/powerpc.asm.in Executable file
View 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

File diff suppressed because it is too large Load diff

205
lib/ptrset.nim Executable file
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

179
lib/times.nim Executable file
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

230
lib/windows/nb30.nim Executable file
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load diff