too many changes to list
This commit is contained in:
parent
916c25f9a7
commit
07d5a8085b
200 changed files with 24344 additions and 17809 deletions
|
|
@ -17,9 +17,9 @@ 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_TextFile {.importc: "FILE", nodecl, final.} = object # empty record for
|
||||
# data hiding
|
||||
C_BinaryFile {.importc: "FILE", nodecl, final.} = object
|
||||
C_TextFileStar = ptr CTextFile
|
||||
C_BinaryFileStar = ptr CBinaryFile
|
||||
|
||||
|
|
|
|||
|
|
@ -18,13 +18,13 @@ proc raiseDivByZero {.exportc: "raiseDivByZero".} =
|
|||
raise newException(EDivByZero, "divison by zero")
|
||||
|
||||
proc addInt64(a, b: int64): int64 {.compilerProc, inline.} =
|
||||
result = a + b
|
||||
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
|
||||
result = a -% b
|
||||
if (result xor a) >= int64(0) or (result xor not b) >= int64(0):
|
||||
return result
|
||||
raiseOverflow()
|
||||
|
|
@ -74,7 +74,7 @@ proc modInt64(a, b: int64): int64 {.compilerProc, inline.} =
|
|||
proc mulInt64(a, b: int64): int64 {.compilerproc.} =
|
||||
var
|
||||
resAsFloat, floatProd: float64
|
||||
result = a * b
|
||||
result = a *% b
|
||||
floatProd = float64(a) # conversion
|
||||
floatProd = floatProd * float64(b)
|
||||
resAsFloat = float64(result)
|
||||
|
|
@ -211,7 +211,7 @@ when defined(asmVersion) and not defined(gcc):
|
|||
"""
|
||||
|
||||
elif defined(asmVersion) and defined(gcc):
|
||||
proc addInt(a, b: int): int =
|
||||
proc addInt(a, b: int): int =
|
||||
asm """ "addl %1,%%eax\n"
|
||||
"jno 1\n"
|
||||
"call _raiseOverflow\n"
|
||||
|
|
@ -219,7 +219,7 @@ elif defined(asmVersion) and defined(gcc):
|
|||
:"=a"(`a`)
|
||||
:"a"(`a`), "r"(`b`)
|
||||
"""
|
||||
|
||||
|
||||
proc subInt(a, b: int): int =
|
||||
asm """ "subl %1,%%eax\n"
|
||||
"jno 1\n"
|
||||
|
|
@ -228,7 +228,7 @@ elif defined(asmVersion) and defined(gcc):
|
|||
:"=a"(`a`)
|
||||
:"a"(`a`), "r"(`b`)
|
||||
"""
|
||||
|
||||
|
||||
proc negInt(a: int): int =
|
||||
asm """ "negl %%eax\n"
|
||||
"jno 1\n"
|
||||
|
|
@ -237,7 +237,7 @@ elif defined(asmVersion) and defined(gcc):
|
|||
:"=a"(`a`)
|
||||
:"a"(`a`)
|
||||
"""
|
||||
|
||||
|
||||
proc divInt(a, b: int): int =
|
||||
asm """ "xorl %%edx, %%edx\n"
|
||||
"idivl %%ecx\n"
|
||||
|
|
@ -276,13 +276,13 @@ else:
|
|||
# Platform independant versions of the above (slower!)
|
||||
|
||||
proc addInt(a, b: int): int =
|
||||
result = a + b
|
||||
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
|
||||
result = a -% b
|
||||
if (result xor a) >= 0 or (result xor not b) >= 0:
|
||||
return result
|
||||
raiseOverflow()
|
||||
|
|
@ -327,7 +327,7 @@ else:
|
|||
var
|
||||
resAsFloat, floatProd: float
|
||||
|
||||
result = a * b
|
||||
result = a *% b
|
||||
floatProd = toFloat(a) * toFloat(b)
|
||||
resAsFloat = toFloat(result)
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,8 @@ proc genericAssign(dest, src: Pointer, mt: PNimType) =
|
|||
var dstseq = cast[PGenericSeq](dst)
|
||||
dstseq.len = seq.len
|
||||
dstseq.space = seq.len
|
||||
of tyRecord, tyObject, tyTuple:
|
||||
of tyObject, tyTuple, tyPureObject:
|
||||
# we don't need to copy m_type field for tyObject, as they are equal anyway
|
||||
genericAssignAux(dest, src, mt.node)
|
||||
of tyArray, tyArrayConstr:
|
||||
for i in 0..(mt.size div mt.base.size)-1:
|
||||
|
|
@ -75,6 +76,7 @@ proc genericAssign(dest, src: Pointer, mt: PNimType) =
|
|||
copyMem(dest, src, mt.size) # copy raw bits
|
||||
|
||||
proc genericSeqAssign(dest, src: Pointer, mt: PNimType) {.compilerProc.} =
|
||||
var src = src # ugly, but I like to stress the parser sometimes :-)
|
||||
genericAssign(dest, addr(src), mt)
|
||||
|
||||
proc genericAssignOpenArray(dest, src: pointer, len: int,
|
||||
|
|
@ -110,7 +112,7 @@ proc objectInit(dest: Pointer, typ: PNimType) =
|
|||
var pint = cast[ptr PNimType](dest)
|
||||
pint^ = typ
|
||||
objectInitAux(dest, typ.node)
|
||||
of tyRecord:
|
||||
of tyTuple, tyPureObject:
|
||||
objectInitAux(dest, typ.node)
|
||||
of tyArray, tyArrayConstr:
|
||||
for i in 0..(typ.size div typ.base.size)-1:
|
||||
|
|
|
|||
|
|
@ -149,13 +149,13 @@ type
|
|||
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
|
||||
cairo_t* {.final.} = object #OPAQUE
|
||||
cairo_surface_t* {.final.} = object #OPAQUE
|
||||
cairo_pattern_t* {.final.} = object #OPAQUE
|
||||
cairo_scaled_font_t* {.final.} = object #OPAQUE
|
||||
cairo_font_face_t* {.final.} = object #OPAQUE
|
||||
cairo_font_options_t* {.final.} = object #OPAQUE
|
||||
cairo_matrix_t* {.final.} = object
|
||||
xx: float64
|
||||
yx: float64
|
||||
xy: float64
|
||||
|
|
@ -163,15 +163,15 @@ type
|
|||
x0: float64
|
||||
y0: float64
|
||||
|
||||
cairo_user_data_key_t* = record
|
||||
cairo_user_data_key_t* {.final.} = object
|
||||
unused: int32
|
||||
|
||||
cairo_glyph_t* = record
|
||||
cairo_glyph_t* {.final.} = object
|
||||
index: int32
|
||||
x: float64
|
||||
y: float64
|
||||
|
||||
cairo_text_extents_t* = record
|
||||
cairo_text_extents_t* {.final.} = object
|
||||
x_bearing: float64
|
||||
y_bearing: float64
|
||||
width: float64
|
||||
|
|
@ -179,28 +179,28 @@ type
|
|||
x_advance: float64
|
||||
y_advance: float64
|
||||
|
||||
cairo_font_extents_t* = record
|
||||
cairo_font_extents_t* {.final.} = object
|
||||
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
|
||||
cairo_path_data_t* {.final.} = object #* _type : cairo_path_data_type_t;
|
||||
# length : LongInt;
|
||||
# end
|
||||
x: float64
|
||||
y: float64
|
||||
|
||||
cairo_path_t* = record
|
||||
cairo_path_t* {.final.} = object
|
||||
status: cairo_status_t
|
||||
data: Pcairo_path_data_t
|
||||
num_data: int32
|
||||
|
||||
cairo_rectangle_t* = record
|
||||
cairo_rectangle_t* {.final.} = object
|
||||
x, y, width, height: float64
|
||||
|
||||
cairo_rectangle_list_t* = record
|
||||
cairo_rectangle_list_t* {.final.} = object
|
||||
status: cairo_status_t
|
||||
rectangles: Pcairo_rectangle_t
|
||||
num_rectangles: int32
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ type
|
|||
ATK_LAYER_INVALID, ATK_LAYER_BACKGROUND, ATK_LAYER_CANVAS, ATK_LAYER_WIDGET,
|
||||
ATK_LAYER_MDI, ATK_LAYER_POPUP, ATK_LAYER_OVERLAY
|
||||
PAtkPropertyValues* = ptr TAtkPropertyValues
|
||||
TAtkPropertyValues* = record
|
||||
TAtkPropertyValues* {.final.} = object
|
||||
property_name*: cstring
|
||||
old_value*: TGValue
|
||||
new_value*: TGValue
|
||||
|
|
@ -379,7 +379,7 @@ type
|
|||
|
||||
TAtkAttributeSet* = TGSList
|
||||
PAtkAttribute* = ptr TAtkAttribute
|
||||
TAtkAttribute* = record
|
||||
TAtkAttribute* {.final.} = object
|
||||
name*: cstring
|
||||
value*: cstring
|
||||
|
||||
|
|
@ -453,7 +453,7 @@ type
|
|||
TAtkEventListenerInitProc* = proc ()
|
||||
TAtkEventListenerInit* = proc (para1: TAtkEventListenerInitProc){.cdecl.}
|
||||
PAtkKeyEventStruct* = ptr TAtkKeyEventStruct
|
||||
TAtkKeyEventStruct* = record
|
||||
TAtkKeyEventStruct* {.final.} = object
|
||||
`type`*: gint
|
||||
state*: guint
|
||||
keyval*: guint
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ type
|
|||
TGdkVisualClass* = object of TGObjectClass
|
||||
|
||||
PGdkColor* = ptr TGdkColor
|
||||
TGdkColor* = record
|
||||
TGdkColor* {.final.} = object
|
||||
pixel*: guint32
|
||||
red*: guint16
|
||||
green*: guint16
|
||||
|
|
@ -52,7 +52,7 @@ type
|
|||
TGdkFontType* = enum
|
||||
GDK_FONT_FONT, GDK_FONT_FONTSET
|
||||
PGdkFont* = ptr TGdkFont
|
||||
TGdkFont* = record
|
||||
TGdkFont* {.final.} = object
|
||||
`type`*: TGdkFontType
|
||||
ascent*: gint
|
||||
descent*: gint
|
||||
|
|
@ -79,7 +79,7 @@ type
|
|||
PGdkGCValuesMask* = ptr TGdkGCValuesMask
|
||||
TGdkGCValuesMask* = int32
|
||||
PGdkGCValues* = ptr TGdkGCValues
|
||||
TGdkGCValues* = record
|
||||
TGdkGCValues* {.final.} = object
|
||||
foreground*: TGdkColor
|
||||
background*: TGdkColor
|
||||
font*: PGdkFont
|
||||
|
|
@ -125,7 +125,7 @@ type
|
|||
TGdkInputCondition* = int32
|
||||
PGdkStatus* = ptr TGdkStatus
|
||||
TGdkStatus* = int32
|
||||
TGdkPoint* = record
|
||||
TGdkPoint* {.final.} = object
|
||||
x*: gint
|
||||
y*: gint
|
||||
|
||||
|
|
@ -135,14 +135,14 @@ type
|
|||
PGdkWChar* = ptr TGdkWChar
|
||||
TGdkWChar* = guint32
|
||||
PGdkSegment* = ptr TGdkSegment
|
||||
TGdkSegment* = record
|
||||
TGdkSegment* {.final.} = object
|
||||
x1*: gint
|
||||
y1*: gint
|
||||
x2*: gint
|
||||
y2*: gint
|
||||
|
||||
PGdkRectangle* = ptr TGdkRectangle
|
||||
TGdkRectangle* = record
|
||||
TGdkRectangle* {.final.} = object
|
||||
x*: gint
|
||||
y*: gint
|
||||
width*: gint
|
||||
|
|
@ -190,7 +190,7 @@ type
|
|||
PGdkCursorType* = ptr TGdkCursorType
|
||||
TGdkCursorType* = gint
|
||||
PGdkCursor* = ptr TGdkCursor
|
||||
TGdkCursor* = record
|
||||
TGdkCursor* {.final.} = object
|
||||
`type`*: TGdkCursorType
|
||||
ref_count*: guint
|
||||
|
||||
|
|
@ -220,14 +220,14 @@ type
|
|||
PGdkRegionBox* = ptr TGdkRegionBox
|
||||
TGdkRegionBox* = TGdkSegment
|
||||
PGdkRegion* = ptr TGdkRegion
|
||||
TGdkRegion* = record
|
||||
TGdkRegion* {.final.} = object
|
||||
size*: int32
|
||||
numRects*: int32
|
||||
rects*: PGdkRegionBox
|
||||
extents*: TGdkRegionBox
|
||||
|
||||
PPOINTBLOCK* = ptr TPOINTBLOCK
|
||||
TPOINTBLOCK* = record
|
||||
TPOINTBLOCK* {.final.} = object
|
||||
pts*: array[0..(NUMPTSTOBUFFER) - 1, TGdkPoint]
|
||||
next*: PPOINTBLOCK
|
||||
|
||||
|
|
@ -336,13 +336,13 @@ type
|
|||
GDK_SETTING_ACTION_NEW, GDK_SETTING_ACTION_CHANGED,
|
||||
GDK_SETTING_ACTION_DELETED
|
||||
PGdkEventAny* = ptr TGdkEventAny
|
||||
TGdkEventAny* = record
|
||||
TGdkEventAny* {.final.} = object
|
||||
`type`*: TGdkEventType
|
||||
window*: PGdkWindow
|
||||
send_event*: gint8
|
||||
|
||||
PGdkEventExpose* = ptr TGdkEventExpose
|
||||
TGdkEventExpose* = record
|
||||
TGdkEventExpose* {.final.} = object
|
||||
`type`*: TGdkEventType
|
||||
window*: PGdkWindow
|
||||
send_event*: gint8
|
||||
|
|
@ -351,20 +351,20 @@ type
|
|||
count*: gint
|
||||
|
||||
PGdkEventNoExpose* = ptr TGdkEventNoExpose
|
||||
TGdkEventNoExpose* = record
|
||||
TGdkEventNoExpose* {.final.} = object
|
||||
`type`*: TGdkEventType
|
||||
window*: PGdkWindow
|
||||
send_event*: gint8
|
||||
|
||||
PGdkEventVisibility* = ptr TGdkEventVisibility
|
||||
TGdkEventVisibility* = record
|
||||
TGdkEventVisibility* {.final.} = object
|
||||
`type`*: TGdkEventType
|
||||
window*: PGdkWindow
|
||||
send_event*: gint8
|
||||
state*: TGdkVisibilityState
|
||||
|
||||
PGdkEventMotion* = ptr TGdkEventMotion
|
||||
TGdkEventMotion* = record
|
||||
TGdkEventMotion* {.final.} = object
|
||||
`type`*: TGdkEventType
|
||||
window*: PGdkWindow
|
||||
send_event*: gint8
|
||||
|
|
@ -379,7 +379,7 @@ type
|
|||
y_root*: gdouble
|
||||
|
||||
PGdkEventButton* = ptr TGdkEventButton
|
||||
TGdkEventButton* = record
|
||||
TGdkEventButton* {.final.} = object
|
||||
`type`*: TGdkEventType
|
||||
window*: PGdkWindow
|
||||
send_event*: gint8
|
||||
|
|
@ -394,7 +394,7 @@ type
|
|||
y_root*: gdouble
|
||||
|
||||
PGdkEventScroll* = ptr TGdkEventScroll
|
||||
TGdkEventScroll* = record
|
||||
TGdkEventScroll* {.final.} = object
|
||||
`type`*: TGdkEventType
|
||||
window*: PGdkWindow
|
||||
send_event*: gint8
|
||||
|
|
@ -408,7 +408,7 @@ type
|
|||
y_root*: gdouble
|
||||
|
||||
PGdkEventKey* = ptr TGdkEventKey
|
||||
TGdkEventKey* = record
|
||||
TGdkEventKey* {.final.} = object
|
||||
`type`*: TGdkEventType
|
||||
window*: PGdkWindow
|
||||
send_event*: gint8
|
||||
|
|
@ -421,7 +421,7 @@ type
|
|||
group*: guint8
|
||||
|
||||
PGdkEventCrossing* = ptr TGdkEventCrossing
|
||||
TGdkEventCrossing* = record
|
||||
TGdkEventCrossing* {.final.} = object
|
||||
`type`*: TGdkEventType
|
||||
window*: PGdkWindow
|
||||
send_event*: gint8
|
||||
|
|
@ -437,14 +437,14 @@ type
|
|||
state*: guint
|
||||
|
||||
PGdkEventFocus* = ptr TGdkEventFocus
|
||||
TGdkEventFocus* = record
|
||||
TGdkEventFocus* {.final.} = object
|
||||
`type`*: TGdkEventType
|
||||
window*: PGdkWindow
|
||||
send_event*: gint8
|
||||
`in`*: gint16
|
||||
|
||||
PGdkEventConfigure* = ptr TGdkEventConfigure
|
||||
TGdkEventConfigure* = record
|
||||
TGdkEventConfigure* {.final.} = object
|
||||
`type`*: TGdkEventType
|
||||
window*: PGdkWindow
|
||||
send_event*: gint8
|
||||
|
|
@ -454,7 +454,7 @@ type
|
|||
height*: gint
|
||||
|
||||
PGdkEventProperty* = ptr TGdkEventProperty
|
||||
TGdkEventProperty* = record
|
||||
TGdkEventProperty* {.final.} = object
|
||||
`type`*: TGdkEventType
|
||||
window*: PGdkWindow
|
||||
send_event*: gint8
|
||||
|
|
@ -464,7 +464,7 @@ type
|
|||
|
||||
TGdkNativeWindow* = pointer
|
||||
PGdkEventSelection* = ptr TGdkEventSelection
|
||||
TGdkEventSelection* = record
|
||||
TGdkEventSelection* {.final.} = object
|
||||
`type`*: TGdkEventType
|
||||
window*: PGdkWindow
|
||||
send_event*: gint8
|
||||
|
|
@ -475,7 +475,7 @@ type
|
|||
requestor*: TGdkNativeWindow
|
||||
|
||||
PGdkEventProximity* = ptr TGdkEventProximity
|
||||
TGdkEventProximity* = record
|
||||
TGdkEventProximity* {.final.} = object
|
||||
`type`*: TGdkEventType
|
||||
window*: PGdkWindow
|
||||
send_event*: gint8
|
||||
|
|
@ -483,11 +483,11 @@ type
|
|||
device*: PGdkDevice
|
||||
|
||||
PmatDUMMY* = ptr TmatDUMMY
|
||||
TmatDUMMY* = record
|
||||
TmatDUMMY* {.final.} = object
|
||||
b*: array[0..19, char]
|
||||
|
||||
PGdkEventClient* = ptr TGdkEventClient
|
||||
TGdkEventClient* = record
|
||||
TGdkEventClient* {.final.} = object
|
||||
`type`*: TGdkEventType
|
||||
window*: PGdkWindow
|
||||
send_event*: gint8
|
||||
|
|
@ -496,7 +496,7 @@ type
|
|||
b*: array[0..19, char]
|
||||
|
||||
PGdkEventSetting* = ptr TGdkEventSetting
|
||||
TGdkEventSetting* = record
|
||||
TGdkEventSetting* {.final.} = object
|
||||
`type`*: TGdkEventType
|
||||
window*: PGdkWindow
|
||||
send_event*: gint8
|
||||
|
|
@ -504,7 +504,7 @@ type
|
|||
name*: cstring
|
||||
|
||||
PGdkEventWindowState* = ptr TGdkEventWindowState
|
||||
TGdkEventWindowState* = record
|
||||
TGdkEventWindowState* {.final.} = object
|
||||
`type`*: TGdkEventType
|
||||
window*: PGdkWindow
|
||||
send_event*: gint8
|
||||
|
|
@ -512,7 +512,7 @@ type
|
|||
new_window_state*: TGdkWindowState
|
||||
|
||||
PGdkEventDND* = ptr TGdkEventDND
|
||||
TGdkEventDND* = record
|
||||
TGdkEventDND* {.final.} = object
|
||||
`type`*: TGdkEventType
|
||||
window*: PGdkWindow
|
||||
send_event*: gint8
|
||||
|
|
@ -521,7 +521,7 @@ type
|
|||
x_root*: gshort
|
||||
y_root*: gshort
|
||||
|
||||
TGdkEvent* = record
|
||||
TGdkEvent* {.final.} = object
|
||||
data*: array[0..255, char] # union of
|
||||
# `type`: TGdkEventType
|
||||
# any: TGdkEventAny
|
||||
|
|
@ -585,12 +585,12 @@ type
|
|||
PGdkAxisUse* = ptr TGdkAxisUse
|
||||
TGdkAxisUse* = int32
|
||||
PGdkDeviceKey* = ptr TGdkDeviceKey
|
||||
TGdkDeviceKey* = record
|
||||
TGdkDeviceKey* {.final.} = object
|
||||
keyval*: guint
|
||||
modifiers*: TGdkModifierType
|
||||
|
||||
PGdkDeviceAxis* = ptr TGdkDeviceAxis
|
||||
TGdkDeviceAxis* = record
|
||||
TGdkDeviceAxis* {.final.} = object
|
||||
use*: TGdkAxisUse
|
||||
min*: gdouble
|
||||
max*: gdouble
|
||||
|
|
@ -605,12 +605,12 @@ type
|
|||
num_keys*: gint
|
||||
keys*: PGdkDeviceKey
|
||||
|
||||
TGdkTimeCoord* = record
|
||||
TGdkTimeCoord* {.final.} = object
|
||||
time*: guint32
|
||||
axes*: array[0..(GDK_MAX_TIMECOORD_AXES) - 1, gdouble]
|
||||
|
||||
PGdkKeymapKey* = ptr TGdkKeymapKey
|
||||
TGdkKeymapKey* = record
|
||||
TGdkKeymapKey* {.final.} = object
|
||||
keycode*: guint
|
||||
group*: gint
|
||||
level*: gint
|
||||
|
|
@ -624,12 +624,12 @@ type
|
|||
direction_changed*: proc (keymap: PGdkKeymap){.cdecl.}
|
||||
|
||||
PGdkPangoAttrStipple* = ptr TGdkPangoAttrStipple
|
||||
TGdkPangoAttrStipple* = record
|
||||
TGdkPangoAttrStipple* {.final.} = object
|
||||
attr*: TPangoAttribute
|
||||
stipple*: PGdkBitmap
|
||||
|
||||
PGdkPangoAttrEmbossed* = ptr TGdkPangoAttrEmbossed
|
||||
TGdkPangoAttrEmbossed* = record
|
||||
TGdkPangoAttrEmbossed* {.final.} = object
|
||||
attr*: TPangoAttribute
|
||||
embossed*: gboolean
|
||||
|
||||
|
|
@ -653,7 +653,7 @@ type
|
|||
GDK_OVERLAP_RECTANGLE_PART
|
||||
TGdkSpanFunc* = proc (span: PGdkSpan, data: gpointer){.cdecl.}
|
||||
PGdkRgbCmap* = ptr TGdkRgbCmap
|
||||
TGdkRgbCmap* = record
|
||||
TGdkRgbCmap* {.final.} = object
|
||||
colors*: array[0..255, guint32]
|
||||
n_colors*: gint
|
||||
info_list*: PGSList
|
||||
|
|
@ -698,7 +698,7 @@ type
|
|||
TGdkInputFunction* = proc (data: gpointer, source: gint,
|
||||
condition: TGdkInputCondition){.cdecl.}
|
||||
TGdkDestroyNotify* = proc (data: gpointer){.cdecl.}
|
||||
TGdkSpan* = record
|
||||
TGdkSpan* {.final.} = object
|
||||
x*: gint
|
||||
y*: gint
|
||||
width*: gint
|
||||
|
|
@ -731,7 +731,7 @@ type
|
|||
GDK_WINDOW_EDGE_SOUTH_WEST, GDK_WINDOW_EDGE_SOUTH,
|
||||
GDK_WINDOW_EDGE_SOUTH_EAST
|
||||
PGdkWindowAttr* = ptr TGdkWindowAttr
|
||||
TGdkWindowAttr* = record
|
||||
TGdkWindowAttr* {.final.} = object
|
||||
title*: cstring
|
||||
event_mask*: gint
|
||||
x*: gint
|
||||
|
|
@ -748,7 +748,7 @@ type
|
|||
override_redirect*: gboolean
|
||||
|
||||
PGdkGeometry* = ptr TGdkGeometry
|
||||
TGdkGeometry* = record
|
||||
TGdkGeometry* {.final.} = object
|
||||
min_width*: gint
|
||||
min_height*: gint
|
||||
max_width*: gint
|
||||
|
|
@ -762,7 +762,7 @@ type
|
|||
win_gravity*: TGdkGravity
|
||||
|
||||
PGdkPointerHooks* = ptr TGdkPointerHooks
|
||||
TGdkPointerHooks* = record
|
||||
TGdkPointerHooks* {.final.} = object
|
||||
get_pointer*: proc (window: PGdkWindow, x: Pgint, y: Pgint,
|
||||
mask: PGdkModifierType): PGdkWindow{.cdecl.}
|
||||
window_at_pointer*: proc (screen: PGdkScreen, win_x: Pgint, win_y: Pgint): PGdkWindow{.
|
||||
|
|
|
|||
|
|
@ -191,12 +191,12 @@ proc gdk_pixbuf_get_option*(pixbuf: PGdkPixbuf, key: cstring): cstring{.cdecl,
|
|||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_get_option".}
|
||||
type
|
||||
PGdkPixbufLoader* = ptr TGdkPixbufLoader
|
||||
TGdkPixbufLoader* = record
|
||||
TGdkPixbufLoader* {.final.} = object
|
||||
parent_instance*: TGObject
|
||||
priv*: gpointer
|
||||
|
||||
PGdkPixbufLoaderClass* = ptr TGdkPixbufLoaderClass
|
||||
TGdkPixbufLoaderClass* = record
|
||||
TGdkPixbufLoaderClass* {.final.} = object
|
||||
parent_class*: TGObjectClass
|
||||
area_prepared*: proc (loader: PGdkPixbufLoader){.cdecl.}
|
||||
area_updated*: proc (loader: PGdkPixbufLoader, x: int32, y: int32,
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ type
|
|||
TGHFunc* = proc (key, value, user_data: gpointer){.cdecl.}
|
||||
PGFreeFunc* = proc (data: gpointer){.cdecl.}
|
||||
PGTimeVal* = ptr TGTimeVal
|
||||
TGTimeVal* = record
|
||||
TGTimeVal* {.final.} = object
|
||||
tv_sec*: glong
|
||||
tv_usec*: glong
|
||||
|
||||
|
|
@ -88,17 +88,17 @@ type
|
|||
TGQuark* = guint32
|
||||
PGQuark* = ptr TGQuark
|
||||
PGTypeCValue* = ptr TGTypeCValue
|
||||
TGTypeCValue* = record
|
||||
TGTypeCValue* {.final.} = object
|
||||
v_double*: gdouble
|
||||
|
||||
GType* = gulong
|
||||
PGType* = ptr GType
|
||||
PGTypeClass* = ptr TGTypeClass
|
||||
TGTypeClass* = record
|
||||
TGTypeClass* {.final.} = object
|
||||
g_type*: GType
|
||||
|
||||
PGTypeInstance* = ptr TGTypeInstance
|
||||
TGTypeInstance* = record
|
||||
TGTypeInstance* {.final.} = object
|
||||
g_class*: PGTypeClass
|
||||
|
||||
PGTypeInterface* = ptr TGTypeInterface
|
||||
|
|
@ -107,14 +107,14 @@ type
|
|||
g_instance_type*: GType
|
||||
|
||||
PGTypeQuery* = ptr TGTypeQuery
|
||||
TGTypeQuery* = record
|
||||
TGTypeQuery* {.final.} = object
|
||||
theType*: GType
|
||||
type_name*: cstring
|
||||
class_size*: guint
|
||||
instance_size*: guint
|
||||
|
||||
PGValue* = ptr TGValue
|
||||
TGValue* = record
|
||||
TGValue* {.final.} = object
|
||||
g_type*: GType
|
||||
data*: array[0..1, gdouble]
|
||||
|
||||
|
|
@ -122,12 +122,12 @@ type
|
|||
PGData* = pointer
|
||||
PGSList* = ptr TGSList
|
||||
PPGSList* = ptr PGSList
|
||||
TGSList* = record
|
||||
TGSList* {.final.} = object
|
||||
data*: gpointer
|
||||
next*: PGSList
|
||||
|
||||
PGList* = ptr TGList
|
||||
TGList* = record
|
||||
TGList* {.final.} = object
|
||||
data*: gpointer
|
||||
next*: PGList
|
||||
prev*: PGList
|
||||
|
|
@ -136,7 +136,7 @@ type
|
|||
TGParamFlags* = int32
|
||||
PGParamSpec* = ptr TGParamSpec
|
||||
PPGParamSpec* = ptr PGParamSpec
|
||||
TGParamSpec* = record
|
||||
TGParamSpec* {.final.} = object
|
||||
g_type_instance*: TGTypeInstance
|
||||
name*: cstring
|
||||
flags*: TGParamFlags
|
||||
|
|
@ -149,7 +149,7 @@ type
|
|||
param_id*: guint
|
||||
|
||||
PGParamSpecClass* = ptr TGParamSpecClass
|
||||
TGParamSpecClass* = record
|
||||
TGParamSpecClass* {.final.} = object
|
||||
g_type_class*: TGTypeClass
|
||||
value_type*: GType
|
||||
finalize*: proc (pspec: PGParamSpec){.cdecl.}
|
||||
|
|
@ -160,7 +160,7 @@ type
|
|||
dummy*: array[0..3, gpointer]
|
||||
|
||||
PGParameter* = ptr TGParameter
|
||||
TGParameter* = record
|
||||
TGParameter* {.final.} = object
|
||||
name*: cstring
|
||||
value*: TGValue
|
||||
|
||||
|
|
@ -305,7 +305,7 @@ const
|
|||
|
||||
type
|
||||
PGTypeValueTable* = ptr TGTypeValueTable
|
||||
TGTypeValueTable* = record
|
||||
TGTypeValueTable* {.final.} = object
|
||||
value_init*: proc (value: PGValue){.cdecl.}
|
||||
value_free*: proc (value: PGValue){.cdecl.}
|
||||
value_copy*: proc (src_value: PGValue, dest_value: PGValue){.cdecl.}
|
||||
|
|
@ -320,7 +320,7 @@ type
|
|||
cdecl.}
|
||||
|
||||
PGTypeInfo* = ptr TGTypeInfo
|
||||
TGTypeInfo* = record
|
||||
TGTypeInfo* {.final.} = object
|
||||
class_size*: guint16
|
||||
base_init*: TGBaseInitFunc
|
||||
base_finalize*: TGBaseFinalizeFunc
|
||||
|
|
@ -333,11 +333,11 @@ type
|
|||
value_table*: PGTypeValueTable
|
||||
|
||||
PGTypeFundamentalInfo* = ptr TGTypeFundamentalInfo
|
||||
TGTypeFundamentalInfo* = record
|
||||
TGTypeFundamentalInfo* {.final.} = object
|
||||
type_flags*: TGTypeFundamentalFlags
|
||||
|
||||
PGInterfaceInfo* = ptr TGInterfaceInfo
|
||||
TGInterfaceInfo* = record
|
||||
TGInterfaceInfo* {.final.} = object
|
||||
interface_init*: TGInterfaceInitFunc
|
||||
interface_finalize*: TGInterfaceFinalizeFunc
|
||||
interface_data*: gpointer
|
||||
|
|
@ -449,7 +449,7 @@ const
|
|||
|
||||
type
|
||||
PGValueArray* = ptr TGValueArray
|
||||
TGValueArray* = record
|
||||
TGValueArray* {.final.} = object
|
||||
n_values*: guint
|
||||
values*: PGValue
|
||||
n_prealloced*: guint
|
||||
|
|
@ -628,7 +628,7 @@ proc g_value_set_param_take_ownership*(value: PGValue, param: PGParamSpec){.
|
|||
cdecl, dynlib: gliblib, importc: "g_value_set_param_take_ownership".}
|
||||
type
|
||||
PGParamSpecTypeInfo* = ptr TGParamSpecTypeInfo
|
||||
TGParamSpecTypeInfo* = record
|
||||
TGParamSpecTypeInfo* {.final.} = object
|
||||
instance_size*: guint16
|
||||
n_preallocs*: guint16
|
||||
instance_init*: proc (pspec: PGParamSpec){.cdecl.}
|
||||
|
|
@ -668,7 +668,7 @@ type
|
|||
PGClosure* = ptr TGClosure
|
||||
PGClosureNotifyData* = ptr TGClosureNotifyData
|
||||
TGClosureNotify* = proc (data: gpointer, closure: PGClosure){.cdecl.}
|
||||
TGClosure* = record
|
||||
TGClosure* {.final.} = object
|
||||
flag0*: int32
|
||||
marshal*: proc (closure: PGClosure, return_value: PGValue,
|
||||
n_param_values: guint, param_values: PGValue,
|
||||
|
|
@ -682,7 +682,7 @@ type
|
|||
n_param_values: guint, param_values: PGValue,
|
||||
invocation_hint: gpointer, marshal_data: gpointer){.
|
||||
cdecl.}
|
||||
TGClosureNotifyData* = record
|
||||
TGClosureNotifyData* {.final.} = object
|
||||
data*: gpointer
|
||||
notify*: TGClosureNotify
|
||||
|
||||
|
|
@ -734,7 +734,7 @@ proc is_invalid*(a: var TGClosure): guint
|
|||
proc set_is_invalid*(a: var TGClosure, is_invalid: guint)
|
||||
type
|
||||
PGCClosure* = ptr TGCClosure
|
||||
TGCClosure* = record
|
||||
TGCClosure* {.final.} = object
|
||||
closure*: TGClosure
|
||||
callback*: gpointer
|
||||
|
||||
|
|
@ -797,13 +797,13 @@ type
|
|||
data: gpointer): gboolean{.cdecl.}
|
||||
PGSignalFlags* = ptr TGSignalFlags
|
||||
TGSignalFlags* = int32
|
||||
TGSignalInvocationHint* = record
|
||||
TGSignalInvocationHint* {.final.} = object
|
||||
signal_id*: guint
|
||||
detail*: TGQuark
|
||||
run_type*: TGSignalFlags
|
||||
|
||||
PGSignalQuery* = ptr TGSignalQuery
|
||||
TGSignalQuery* = record
|
||||
TGSignalQuery* {.final.} = object
|
||||
signal_id*: guint
|
||||
signal_name*: cstring
|
||||
itype*: GType
|
||||
|
|
@ -952,7 +952,7 @@ type
|
|||
TGTypePluginCompleteInterfaceInfo* = proc (plugin: PGTypePlugin,
|
||||
instance_type: GType, interface_type: GType, info: PGInterfaceInfo){.cdecl.}
|
||||
PGTypePluginClass* = ptr TGTypePluginClass
|
||||
TGTypePluginClass* = record
|
||||
TGTypePluginClass* {.final.} = object
|
||||
base_iface*: TGTypeInterface
|
||||
use_plugin*: TGTypePluginUse
|
||||
unuse_plugin*: TGTypePluginUnuse
|
||||
|
|
@ -1011,7 +1011,7 @@ type
|
|||
notify*: proc (anObject: PGObject, pspec: PGParamSpec){.cdecl.}
|
||||
pdummy*: array[0..7, gpointer]
|
||||
|
||||
TGObjectConstructParam* = record
|
||||
TGObjectConstructParam* {.final.} = object
|
||||
pspec*: PGParamSpec
|
||||
value*: PGValue
|
||||
|
||||
|
|
@ -1125,27 +1125,27 @@ proc GUINT32_SWAP_LE_BE_CONSTANT*(val: guint32): guint32
|
|||
type
|
||||
PGEnumClass* = ptr TGEnumClass
|
||||
PGEnumValue* = ptr TGEnumValue
|
||||
TGEnumClass* = record
|
||||
TGEnumClass* {.final.} = object
|
||||
g_type_class*: TGTypeClass
|
||||
minimum*: gint
|
||||
maximum*: gint
|
||||
n_values*: guint
|
||||
values*: PGEnumValue
|
||||
|
||||
TGEnumValue* = record
|
||||
TGEnumValue* {.final.} = object
|
||||
value*: gint
|
||||
value_name*: cstring
|
||||
value_nick*: cstring
|
||||
|
||||
PGFlagsClass* = ptr TGFlagsClass
|
||||
PGFlagsValue* = ptr TGFlagsValue
|
||||
TGFlagsClass* = record
|
||||
TGFlagsClass* {.final.} = object
|
||||
g_type_class*: TGTypeClass
|
||||
mask*: guint
|
||||
n_values*: guint
|
||||
values*: PGFlagsValue
|
||||
|
||||
TGFlagsValue* = record
|
||||
TGFlagsValue* {.final.} = object
|
||||
value*: guint
|
||||
value_name*: cstring
|
||||
value_nick*: cstring
|
||||
|
|
@ -1203,7 +1203,7 @@ const
|
|||
G_MAXUSHORT* = 2 * G_MAXSHORT + 1
|
||||
G_MAXINT* = 2147483647
|
||||
G_MININT* = - G_MAXINT - 1
|
||||
G_MAXUINT* = 4294967295
|
||||
G_MAXUINT* = -1
|
||||
G_MINLONG* = G_MININT
|
||||
G_MAXLONG* = G_MAXINT
|
||||
G_MAXULONG* = G_MAXUINT
|
||||
|
|
@ -1224,7 +1224,7 @@ const
|
|||
|
||||
type
|
||||
PGSystemThread* = ptr TGSystemThread
|
||||
TGSystemThread* = record
|
||||
TGSystemThread* {.final.} = object
|
||||
data*: array[0..3, char]
|
||||
dummy_double*: float64
|
||||
dummy_pointer*: pointer
|
||||
|
|
@ -1350,7 +1350,7 @@ proc g_set_prgname*(prgname: cstring){.cdecl, dynlib: gliblib,
|
|||
importc: "g_set_prgname".}
|
||||
type
|
||||
PGDebugKey* = ptr TGDebugKey
|
||||
TGDebugKey* = record
|
||||
TGDebugKey* {.final.} = object
|
||||
key*: cstring
|
||||
value*: guint
|
||||
|
||||
|
|
@ -1390,7 +1390,7 @@ proc g_bit_storage*(number: gulong): guint{.cdecl, dynlib: gliblib,
|
|||
type
|
||||
PPGTrashStack* = ptr PGTrashStack
|
||||
PGTrashStack* = ptr TGTrashStack
|
||||
TGTrashStack* = record
|
||||
TGTrashStack* {.final.} = object
|
||||
next*: PGTrashStack
|
||||
|
||||
|
||||
|
|
@ -1466,7 +1466,7 @@ const
|
|||
|
||||
type
|
||||
PGMemVTable* = ptr TGMemVTable
|
||||
TGMemVTable* = record
|
||||
TGMemVTable* {.final.} = object
|
||||
malloc*: proc (n_bytes: gsize): gpointer{.cdecl.}
|
||||
realloc*: proc (mem: gpointer, n_bytes: gsize): gpointer{.cdecl.}
|
||||
free*: proc (mem: gpointer){.cdecl.}
|
||||
|
|
@ -1679,7 +1679,7 @@ type
|
|||
TGCompletionStrncmpFunc* = proc (s1: cstring, s2: cstring, n: gsize): gint{.
|
||||
cdecl.}
|
||||
PGCompletion* = ptr TGCompletion
|
||||
TGCompletion* = record
|
||||
TGCompletion* {.final.} = object
|
||||
items*: PGList
|
||||
func*: TGCompletionFunc
|
||||
prefix*: cstring
|
||||
|
|
@ -1809,7 +1809,7 @@ type
|
|||
PGDateDay* = ptr TGDateDay
|
||||
TGDateDay* = guint8
|
||||
Ptm* = ptr Ttm
|
||||
Ttm* = record
|
||||
Ttm* {.final.} = object
|
||||
tm_sec*: gint
|
||||
tm_min*: gint
|
||||
tm_hour*: gint
|
||||
|
|
@ -1872,7 +1872,7 @@ const
|
|||
|
||||
type
|
||||
PGDate* = ptr TGDate
|
||||
TGDate* = record
|
||||
TGDate* {.final.} = object
|
||||
flag0*: int32
|
||||
flag1*: int32
|
||||
|
||||
|
|
@ -2028,7 +2028,7 @@ proc g_file_open_tmp*(tmpl: cstring, name_used: PPchar, error: pointer): int32{.
|
|||
cdecl, dynlib: gliblib, importc: "g_file_open_tmp".}
|
||||
type
|
||||
PGHook* = ptr TGHook
|
||||
TGHook* = record
|
||||
TGHook* {.final.} = object
|
||||
data*: gpointer
|
||||
next*: PGHook
|
||||
prev*: PGHook
|
||||
|
|
@ -2047,7 +2047,7 @@ type
|
|||
TGHookFunc* = proc (data: gpointer){.cdecl.}
|
||||
TGHookCheckFunc* = proc (data: gpointer): gboolean{.cdecl.}
|
||||
TGHookFinalizeFunc* = proc (hook_list: PGHookList, hook: PGHook){.cdecl.}
|
||||
TGHookList* = record
|
||||
TGHookList* {.final.} = object
|
||||
seq_id*: gulong
|
||||
flag0*: int32
|
||||
hooks*: PGHook
|
||||
|
|
@ -2138,7 +2138,7 @@ proc g_hook_list_marshal_check*(hook_list: PGHookList, may_recurse: gboolean,
|
|||
importc: "g_hook_list_marshal_check".}
|
||||
type
|
||||
PGThreadPool* = ptr TGThreadPool
|
||||
TGThreadPool* = record
|
||||
TGThreadPool* {.final.} = object
|
||||
func*: TGFunc
|
||||
user_data*: gpointer
|
||||
exclusive*: gboolean
|
||||
|
|
@ -2352,7 +2352,7 @@ proc g_utf8_collate_key*(str: cstring, len: gssize): cstring{.cdecl,
|
|||
dynlib: gliblib, importc: "g_utf8_collate_key".}
|
||||
type
|
||||
PGString* = ptr TGString
|
||||
TGString* = record
|
||||
TGString* {.final.} = object
|
||||
str*: cstring
|
||||
len*: gsize
|
||||
allocated_len*: gsize
|
||||
|
|
@ -2468,7 +2468,7 @@ type
|
|||
TGIOFunc* = proc (source: PGIOChannel, condition: TGIOCondition,
|
||||
data: gpointer): gboolean{.cdecl.}
|
||||
PGIOFuncs* = ptr TGIOFuncs
|
||||
TGIOFuncs* = record
|
||||
TGIOFuncs* {.final.} = object
|
||||
io_read*: proc (channel: PGIOChannel, buf: cstring, count: gsize,
|
||||
bytes_read: Pgsize, err: pointer): TGIOStatus{.cdecl.}
|
||||
io_write*: proc (channel: PGIOChannel, buf: cstring, count: gsize,
|
||||
|
|
@ -2483,7 +2483,7 @@ type
|
|||
cdecl.}
|
||||
io_get_flags*: proc (channel: PGIOChannel): TGIOFlags{.cdecl.}
|
||||
|
||||
TGIOChannel* = record
|
||||
TGIOChannel* {.final.} = object
|
||||
ref_count*: guint
|
||||
funcs*: PGIOFuncs
|
||||
encoding*: cstring
|
||||
|
|
@ -2699,7 +2699,7 @@ type
|
|||
PGMarkupParseContext* = ptr TGMarkupParseContext
|
||||
TGMarkupParseContext* = pointer
|
||||
PGMarkupParser* = ptr TGMarkupParser
|
||||
TGMarkupParser* = record
|
||||
TGMarkupParser* {.final.} = object
|
||||
start_element*: proc (context: PGMarkupParseContext, element_name: cstring,
|
||||
attribute_names: PPgchar, attribute_values: PPgchar,
|
||||
user_data: gpointer, error: pointer){.cdecl.}
|
||||
|
|
@ -2733,7 +2733,7 @@ proc g_markup_escape_text*(text: cstring, length: gssize): cstring{.cdecl,
|
|||
dynlib: gliblib, importc: "g_markup_escape_text".}
|
||||
type
|
||||
PGNode* = ptr TGNode
|
||||
TGNode* = record
|
||||
TGNode* {.final.} = object
|
||||
data*: gpointer
|
||||
next*: PGNode
|
||||
prev*: PGNode
|
||||
|
|
@ -2886,7 +2886,7 @@ proc g_qsort_with_data*(pbase: gconstpointer, total_elems: gint, size: gsize,
|
|||
cdecl, dynlib: gliblib, importc: "g_qsort_with_data".}
|
||||
type
|
||||
PGQueue* = ptr TGQueue
|
||||
TGQueue* = record
|
||||
TGQueue* {.final.} = object
|
||||
head*: PGList
|
||||
tail*: PGList
|
||||
length*: guint
|
||||
|
|
@ -2947,7 +2947,7 @@ proc g_random_double_range*(`begin`: gdouble, `end`: gdouble): gdouble{.cdecl,
|
|||
dynlib: gliblib, importc: "g_random_double_range".}
|
||||
type
|
||||
PGTuples* = ptr TGTuples
|
||||
TGTuples* = record
|
||||
TGTuples* {.final.} = object
|
||||
len*: guint
|
||||
|
||||
PGRelation* = pointer
|
||||
|
|
@ -3003,12 +3003,12 @@ type
|
|||
PGScanner* = ptr TGScanner
|
||||
PGScannerConfig* = ptr TGScannerConfig
|
||||
PGTokenValue* = ptr TGTokenValue
|
||||
TGTokenValue* = record
|
||||
TGTokenValue* {.final.} = object
|
||||
v_float*: gdouble
|
||||
|
||||
TGScannerMsgFunc* = proc (scanner: PGScanner, message: cstring,
|
||||
error: gboolean){.cdecl.}
|
||||
TGScanner* = record
|
||||
TGScanner* {.final.} = object
|
||||
user_data*: gpointer
|
||||
max_parse_errors*: guint
|
||||
parse_errors*: guint
|
||||
|
|
@ -3031,7 +3031,7 @@ type
|
|||
scope_id*: guint
|
||||
msg_handler*: TGScannerMsgFunc
|
||||
|
||||
TGScannerConfig* = record
|
||||
TGScannerConfig* {.final.} = object
|
||||
cset_skip_characters*: cstring
|
||||
cset_identifier_first*: cstring
|
||||
cset_identifier_nth*: cstring
|
||||
|
|
|
|||
|
|
@ -155,17 +155,17 @@ type
|
|||
TGtkSignalFunc* = proc (para1: TGtkSignalFuncProc){.cdecl.}
|
||||
PGtkSignalMarshaller* = ptr TGtkSignalMarshaller
|
||||
TGtkSignalMarshaller* = TGSignalCMarshaller
|
||||
TGtkArgSignalData* = record
|
||||
TGtkArgSignalData* {.final.} = object
|
||||
f*: TGtkSignalFunc
|
||||
d*: gpointer
|
||||
|
||||
TGtkArg* = record
|
||||
TGtkArg* {.final.} = object
|
||||
`type`*: TGtkType
|
||||
name*: cstring
|
||||
d*: gdouble # was a union type
|
||||
|
||||
PGtkTypeInfo* = ptr TGtkTypeInfo
|
||||
TGtkTypeInfo* = record
|
||||
TGtkTypeInfo* {.final.} = object
|
||||
type_name*: cstring
|
||||
object_size*: guint
|
||||
class_size*: guint
|
||||
|
|
@ -188,7 +188,7 @@ type
|
|||
TGtkAllocation* = TGdkRectangle
|
||||
TGtkCallback* = proc (widget: PGtkWidget, data: gpointer){.cdecl.}
|
||||
PGtkRequisition* = ptr TGtkRequisition
|
||||
TGtkRequisition* = record
|
||||
TGtkRequisition* {.final.} = object
|
||||
width*: gint
|
||||
height*: gint
|
||||
|
||||
|
|
@ -323,7 +323,7 @@ type
|
|||
gtk_reserved8*: proc (){.cdecl.}
|
||||
|
||||
PGtkWidgetAuxInfo* = ptr TGtkWidgetAuxInfo
|
||||
TGtkWidgetAuxInfo* = record
|
||||
TGtkWidgetAuxInfo* {.final.} = object
|
||||
x*: gint
|
||||
y*: gint
|
||||
width*: gint
|
||||
|
|
@ -331,7 +331,7 @@ type
|
|||
flag0*: guint16
|
||||
|
||||
PGtkWidgetShapeInfo* = ptr TGtkWidgetShapeInfo
|
||||
TGtkWidgetShapeInfo* = record
|
||||
TGtkWidgetShapeInfo* {.final.} = object
|
||||
offset_x*: gint16
|
||||
offset_y*: gint16
|
||||
shape_mask*: PGdkBitmap
|
||||
|
|
@ -370,12 +370,12 @@ type
|
|||
gtk_reserved4: proc (){.cdecl.}
|
||||
|
||||
PGtkAccelKey* = ptr TGtkAccelKey
|
||||
TGtkAccelKey* = record
|
||||
TGtkAccelKey* {.final.} = object
|
||||
accel_key*: guint
|
||||
accel_mods*: TGdkModifierType
|
||||
flag0*: guint16
|
||||
|
||||
TGtkAccelGroupEntry* = record
|
||||
TGtkAccelGroupEntry* {.final.} = object
|
||||
key*: TGtkAccelKey
|
||||
closure*: PGClosure
|
||||
accel_path_quark*: TGQuark
|
||||
|
|
@ -595,7 +595,7 @@ type
|
|||
PGtkBindingSignal* = ptr TGtkBindingSignal
|
||||
PGtkBindingArg* = ptr TGtkBindingArg
|
||||
PGtkBindingSet* = ptr TGtkBindingSet
|
||||
TGtkBindingSet* = record
|
||||
TGtkBindingSet* {.final.} = object
|
||||
set_name*: cstring
|
||||
priority*: gint
|
||||
widget_path_pspecs*: PGSList
|
||||
|
|
@ -605,7 +605,7 @@ type
|
|||
current*: PGtkBindingEntry
|
||||
flag0*: guint16
|
||||
|
||||
TGtkBindingEntry* = record
|
||||
TGtkBindingEntry* {.final.} = object
|
||||
keyval*: guint
|
||||
modifiers*: TGdkModifierType
|
||||
binding_set*: PGtkBindingSet
|
||||
|
|
@ -614,13 +614,13 @@ type
|
|||
hash_next*: PGtkBindingEntry
|
||||
signals*: PGtkBindingSignal
|
||||
|
||||
TGtkBindingSignal* = record
|
||||
TGtkBindingSignal* {.final.} = object
|
||||
next*: PGtkBindingSignal
|
||||
signal_name*: cstring
|
||||
n_args*: guint
|
||||
args*: PGtkBindingArg
|
||||
|
||||
TGtkBindingArg* = record
|
||||
TGtkBindingArg* {.final.} = object
|
||||
arg_type*: TGtkType
|
||||
d*: gdouble
|
||||
|
||||
|
|
@ -634,7 +634,7 @@ type
|
|||
TGtkBoxClass* = object of TGtkContainerClass
|
||||
|
||||
PGtkBoxChild* = ptr TGtkBoxChild
|
||||
TGtkBoxChild* = record
|
||||
TGtkBoxChild* {.final.} = object
|
||||
widget*: PGtkWidget
|
||||
padding*: guint16
|
||||
flag0*: guint16
|
||||
|
|
@ -906,12 +906,12 @@ type
|
|||
TGtkCListCompareFunc* = proc (clist: PGtkCList, ptr1: gconstpointer,
|
||||
ptr2: gconstpointer): gint{.cdecl.}
|
||||
PGtkCListCellInfo* = ptr TGtkCListCellInfo
|
||||
TGtkCListCellInfo* = record
|
||||
TGtkCListCellInfo* {.final.} = object
|
||||
row*: gint
|
||||
column*: gint
|
||||
|
||||
PGtkCListDestInfo* = ptr TGtkCListDestInfo
|
||||
TGtkCListDestInfo* = record
|
||||
TGtkCListDestInfo* {.final.} = object
|
||||
cell*: TGtkCListCellInfo
|
||||
insert_pos*: TGtkCListDragPos
|
||||
|
||||
|
|
@ -1014,7 +1014,7 @@ type
|
|||
|
||||
PGPtrArray = pointer
|
||||
PGArray = pointer
|
||||
TGtkCListColumn* = record
|
||||
TGtkCListColumn* {.final.} = object
|
||||
title*: cstring
|
||||
area*: TGdkRectangle
|
||||
button*: PGtkWidget
|
||||
|
|
@ -1025,7 +1025,7 @@ type
|
|||
justification*: TGtkJustification
|
||||
flag0*: guint16
|
||||
|
||||
TGtkCListRow* = record
|
||||
TGtkCListRow* {.final.} = object
|
||||
cell*: PGtkCell
|
||||
state*: TGtkStateType
|
||||
foreground*: TGdkColor
|
||||
|
|
@ -1036,7 +1036,7 @@ type
|
|||
flag0*: guint16
|
||||
|
||||
PGtkCellText* = ptr TGtkCellText
|
||||
TGtkCellText* = record
|
||||
TGtkCellText* {.final.} = object
|
||||
`type`*: TGtkCellType
|
||||
vertical*: gint16
|
||||
horizontal*: gint16
|
||||
|
|
@ -1044,7 +1044,7 @@ type
|
|||
text*: cstring
|
||||
|
||||
PGtkCellPixmap* = ptr TGtkCellPixmap
|
||||
TGtkCellPixmap* = record
|
||||
TGtkCellPixmap* {.final.} = object
|
||||
`type`*: TGtkCellType
|
||||
vertical*: gint16
|
||||
horizontal*: gint16
|
||||
|
|
@ -1053,7 +1053,7 @@ type
|
|||
mask*: PGdkBitmap
|
||||
|
||||
PGtkCellPixText* = ptr TGtkCellPixText
|
||||
TGtkCellPixText* = record
|
||||
TGtkCellPixText* {.final.} = object
|
||||
`type`*: TGtkCellType
|
||||
vertical*: gint16
|
||||
horizontal*: gint16
|
||||
|
|
@ -1064,14 +1064,14 @@ type
|
|||
mask*: PGdkBitmap
|
||||
|
||||
PGtkCellWidget* = ptr TGtkCellWidget
|
||||
TGtkCellWidget* = record
|
||||
TGtkCellWidget* {.final.} = object
|
||||
`type`*: TGtkCellType
|
||||
vertical*: gint16
|
||||
horizontal*: gint16
|
||||
style*: PGtkStyle
|
||||
widget*: PGtkWidget
|
||||
|
||||
TGtkCell* = record
|
||||
TGtkCell* {.final.} = object
|
||||
`type`*: TGtkCellType
|
||||
vertical*: gint16
|
||||
horizontal*: gint16
|
||||
|
|
@ -1212,7 +1212,7 @@ type
|
|||
action: TGtkCTreeExpansionType){.cdecl.}
|
||||
|
||||
PGtkCTreeRow* = ptr TGtkCTreeRow
|
||||
TGtkCTreeRow* = record
|
||||
TGtkCTreeRow* {.final.} = object
|
||||
row*: TGtkCListRow
|
||||
parent*: PGtkCTreeNode
|
||||
sibling*: PGtkCTreeNode
|
||||
|
|
@ -1224,7 +1224,7 @@ type
|
|||
level*: guint16
|
||||
GtkCTreeRow_flag0*: guint16
|
||||
|
||||
TGtkCTreeNode* = record
|
||||
TGtkCTreeNode* {.final.} = object
|
||||
list*: TGList
|
||||
|
||||
PGtkDrawingArea* = ptr TGtkDrawingArea
|
||||
|
|
@ -1479,7 +1479,7 @@ type
|
|||
TGtkFixedClass* = object of TGtkContainerClass
|
||||
|
||||
PGtkFixedChild* = ptr TGtkFixedChild
|
||||
TGtkFixedChild* = record
|
||||
TGtkFixedChild* {.final.} = object
|
||||
widget*: PGtkWidget
|
||||
x*: gint
|
||||
y*: gint
|
||||
|
|
@ -1632,7 +1632,7 @@ type
|
|||
gtk_reserved363: proc (){.cdecl.}
|
||||
gtk_reserved364: proc (){.cdecl.}
|
||||
|
||||
TGtkRulerMetric* = record
|
||||
TGtkRulerMetric* {.final.} = object
|
||||
metric_name*: cstring
|
||||
abbrev*: cstring
|
||||
pixels_per_unit*: gdouble
|
||||
|
|
@ -1657,7 +1657,7 @@ type
|
|||
TGtkSettingsClass* = object of TGObjectClass
|
||||
|
||||
PGtkSettingsValue* = ptr TGtkSettingsValue
|
||||
TGtkSettingsValue* = record
|
||||
TGtkSettingsValue* {.final.} = object
|
||||
origin*: cstring
|
||||
value*: TGValue
|
||||
|
||||
|
|
@ -1708,7 +1708,7 @@ type
|
|||
GTK_RC_TOKEN_IM_MODULE_FILE, GTK_RC_TOKEN_STOCK, GTK_RC_TOKEN_LTR,
|
||||
GTK_RC_TOKEN_RTL, GTK_RC_TOKEN_LAST
|
||||
PGtkRcProperty* = ptr TGtkRcProperty
|
||||
TGtkRcProperty* = record
|
||||
TGtkRcProperty* {.final.} = object
|
||||
type_name*: TGQuark
|
||||
property_name*: TGQuark
|
||||
origin*: cstring
|
||||
|
|
@ -1877,7 +1877,7 @@ type
|
|||
gtk_reserved3812: proc (){.cdecl.}
|
||||
|
||||
PGtkBorder* = ptr TGtkBorder
|
||||
TGtkBorder* = record
|
||||
TGtkBorder* {.final.} = object
|
||||
left*: gint
|
||||
right*: gint
|
||||
top*: gint
|
||||
|
|
@ -1978,27 +1978,27 @@ type
|
|||
|
||||
PGtkIconSet* = pointer
|
||||
PGtkImagePixmapData* = ptr TGtkImagePixmapData
|
||||
TGtkImagePixmapData* = record
|
||||
TGtkImagePixmapData* {.final.} = object
|
||||
pixmap*: PGdkPixmap
|
||||
|
||||
PGtkImageImageData* = ptr TGtkImageImageData
|
||||
TGtkImageImageData* = record
|
||||
TGtkImageImageData* {.final.} = object
|
||||
image*: PGdkImage
|
||||
|
||||
PGtkImagePixbufData* = ptr TGtkImagePixbufData
|
||||
TGtkImagePixbufData* = record
|
||||
TGtkImagePixbufData* {.final.} = object
|
||||
pixbuf*: PGdkPixbuf
|
||||
|
||||
PGtkImageStockData* = ptr TGtkImageStockData
|
||||
TGtkImageStockData* = record
|
||||
TGtkImageStockData* {.final.} = object
|
||||
stock_id*: cstring
|
||||
|
||||
PGtkImageIconSetData* = ptr TGtkImageIconSetData
|
||||
TGtkImageIconSetData* = record
|
||||
TGtkImageIconSetData* {.final.} = object
|
||||
icon_set*: PGtkIconSet
|
||||
|
||||
PGtkImageAnimationData* = ptr TGtkImageAnimationData
|
||||
TGtkImageAnimationData* = record
|
||||
TGtkImageAnimationData* {.final.} = object
|
||||
anim*: PGdkPixbufAnimation
|
||||
iter*: PGdkPixbufAnimationIter
|
||||
frame_timeout*: guint
|
||||
|
|
@ -2111,7 +2111,7 @@ type
|
|||
gtk_reserved474: proc (){.cdecl.}
|
||||
|
||||
PGtkItemFactoryEntry* = ptr TGtkItemFactoryEntry
|
||||
TGtkItemFactoryEntry* = record
|
||||
TGtkItemFactoryEntry* {.final.} = object
|
||||
path*: cstring
|
||||
accelerator*: cstring
|
||||
callback*: TGtkItemFactoryCallback
|
||||
|
|
@ -2120,7 +2120,7 @@ type
|
|||
extra_data*: gconstpointer
|
||||
|
||||
PGtkItemFactoryItem* = ptr TGtkItemFactoryItem
|
||||
TGtkItemFactoryItem* = record
|
||||
TGtkItemFactoryItem* {.final.} = object
|
||||
path*: cstring
|
||||
widgets*: PGSList
|
||||
|
||||
|
|
@ -2173,7 +2173,7 @@ type
|
|||
cdecl.}
|
||||
PGtkTreeModelFlags* = ptr TGtkTreeModelFlags
|
||||
TGtkTreeModelFlags* = int32
|
||||
TGtkTreeIter* = record
|
||||
TGtkTreeIter* {.final.} = object
|
||||
stamp*: gint
|
||||
user_data*: gpointer
|
||||
user_data2*: gpointer
|
||||
|
|
@ -2435,12 +2435,12 @@ type
|
|||
GtkPreview_flag0*: guint16
|
||||
|
||||
PGtkPreviewInfo* = ptr TGtkPreviewInfo
|
||||
TGtkPreviewInfo* = record
|
||||
TGtkPreviewInfo* {.final.} = object
|
||||
lookup*: Pguchar
|
||||
gamma*: gdouble
|
||||
|
||||
PGtkDitherInfo* = ptr TGtkDitherInfo
|
||||
TGtkDitherInfo* = record
|
||||
TGtkDitherInfo* {.final.} = object
|
||||
c*: array[0..3, guchar]
|
||||
|
||||
PGtkPreviewClass* = ptr TGtkPreviewClass
|
||||
|
|
@ -2533,7 +2533,7 @@ type
|
|||
gtk_reserved603: proc (){.cdecl.}
|
||||
gtk_reserved604: proc (){.cdecl.}
|
||||
|
||||
TGtkSelectionData* = record
|
||||
TGtkSelectionData* {.final.} = object
|
||||
selection*: TGdkAtom
|
||||
target*: TGdkAtom
|
||||
thetype*: TGdkAtom
|
||||
|
|
@ -2543,18 +2543,18 @@ type
|
|||
display*: PGdkDisplay
|
||||
|
||||
PGtkTargetEntry* = ptr TGtkTargetEntry
|
||||
TGtkTargetEntry* = record
|
||||
TGtkTargetEntry* {.final.} = object
|
||||
target*: cstring
|
||||
flags*: guint
|
||||
info*: guint
|
||||
|
||||
PGtkTargetList* = ptr TGtkTargetList
|
||||
TGtkTargetList* = record
|
||||
TGtkTargetList* {.final.} = object
|
||||
list*: PGList
|
||||
ref_count*: guint
|
||||
|
||||
PGtkTargetPair* = ptr TGtkTargetPair
|
||||
TGtkTargetPair* = record
|
||||
TGtkTargetPair* {.final.} = object
|
||||
target*: TGdkAtom
|
||||
flags*: guint
|
||||
info*: guint
|
||||
|
|
@ -2635,7 +2635,7 @@ type
|
|||
gtk_reserved634: proc (){.cdecl.}
|
||||
|
||||
PGtkStockItem* = ptr TGtkStockItem
|
||||
TGtkStockItem* = record
|
||||
TGtkStockItem* {.final.} = object
|
||||
stock_id*: cstring
|
||||
label*: cstring
|
||||
modifier*: TGdkModifierType
|
||||
|
|
@ -2681,7 +2681,7 @@ type
|
|||
TGtkTableClass* = object of TGtkContainerClass
|
||||
|
||||
PGtkTableChild* = ptr TGtkTableChild
|
||||
TGtkTableChild* = record
|
||||
TGtkTableChild* {.final.} = object
|
||||
widget*: PGtkWidget
|
||||
left_attach*: guint16
|
||||
right_attach*: guint16
|
||||
|
|
@ -2691,7 +2691,7 @@ type
|
|||
ypadding*: guint16
|
||||
GtkTableChild_flag0*: guint16
|
||||
|
||||
TGtkTableRowCol* = record
|
||||
TGtkTableRowCol* {.final.} = object
|
||||
requisition*: guint16
|
||||
allocation*: guint16
|
||||
spacing*: guint16
|
||||
|
|
@ -2710,7 +2710,7 @@ type
|
|||
|
||||
PGtkTextFont* = pointer
|
||||
PGtkPropertyMark* = ptr TGtkPropertyMark
|
||||
TGtkPropertyMark* = record
|
||||
TGtkPropertyMark* {.final.} = object
|
||||
`property`*: PGList
|
||||
offset*: guint
|
||||
index*: guint
|
||||
|
|
@ -2764,7 +2764,7 @@ type
|
|||
PGtkTextSearchFlags* = ptr TGtkTextSearchFlags
|
||||
TGtkTextSearchFlags* = int32
|
||||
PGtkTextIter* = ptr TGtkTextIter
|
||||
TGtkTextIter* = record
|
||||
TGtkTextIter* {.final.} = object
|
||||
dummy1*: gpointer
|
||||
dummy2*: gpointer
|
||||
dummy3*: gint
|
||||
|
|
@ -2802,7 +2802,7 @@ type
|
|||
gtk_reserved664: proc (){.cdecl.}
|
||||
|
||||
PGtkTextAppearance* = ptr TGtkTextAppearance
|
||||
TGtkTextAppearance* = record
|
||||
TGtkTextAppearance* {.final.} = object
|
||||
bg_color*: TGdkColor
|
||||
fg_color*: TGdkColor
|
||||
bg_stipple*: PGdkBitmap
|
||||
|
|
@ -2811,7 +2811,7 @@ type
|
|||
padding1*: gpointer
|
||||
flag0*: guint16
|
||||
|
||||
TGtkTextAttributes* = record
|
||||
TGtkTextAttributes* {.final.} = object
|
||||
refcount*: guint
|
||||
appearance*: TGtkTextAppearance
|
||||
justification*: TGtkJustification
|
||||
|
|
@ -2860,7 +2860,7 @@ type
|
|||
gtk_reserved4: proc (){.cdecl.}
|
||||
|
||||
PGtkTextMarkBody* = ptr TGtkTextMarkBody
|
||||
TGtkTextMarkBody* = record
|
||||
TGtkTextMarkBody* {.final.} = object
|
||||
obj*: PGtkTextMark
|
||||
name*: cstring
|
||||
tree*: PGtkTextBTree
|
||||
|
|
@ -2879,11 +2879,11 @@ type
|
|||
gtk_reserved4: proc (){.cdecl.}
|
||||
|
||||
PGtkTextPixbuf* = ptr TGtkTextPixbuf
|
||||
TGtkTextPixbuf* = record
|
||||
TGtkTextPixbuf* {.final.} = object
|
||||
pixbuf*: PGdkPixbuf
|
||||
|
||||
PGtkTextChildBody* = ptr TGtkTextChildBody
|
||||
TGtkTextChildBody* = record
|
||||
TGtkTextChildBody* {.final.} = object
|
||||
obj*: PGtkTextChildAnchor
|
||||
widgets*: PGSList
|
||||
tree*: PGtkTextBTree
|
||||
|
|
@ -2892,17 +2892,17 @@ type
|
|||
PGtkTextLineSegment* = ptr TGtkTextLineSegment
|
||||
PGtkTextLineSegmentClass* = ptr TGtkTextLineSegmentClass
|
||||
PGtkTextTagInfo* = ptr TGtkTextTagInfo
|
||||
TGtkTextTagInfo* = record
|
||||
TGtkTextTagInfo* {.final.} = object
|
||||
tag*: PGtkTextTag
|
||||
tag_root*: PGtkTextBTreeNode
|
||||
toggle_count*: gint
|
||||
|
||||
PGtkTextToggleBody* = ptr TGtkTextToggleBody
|
||||
TGtkTextToggleBody* = record
|
||||
TGtkTextToggleBody* {.final.} = object
|
||||
info*: PGtkTextTagInfo
|
||||
inNodeCounts*: gboolean
|
||||
|
||||
TGtkTextLineSegment* = record
|
||||
TGtkTextLineSegment* {.final.} = object
|
||||
`type`*: PGtkTextLineSegmentClass
|
||||
next*: PGtkTextLineSegment
|
||||
char_count*: int32
|
||||
|
|
@ -2919,7 +2919,7 @@ type
|
|||
line: PGtkTextLine){.cdecl.}
|
||||
TGtkTextSegCheckFunc* = proc (seg: PGtkTextLineSegment, line: PGtkTextLine){.
|
||||
cdecl.}
|
||||
TGtkTextLineSegmentClass* = record
|
||||
TGtkTextLineSegmentClass* {.final.} = object
|
||||
name*: cstring
|
||||
leftGravity*: gboolean
|
||||
splitFunc*: TGtkTextSegSplitFunc
|
||||
|
|
@ -2929,13 +2929,13 @@ type
|
|||
checkFunc*: TGtkTextSegCheckFunc
|
||||
|
||||
PGtkTextLineData* = ptr TGtkTextLineData
|
||||
TGtkTextLineData* = record
|
||||
TGtkTextLineData* {.final.} = object
|
||||
view_id*: gpointer
|
||||
next*: PGtkTextLineData
|
||||
height*: gint
|
||||
flag0*: int32
|
||||
|
||||
TGtkTextLine* = record
|
||||
TGtkTextLine* {.final.} = object
|
||||
parent*: PGtkTextBTreeNode
|
||||
next*: PGtkTextLine
|
||||
segments*: PGtkTextLineSegment
|
||||
|
|
@ -3020,18 +3020,18 @@ type
|
|||
gtk_reserved4: proc (){.cdecl.}
|
||||
|
||||
PGtkTextAttrAppearance* = ptr TGtkTextAttrAppearance
|
||||
TGtkTextAttrAppearance* = record
|
||||
TGtkTextAttrAppearance* {.final.} = object
|
||||
attr*: TPangoAttribute
|
||||
appearance*: TGtkTextAppearance
|
||||
|
||||
PGtkTextCursorDisplay* = ptr TGtkTextCursorDisplay
|
||||
TGtkTextCursorDisplay* = record
|
||||
TGtkTextCursorDisplay* {.final.} = object
|
||||
x*: gint
|
||||
y*: gint
|
||||
height*: gint
|
||||
flag0*: guint16
|
||||
|
||||
TGtkTextLineDisplay* = record
|
||||
TGtkTextLineDisplay* {.final.} = object
|
||||
layout*: PPangoLayout
|
||||
cursors*: PGSList
|
||||
shaped_objects*: PGSList
|
||||
|
|
@ -3152,7 +3152,7 @@ type
|
|||
|
||||
PGtkTooltips* = ptr TGtkTooltips
|
||||
PGtkTooltipsData* = ptr TGtkTooltipsData
|
||||
TGtkTooltipsData* = record
|
||||
TGtkTooltipsData* {.final.} = object
|
||||
tooltips*: PGtkTooltips
|
||||
widget*: PGtkWidget
|
||||
tip_text*: cstring
|
||||
|
|
@ -3184,7 +3184,7 @@ type
|
|||
TGtkToolbarSpaceStyle* = enum
|
||||
GTK_TOOLBAR_SPACE_EMPTY, GTK_TOOLBAR_SPACE_LINE
|
||||
PGtkToolbarChild* = ptr TGtkToolbarChild
|
||||
TGtkToolbarChild* = record
|
||||
TGtkToolbarChild* {.final.} = object
|
||||
`type`*: TGtkToolbarChildType
|
||||
widget*: PGtkWidget
|
||||
icon*: PGtkWidget
|
||||
|
|
@ -3365,13 +3365,13 @@ type
|
|||
PGtkRBNode* = ptr TGtkRBNode
|
||||
TGtkRBTreeTraverseFunc* = proc (tree: PGtkRBTree, node: PGtkRBNode,
|
||||
data: gpointer){.cdecl.}
|
||||
TGtkRBTree* = record
|
||||
TGtkRBTree* {.final.} = object
|
||||
root*: PGtkRBNode
|
||||
`nil`*: PGtkRBNode
|
||||
parent_tree*: PGtkRBTree
|
||||
parent_node*: PGtkRBNode
|
||||
|
||||
TGtkRBNode* = record
|
||||
TGtkRBNode* {.final.} = object
|
||||
flag0*: guint16
|
||||
left*: PGtkRBNode
|
||||
right*: PGtkRBNode
|
||||
|
|
@ -3386,14 +3386,14 @@ type
|
|||
TGtkTreeViewSearchDialogPositionFunc* = proc (tree_view: PGtkTreeView,
|
||||
search_dialog: PGtkWidget){.cdecl.}
|
||||
PGtkTreeViewColumnReorder* = ptr TGtkTreeViewColumnReorder
|
||||
TGtkTreeViewColumnReorder* = record
|
||||
TGtkTreeViewColumnReorder* {.final.} = object
|
||||
left_align*: gint
|
||||
right_align*: gint
|
||||
left_column*: PGtkTreeViewColumn
|
||||
right_column*: PGtkTreeViewColumn
|
||||
|
||||
PGtkTreeViewPrivate* = ptr TGtkTreeViewPrivate
|
||||
TGtkTreeViewPrivate* = record
|
||||
TGtkTreeViewPrivate* {.final.} = object
|
||||
model*: PGtkTreeModel
|
||||
flags*: guint
|
||||
tree*: PGtkRBTree
|
||||
|
|
@ -11304,96 +11304,127 @@ proc GTK_FUNDAMENTAL_TYPE*(thetype: GType): GType =
|
|||
result = G_TYPE_FUNDAMENTAL(thetype)
|
||||
|
||||
proc GTK_VALUE_CHAR*(a: TGtkArg): gchar =
|
||||
var a = a
|
||||
Result = cast[ptr gchar](addr(a.d))^
|
||||
|
||||
proc GTK_VALUE_UCHAR*(a: TGtkArg): guchar =
|
||||
var a = a
|
||||
Result = cast[ptr guchar](addr(a.d))^
|
||||
|
||||
proc GTK_VALUE_BOOL*(a: TGtkArg): gboolean =
|
||||
var a = a
|
||||
Result = cast[ptr gboolean](addr(a.d))^
|
||||
|
||||
proc GTK_VALUE_INT*(a: TGtkArg): gint =
|
||||
var a = a
|
||||
Result = cast[ptr gint](addr(a.d))^
|
||||
|
||||
proc GTK_VALUE_UINT*(a: TGtkArg): guint =
|
||||
var a = a
|
||||
Result = cast[ptr guint](addr(a.d))^
|
||||
|
||||
proc GTK_VALUE_LONG*(a: TGtkArg): glong =
|
||||
var a = a
|
||||
Result = cast[ptr glong](addr(a.d))^
|
||||
|
||||
proc GTK_VALUE_ULONG*(a: TGtkArg): gulong =
|
||||
var a = a
|
||||
Result = cast[ptr gulong](addr(a.d))^
|
||||
|
||||
proc GTK_VALUE_FLOAT*(a: TGtkArg): gfloat =
|
||||
var a = a
|
||||
Result = cast[ptr gfloat](addr(a.d))^
|
||||
|
||||
proc GTK_VALUE_DOUBLE*(a: TGtkArg): gdouble =
|
||||
var a = a
|
||||
Result = cast[ptr gdouble](addr(a.d))^
|
||||
|
||||
proc GTK_VALUE_STRING*(a: TGtkArg): cstring =
|
||||
var a = a
|
||||
Result = cast[ptr cstring](addr(a.d))^
|
||||
|
||||
proc GTK_VALUE_ENUM*(a: TGtkArg): gint =
|
||||
var a = a
|
||||
Result = cast[ptr gint](addr(a.d))^
|
||||
|
||||
proc GTK_VALUE_FLAGS*(a: TGtkArg): guint =
|
||||
var a = a
|
||||
Result = cast[ptr guint](addr(a.d))^
|
||||
|
||||
proc GTK_VALUE_BOXED*(a: TGtkArg): gpointer =
|
||||
var a = a
|
||||
Result = cast[ptr gpointer](addr(a.d))^
|
||||
|
||||
proc GTK_VALUE_OBJECT*(a: TGtkArg): PGtkObject =
|
||||
var a = a
|
||||
Result = cast[ptr PGtkObject](addr(a.d))^
|
||||
|
||||
proc GTK_VALUE_POINTER*(a: TGtkArg): GPointer =
|
||||
var a = a
|
||||
Result = cast[ptr gpointer](addr(a.d))^
|
||||
|
||||
proc GTK_VALUE_SIGNAL*(a: TGtkArg): TGtkArgSignalData =
|
||||
var a = a
|
||||
Result = cast[ptr TGtkArgSignalData](addr(a.d))^
|
||||
|
||||
proc GTK_RETLOC_CHAR*(a: TGtkArg): cstring =
|
||||
var a = a
|
||||
Result = cast[ptr cstring](addr(a.d))^
|
||||
|
||||
proc GTK_RETLOC_UCHAR*(a: TGtkArg): Pguchar =
|
||||
var a = a
|
||||
Result = cast[ptr pguchar](addr(a.d))^
|
||||
|
||||
proc GTK_RETLOC_BOOL*(a: TGtkArg): Pgboolean =
|
||||
var a = a
|
||||
Result = cast[ptr pgboolean](addr(a.d))^
|
||||
|
||||
proc GTK_RETLOC_INT*(a: TGtkArg): Pgint =
|
||||
var a = a
|
||||
Result = cast[ptr pgint](addr(a.d))^
|
||||
|
||||
proc GTK_RETLOC_UINT*(a: TGtkArg): Pguint =
|
||||
var a = a
|
||||
Result = cast[ptr pguint](addr(a.d))^
|
||||
|
||||
proc GTK_RETLOC_LONG*(a: TGtkArg): Pglong =
|
||||
var a = a
|
||||
Result = cast[ptr pglong](addr(a.d))^
|
||||
|
||||
proc GTK_RETLOC_ULONG*(a: TGtkArg): Pgulong =
|
||||
var a = a
|
||||
Result = cast[ptr pgulong](addr(a.d))^
|
||||
|
||||
proc GTK_RETLOC_FLOAT*(a: TGtkArg): Pgfloat =
|
||||
var a = a
|
||||
Result = cast[ptr pgfloat](addr(a.d))^
|
||||
|
||||
proc GTK_RETLOC_DOUBLE*(a: TGtkArg): Pgdouble =
|
||||
var a = a
|
||||
Result = cast[ptr pgdouble](addr(a.d))^
|
||||
|
||||
proc GTK_RETLOC_STRING*(a: TGtkArg): Ppgchar =
|
||||
var a = a
|
||||
Result = cast[ptr Ppgchar](addr(a.d))^
|
||||
|
||||
proc GTK_RETLOC_ENUM*(a: TGtkArg): Pgint =
|
||||
var a = a
|
||||
Result = cast[ptr Pgint](addr(a.d))^
|
||||
|
||||
proc GTK_RETLOC_FLAGS*(a: TGtkArg): Pguint =
|
||||
var a = a
|
||||
Result = cast[ptr pguint](addr(a.d))^
|
||||
|
||||
proc GTK_RETLOC_BOXED*(a: TGtkArg): Pgpointer =
|
||||
var a = a
|
||||
Result = cast[ptr pgpointer](addr(a.d))^
|
||||
|
||||
proc GTK_RETLOC_OBJECT*(a: TGtkArg): PPGtkObject =
|
||||
var a = a
|
||||
Result = cast[ptr ppgtkobject](addr(a.d))^
|
||||
|
||||
proc GTK_RETLOC_POINTER*(a: TGtkArg): Pgpointer =
|
||||
var a = a
|
||||
Result = cast[ptr pgpointer](addr(a.d))^
|
||||
|
||||
proc GTK_TYPE_WIDGET*(): GType =
|
||||
|
|
@ -15108,7 +15139,7 @@ proc gtk_signal_handler_pending_by_func*(anObject: PGtkObject, signal_id: guint,
|
|||
G_SIGNAL_MATCH_DATA)
|
||||
if not may_be_blocked:
|
||||
t = t or cast[int](G_SIGNAL_MATCH_UNBLOCKED)
|
||||
Result = g_signal_handler_find(anObject, t, signal_id, 0, nil, addr(func_),
|
||||
Result = g_signal_handler_find(anObject, t, signal_id, 0, nil, func_,
|
||||
data) != 0
|
||||
|
||||
proc GTK_TYPE_SIZE_GROUP*(): GType =
|
||||
|
|
@ -17045,7 +17076,7 @@ type
|
|||
GTK_FILE_FILTER_FILENAME = 1 shl 0, GTK_FILE_FILTER_URI = 1 shl 1,
|
||||
GTK_FILE_FILTER_DISPLAY_NAME = 1 shl 2, GTK_FILE_FILTER_MIME_TYPE = 1 shl 3
|
||||
PGtkFileFilterInfo* = ref TGtkFileFilterInfo
|
||||
TGtkFileFilterInfo* = record
|
||||
TGtkFileFilterInfo* {.final.} = object
|
||||
contains*: TGtkFileFilterFlags
|
||||
filename*: cstring
|
||||
uri*: cstring
|
||||
|
|
|
|||
|
|
@ -68,12 +68,12 @@ type
|
|||
exc: PDomException): PDomString{.cdecl.}
|
||||
|
||||
PDomDocument* = ptr TDomDocument
|
||||
TDomDocument* = record
|
||||
TDomDocument* {.final.} = object
|
||||
parent*: PDomNode
|
||||
iterators*: PGSList
|
||||
|
||||
PDomDocumentClass* = ptr TDomDocumentClass
|
||||
TDomDocumentClass* = record
|
||||
TDomDocumentClass* {.final.} = object
|
||||
parent_class*: PDomNodeClass
|
||||
|
||||
PHtmlFocusIterator* = ptr THtmlFocusIterator
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ type
|
|||
PPangoGlyph* = ptr TPangoGlyph
|
||||
TPangoGlyph* = guint32
|
||||
PPangoRectangle* = ptr TPangoRectangle
|
||||
TPangoRectangle* = record
|
||||
TPangoRectangle* {.final.} = object
|
||||
x*: int32
|
||||
y*: int32
|
||||
width*: int32
|
||||
|
|
@ -61,7 +61,7 @@ type
|
|||
PANGO_DIRECTION_LTR, PANGO_DIRECTION_RTL, PANGO_DIRECTION_TTB_LTR,
|
||||
PANGO_DIRECTION_TTB_RTL
|
||||
PPangoColor* = ptr TPangoColor
|
||||
TPangoColor* = record
|
||||
TPangoColor* {.final.} = object
|
||||
red*: guint16
|
||||
green*: guint16
|
||||
blue*: guint16
|
||||
|
|
@ -72,12 +72,12 @@ type
|
|||
TPangoUnderline* = int32
|
||||
PPangoAttribute* = ptr TPangoAttribute
|
||||
PPangoAttrClass* = ptr TPangoAttrClass
|
||||
TPangoAttribute* = record
|
||||
TPangoAttribute* {.final.} = object
|
||||
klass*: PPangoAttrClass
|
||||
start_index*: int
|
||||
end_index*: int
|
||||
|
||||
TPangoAttrClass* = record
|
||||
TPangoAttrClass* {.final.} = object
|
||||
`type`*: TPangoAttrType
|
||||
copy*: proc (attr: PPangoAttribute): PPangoAttribute{.cdecl.}
|
||||
destroy*: proc (attr: PPangoAttribute){.cdecl.}
|
||||
|
|
@ -85,43 +85,43 @@ type
|
|||
cdecl.}
|
||||
|
||||
PPangoAttrString* = ptr TPangoAttrString
|
||||
TPangoAttrString* = record
|
||||
TPangoAttrString* {.final.} = object
|
||||
attr*: TPangoAttribute
|
||||
value*: cstring
|
||||
|
||||
PPangoAttrLanguage* = ptr TPangoAttrLanguage
|
||||
TPangoAttrLanguage* = record
|
||||
TPangoAttrLanguage* {.final.} = object
|
||||
attr*: TPangoAttribute
|
||||
value*: PPangoLanguage
|
||||
|
||||
PPangoAttrInt* = ptr TPangoAttrInt
|
||||
TPangoAttrInt* = record
|
||||
TPangoAttrInt* {.final.} = object
|
||||
attr*: TPangoAttribute
|
||||
value*: int32
|
||||
|
||||
PPangoAttrFloat* = ptr TPangoAttrFloat
|
||||
TPangoAttrFloat* = record
|
||||
TPangoAttrFloat* {.final.} = object
|
||||
attr*: TPangoAttribute
|
||||
value*: gdouble
|
||||
|
||||
PPangoAttrColor* = ptr TPangoAttrColor
|
||||
TPangoAttrColor* = record
|
||||
TPangoAttrColor* {.final.} = object
|
||||
attr*: TPangoAttribute
|
||||
color*: TPangoColor
|
||||
|
||||
PPangoAttrShape* = ptr TPangoAttrShape
|
||||
TPangoAttrShape* = record
|
||||
TPangoAttrShape* {.final.} = object
|
||||
attr*: TPangoAttribute
|
||||
ink_rect*: TPangoRectangle
|
||||
logical_rect*: TPangoRectangle
|
||||
|
||||
PPangoAttrFontDesc* = ptr TPangoAttrFontDesc
|
||||
TPangoAttrFontDesc* = record
|
||||
TPangoAttrFontDesc* {.final.} = object
|
||||
attr*: TPangoAttribute
|
||||
desc*: PPangoFontDescription
|
||||
|
||||
PPangoLogAttr* = ptr TPangoLogAttr
|
||||
TPangoLogAttr* = record
|
||||
TPangoLogAttr* {.final.} = object
|
||||
flag0*: guint16
|
||||
|
||||
PPangoCoverageLevel* = ptr TPangoCoverageLevel
|
||||
|
|
@ -129,25 +129,25 @@ type
|
|||
PANGO_COVERAGE_NONE, PANGO_COVERAGE_FALLBACK, PANGO_COVERAGE_APPROXIMATE,
|
||||
PANGO_COVERAGE_EXACT
|
||||
PPangoBlockInfo* = ptr TPangoBlockInfo
|
||||
TPangoBlockInfo* = record
|
||||
TPangoBlockInfo* {.final.} = object
|
||||
data*: Pguchar
|
||||
level*: TPangoCoverageLevel
|
||||
|
||||
PPangoCoverage* = ptr TPangoCoverage
|
||||
TPangoCoverage* = record
|
||||
TPangoCoverage* {.final.} = object
|
||||
ref_count*: int
|
||||
n_blocks*: int32
|
||||
data_size*: int32
|
||||
blocks*: PPangoBlockInfo
|
||||
|
||||
PPangoEngineRange* = ptr TPangoEngineRange
|
||||
TPangoEngineRange* = record
|
||||
TPangoEngineRange* {.final.} = object
|
||||
start*: int32
|
||||
theEnd*: int32
|
||||
langs*: cstring
|
||||
|
||||
PPangoEngineInfo* = ptr TPangoEngineInfo
|
||||
TPangoEngineInfo* = record
|
||||
TPangoEngineInfo* {.final.} = object
|
||||
id*: cstring
|
||||
engine_type*: cstring
|
||||
render_type*: cstring
|
||||
|
|
@ -155,7 +155,7 @@ type
|
|||
n_ranges*: gint
|
||||
|
||||
PPangoEngine* = ptr TPangoEngine
|
||||
TPangoEngine* = record
|
||||
TPangoEngine* {.final.} = object
|
||||
id*: cstring
|
||||
`type`*: cstring
|
||||
length*: gint
|
||||
|
|
@ -165,7 +165,7 @@ type
|
|||
attrs: PPangoLogAttr, attrs_len: int32){.
|
||||
cdecl.}
|
||||
PPangoEngineLang* = ptr TPangoEngineLang
|
||||
TPangoEngineLang* = record
|
||||
TPangoEngineLang* {.final.} = object
|
||||
engine*: TPangoEngine
|
||||
script_break*: TPangoEngineLangScriptBreak
|
||||
|
||||
|
|
@ -176,7 +176,7 @@ type
|
|||
language: PPangoLanguage): PPangoCoverage{.
|
||||
cdecl.}
|
||||
PPangoEngineShape* = ptr TPangoEngineShape
|
||||
TPangoEngineShape* = record
|
||||
TPangoEngineShape* {.final.} = object
|
||||
engine*: TPangoEngine
|
||||
script_shape*: TPangoEngineShapeScript
|
||||
get_coverage*: TPangoEngineShapeGetCoverage
|
||||
|
|
@ -194,28 +194,28 @@ type
|
|||
PPangoGlyphUnit* = ptr TPangoGlyphUnit
|
||||
TPangoGlyphUnit* = gint32
|
||||
PPangoGlyphGeometry* = ptr TPangoGlyphGeometry
|
||||
TPangoGlyphGeometry* = record
|
||||
TPangoGlyphGeometry* {.final.} = object
|
||||
width*: TPangoGlyphUnit
|
||||
x_offset*: TPangoGlyphUnit
|
||||
y_offset*: TPangoGlyphUnit
|
||||
|
||||
PPangoGlyphVisAttr* = ptr TPangoGlyphVisAttr
|
||||
TPangoGlyphVisAttr* = record
|
||||
TPangoGlyphVisAttr* {.final.} = object
|
||||
flag0*: int16
|
||||
|
||||
PPangoGlyphInfo* = ptr TPangoGlyphInfo
|
||||
TPangoGlyphInfo* = record
|
||||
TPangoGlyphInfo* {.final.} = object
|
||||
glyph*: TPangoGlyph
|
||||
geometry*: TPangoGlyphGeometry
|
||||
attr*: TPangoGlyphVisAttr
|
||||
|
||||
TPangoGlyphString* = record
|
||||
TPangoGlyphString* {.final.} = object
|
||||
num_glyphs*: gint
|
||||
glyphs*: PPangoGlyphInfo
|
||||
log_clusters*: Pgint
|
||||
space*: gint
|
||||
|
||||
TPangoAnalysis* = record
|
||||
TPangoAnalysis* {.final.} = object
|
||||
shape_engine*: PPangoEngineShape
|
||||
lang_engine*: PPangoEngineLang
|
||||
font*: PPangoFont
|
||||
|
|
@ -223,7 +223,7 @@ type
|
|||
language*: PPangoLanguage
|
||||
extra_attrs*: PGSList
|
||||
|
||||
TPangoItem* = record
|
||||
TPangoItem* {.final.} = object
|
||||
offset*: gint
|
||||
length*: gint
|
||||
num_chars*: gint
|
||||
|
|
@ -236,14 +236,14 @@ type
|
|||
TPangoWrapMode* = enum
|
||||
PANGO_WRAP_WORD, PANGO_WRAP_CHAR
|
||||
PPangoLayoutLine* = ptr TPangoLayoutLine
|
||||
TPangoLayoutLine* = record
|
||||
TPangoLayoutLine* {.final.} = object
|
||||
layout*: PPangoLayout
|
||||
start_index*: gint
|
||||
length*: gint
|
||||
runs*: PGSList
|
||||
|
||||
PPangoLayoutRun* = ptr TPangoLayoutRun
|
||||
TPangoLayoutRun* = record
|
||||
TPangoLayoutRun* {.final.} = object
|
||||
item*: PPangoItem
|
||||
glyphs*: PPangoGlyphString
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ type
|
|||
regMN,
|
||||
regNewline
|
||||
|
||||
TRegex = record
|
||||
TRegex = object of TObject
|
||||
case kind: TRegexKind
|
||||
of regChar: c: char
|
||||
of regSet: s: ref set[char]
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ type
|
|||
# Data passed back in callouts
|
||||
# Const before type ignored
|
||||
# Pointer to character tables
|
||||
Tpcre_extra* = record
|
||||
Tpcre_extra* {.final.} = object
|
||||
flags: cuint
|
||||
study_data: pointer
|
||||
match_limit: cuint
|
||||
|
|
@ -189,7 +189,7 @@ type
|
|||
# Offset to next item in the pattern
|
||||
# Length of next item in the pattern
|
||||
# ------------------------------------------------------------------
|
||||
TPcre_callout_block* = record
|
||||
TPcre_callout_block* {.final.} = object
|
||||
version: cint
|
||||
callout_number: cint
|
||||
offset_vector: ptr cint
|
||||
|
|
|
|||
|
|
@ -19,10 +19,8 @@ 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
|
||||
TComplex* = tuple[re, im: float]
|
||||
## a complex number, consisting of a real and an imaginary part
|
||||
|
||||
proc `==` *(x, y: TComplex): bool =
|
||||
## Compare two complex numbers `x` and `y` for equality.
|
||||
|
|
|
|||
|
|
@ -25,23 +25,24 @@ type
|
|||
dbQuiting, # debugger wants to quit
|
||||
dbBreakpoints # debugger is only interested in breakpoints
|
||||
|
||||
TDbgBreakpoint = record
|
||||
TDbgBreakpoint {.final.} = object
|
||||
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:
|
||||
TVarSlot {.compilerproc, final.} = object # 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.
|
||||
TExtendedFrame {.final.} = object # 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]
|
||||
|
||||
|
|
@ -69,7 +70,7 @@ proc findBreakpoint(name: string): int =
|
|||
return -1
|
||||
|
||||
proc ListBreakPoints() =
|
||||
write(stdout, "*** emdb| Breakpoints:\n")
|
||||
write(stdout, "*** endb| Breakpoints:\n")
|
||||
for i in 0 .. dbgBPlen-1:
|
||||
write(stdout, dbgBP[i].name & ": " & $abs(dbgBP[i].low) & ".." &
|
||||
$abs(dbgBP[i].high) & dbgBP[i].filename)
|
||||
|
|
@ -101,13 +102,13 @@ proc writeVariable(stream: TFile, slot: TVarSlot) =
|
|||
writeln(stream, dbgRepr(slot.address, slot.typ))
|
||||
|
||||
proc ListFrame(stream: TFile, f: PExtendedFrame) =
|
||||
write(stream, "*** emdb| Frame (" & $f.f.len & " slots):\n")
|
||||
write(stream, "*** endb| 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")
|
||||
write(stream, "*** endb| Frame (" & $f.f.len & " slots):\n")
|
||||
for i in 0 .. f.f.len-1:
|
||||
writeln(stream, f.slots[i].name)
|
||||
write(stream, "***\n")
|
||||
|
|
@ -115,7 +116,7 @@ proc ListVariables(stream: TFile, f: PExtendedFrame) =
|
|||
proc debugOut(msg: cstring) =
|
||||
# the *** *** markers are for easy recognition of debugger
|
||||
# output for external frontends.
|
||||
write(stdout, "*** emdb| ")
|
||||
write(stdout, "*** endb| ")
|
||||
write(stdout, msg)
|
||||
write(stdout, "***\n")
|
||||
|
||||
|
|
@ -131,14 +132,14 @@ proc findVariable(frame: PExtendedFrame, varname: cstring): int =
|
|||
|
||||
proc dbgShowCurrentProc(dbgFramePointer: PFrame) =
|
||||
if dbgFramePointer != nil:
|
||||
write(stdout, "*** emdb| now in proc: ")
|
||||
write(stdout, "*** endb| now in proc: ")
|
||||
write(stdout, dbgFramePointer.procname)
|
||||
write(stdout, " ***\n")
|
||||
else:
|
||||
write(stdout, "*** emdb| (procedure name not available) ***\n")
|
||||
write(stdout, "*** endb| (procedure name not available) ***\n")
|
||||
|
||||
proc dbgShowExecutionPoint() =
|
||||
write(stdout, "*** emdb| " & $framePtr.filename & "(" & $framePtr.line &
|
||||
write(stdout, "*** endb| " & $framePtr.filename & "(" & $framePtr.line &
|
||||
") " & $framePtr.procname & " ***\n")
|
||||
|
||||
when defined(windows) or defined(dos) or defined(os2):
|
||||
|
|
@ -219,26 +220,26 @@ 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
|
||||
s, step single step, stepping into routine calls
|
||||
n, next 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]
|
||||
b, break <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>
|
||||
e, eval <expr> evaluate the expression <expr>
|
||||
o, out <file> <expr> evaluate <expr> 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
|
||||
bt, backtrace 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
|
||||
|
|
@ -352,7 +353,7 @@ proc CommandPrompt() =
|
|||
dbgDown: int = 0 # how often we did go down
|
||||
|
||||
while again:
|
||||
write(stdout, "*** emdb| >>")
|
||||
write(stdout, "*** endb| >>")
|
||||
var tmp = readLine(stdin)
|
||||
if tmp.len > 0: dbgUser = tmp
|
||||
# now look what we have to do:
|
||||
|
|
@ -360,10 +361,10 @@ proc CommandPrompt() =
|
|||
var i = scanWord(dbgUser, dbgTemp, 0)
|
||||
case dbgTemp
|
||||
of "": InvalidCommand()
|
||||
of "s", "stepinto":
|
||||
of "s", "step":
|
||||
dbgState = dbStepInto
|
||||
again = false
|
||||
of "n", "stepover":
|
||||
of "n", "next":
|
||||
dbgState = dbStepOver
|
||||
dbgSkipToFrame = framePtr
|
||||
again = false
|
||||
|
|
@ -412,9 +413,9 @@ proc CommandPrompt() =
|
|||
dbgShowCurrentProc(dbgFramePtr)
|
||||
else:
|
||||
debugOut("[Warning] cannot go down any further ")
|
||||
of "callstack":
|
||||
of "bt", "backtrace":
|
||||
WriteStackTrace()
|
||||
of "b", "setbreak":
|
||||
of "b", "break":
|
||||
setBreakPoint(dbgUser, i)
|
||||
of "breakpoints":
|
||||
ListBreakPoints()
|
||||
|
|
@ -443,7 +444,7 @@ proc endbStep() =
|
|||
proc checkForBreakpoint() =
|
||||
var i = dbgBreakpointReached(framePtr.line)
|
||||
if i >= 0:
|
||||
write(stdout, "*** emdb| reached ")
|
||||
write(stdout, "*** endb| reached ")
|
||||
write(stdout, dbgBP[i].name)
|
||||
write(stdout, " in ")
|
||||
write(stdout, framePtr.filename)
|
||||
|
|
|
|||
10144
lib/dlmalloc.c
10144
lib/dlmalloc.c
File diff suppressed because it is too large
Load diff
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
# (c) Copyright 2008 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
|
|
@ -35,35 +35,34 @@ proc chckNil(p: pointer) {.inline, compilerproc.}
|
|||
|
||||
type
|
||||
PSafePoint = ptr TSafePoint
|
||||
TSafePoint {.compilerproc.} = record
|
||||
TSafePoint {.compilerproc, final.} = object
|
||||
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
|
||||
excHandler {.compilerproc.}: PSafePoint = nil
|
||||
# list of exception handlers
|
||||
# a global variable for the root of all try blocks
|
||||
|
||||
proc reraiseException() =
|
||||
if excHandler != nil:
|
||||
if excHandler == nil:
|
||||
raise newException(ENoExceptionToReraise, "no exception to reraise")
|
||||
else:
|
||||
c_longjmp(excHandler.context, 1)
|
||||
|
||||
type
|
||||
PFrame = ptr TFrame
|
||||
TFrame {.importc, nodecl.} = record
|
||||
TFrame {.importc, nodecl, final.} = object
|
||||
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
|
||||
TTempFrame = tuple[ # used for recursion elimination in WriteStackTrace
|
||||
procname: CString, line: int]
|
||||
|
||||
var
|
||||
buf: string # cannot be allocated on the stack!
|
||||
|
|
@ -71,7 +70,7 @@ var
|
|||
# assert, as it raises an exception and
|
||||
# exception handler needs the buffer too
|
||||
|
||||
framePtr {.exportc, volatile.}: PFrame
|
||||
framePtr {.exportc.}: PFrame
|
||||
|
||||
tempFrames: array [0..255, TTempFrame] # cannot be allocated
|
||||
# on the stack!
|
||||
|
|
@ -82,8 +81,7 @@ proc auxWriteStackTrace(f: PFrame, s: var string) =
|
|||
i = 0
|
||||
total = 0
|
||||
while it != nil and i <= high(tempFrames):
|
||||
tempFrames[i].procname = it.procname
|
||||
tempFrames[i].line = it.line
|
||||
tempFrames[i] = (it.procname, it.line)
|
||||
inc(i)
|
||||
inc(total)
|
||||
it = it.prev
|
||||
|
|
@ -110,10 +108,10 @@ proc rawWriteStackTrace(s: var string) =
|
|||
auxWriteStackTrace(framePtr, s)
|
||||
|
||||
proc quitOrDebug() {.inline.} =
|
||||
when not defined(emdb):
|
||||
when not defined(endb):
|
||||
quit(1)
|
||||
else:
|
||||
emdbStep() # call the debugger
|
||||
endbStep() # 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
|
||||
|
|
@ -122,7 +120,7 @@ proc raiseException(e: ref E_Base, ename: CString) =
|
|||
excHandler.exc = e
|
||||
c_longjmp(excHandler.context, 1)
|
||||
else:
|
||||
if cast[pointer](buf) != nil:
|
||||
if not isNil(buf):
|
||||
setLen(buf, 0)
|
||||
rawWriteStackTrace(buf)
|
||||
if e.msg != nil and e.msg[0] != '\0':
|
||||
|
|
@ -135,9 +133,7 @@ proc raiseException(e: ref E_Base, ename: CString) =
|
|||
add(buf, "]\n")
|
||||
writeToStdErr(buf)
|
||||
else:
|
||||
writeToStdErr("*** FATAL ERROR *** ")
|
||||
writeToStdErr(ename)
|
||||
writeToStdErr("\n")
|
||||
quitOrDebug()
|
||||
GC_enable()
|
||||
|
||||
|
|
@ -147,7 +143,8 @@ var
|
|||
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
|
||||
if not isNil(assertBuf):
|
||||
# BUGFIX: when debugging the GC, assertBuf may be nil
|
||||
setLen(assertBuf, 0)
|
||||
add(assertBuf, "[Assertion failure] file: ")
|
||||
add(assertBuf, file)
|
||||
|
|
@ -164,6 +161,11 @@ proc WriteStackTrace() =
|
|||
rawWriteStackTrace(s)
|
||||
writeToStdErr(s)
|
||||
|
||||
#proc stackTraceWrapper {.noconv.} =
|
||||
# writeStackTrace()
|
||||
|
||||
#addQuitProc(stackTraceWrapper)
|
||||
|
||||
var
|
||||
dbgAborting: bool # whether the debugger wants to abort
|
||||
|
||||
|
|
@ -171,6 +173,7 @@ proc signalHandler(sig: cint) {.exportc: "signalHandler", noconv.} =
|
|||
# print stack trace and quit
|
||||
var
|
||||
s = int(sig)
|
||||
GC_disable()
|
||||
setLen(buf, 0)
|
||||
rawWriteStackTrace(buf)
|
||||
|
||||
|
|
@ -185,6 +188,7 @@ proc signalHandler(sig: cint) {.exportc: "signalHandler", noconv.} =
|
|||
else: add(buf, "unknown signal\n")
|
||||
writeToStdErr(buf)
|
||||
dbgAborting = True # play safe here...
|
||||
GC_enable()
|
||||
quit(1) # always quit when SIGABRT
|
||||
|
||||
proc registerSignalHandler() =
|
||||
|
|
@ -195,8 +199,8 @@ proc registerSignalHandler() =
|
|||
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
|
||||
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)
|
||||
|
|
@ -204,12 +208,15 @@ assertBuf = newString(2048)
|
|||
setLen(buf, 0)
|
||||
setLen(assertBuf, 0)
|
||||
|
||||
proc raiseRangeError() {.compilerproc, noreturn.} =
|
||||
raise newException(EOutOfRange, "value out of range")
|
||||
proc raiseRangeError(val: biggestInt) {.compilerproc, noreturn.} =
|
||||
raise newException(EOutOfRange, "value " & $val & " out of range")
|
||||
|
||||
proc raiseIndexError() {.compilerproc, noreturn.} =
|
||||
raise newException(EInvalidIndex, "index out of bounds")
|
||||
|
||||
proc raiseFieldError(f: string) {.compilerproc, noreturn.} =
|
||||
raise newException(EInvalidField, f & " is not accessible")
|
||||
|
||||
proc chckIndx(i, a, b: int): int =
|
||||
if i >= a and i <= b:
|
||||
return i
|
||||
|
|
@ -220,19 +227,19 @@ proc chckRange(i, a, b: int): int =
|
|||
if i >= a and i <= b:
|
||||
return i
|
||||
else:
|
||||
raiseRangeError()
|
||||
raiseRangeError(i)
|
||||
|
||||
proc chckRange64(i, a, b: int64): int64 {.compilerproc.} =
|
||||
if i >= a and i <= b:
|
||||
return i
|
||||
else:
|
||||
raiseRangeError()
|
||||
raiseRangeError(i)
|
||||
|
||||
proc chckRangeF(x, a, b: float): float =
|
||||
if x >= a and x <= b:
|
||||
return x
|
||||
else:
|
||||
raiseRangeError()
|
||||
raise newException(EOutOfRange, "value " & $x & " out of range")
|
||||
|
||||
proc chckNil(p: pointer) =
|
||||
if p == nil: c_raise(SIGSEGV)
|
||||
|
|
|
|||
630
lib/gc.nim
630
lib/gc.nim
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
# (c) Copyright 2008 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
|
|
@ -13,33 +13,39 @@
|
|||
# For a description of the algorithms used here see:
|
||||
# intern.html
|
||||
|
||||
#{.define: debugGC.} # we wish to debug the GC...
|
||||
{.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.}
|
||||
|
||||
const
|
||||
traceGC = false # extensive debugging
|
||||
reallyDealloc = true # for debugging purposes this can be set to false
|
||||
|
||||
# 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
|
||||
PageShift = if sizeof(pointer) == 4: 12 else: 13
|
||||
PageSize = 1 shl PageShift # on 32 bit systems 4096
|
||||
CycleIncrease = 2 # is a multiplicative increase
|
||||
|
||||
InitialCycleThreshold = 8*1024*1024 # X MB because cycle checking is slow
|
||||
ZctThreshold = 512 # we collect garbage if the ZCT's size
|
||||
# reaches this threshold
|
||||
# this needs benchmarking...
|
||||
|
||||
when defined(debugGC):
|
||||
const InitialThreshold = 64*1024
|
||||
const stressGC = True # GC is debugged; no need to stress it
|
||||
const stressGC = False
|
||||
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
|
||||
TMallocInfo {.importc: "struct mallinfo", nodecl, final.} = object
|
||||
arena: cint # non-mmapped space allocated from system
|
||||
ordblks: cint # number of free chunks
|
||||
smblks: cint # number of fastbin blocks
|
||||
|
|
@ -68,8 +74,7 @@ else: # not available:
|
|||
proc getTotalMem(): int = return -1
|
||||
|
||||
var
|
||||
rcThreshold: int = InitialThreshold
|
||||
cycleThreshold: int = InitialThreshold
|
||||
cycleThreshold: int = InitialCycleThreshold
|
||||
|
||||
memUsed: int = 0 # we have to keep track how much we have allocated
|
||||
|
||||
|
|
@ -113,11 +118,12 @@ type
|
|||
waNone, waRelease, waZctDecRef, waCycleDecRef, waCycleIncRef, waDebugIncRef
|
||||
|
||||
TCollectorData = int
|
||||
TCell = record
|
||||
TCell {.final.} = object
|
||||
refcount: TCollectorData # the refcount and bit flags
|
||||
typ: PNimType
|
||||
stackcount: int # stack counter for debugging
|
||||
drefc: int # real reference counter for debugging
|
||||
when stressGC:
|
||||
stackcount: int # stack counter for debugging
|
||||
drefc: int # real reference counter for debugging
|
||||
|
||||
PCell = ptr TCell
|
||||
|
||||
|
|
@ -145,6 +151,7 @@ proc extGetCellType(c: pointer): PNimType {.compilerproc.} =
|
|||
|
||||
proc internRefcount(p: pointer): int {.exportc: "getRefcount".} =
|
||||
result = int(usrToCell(p).refcount)
|
||||
if result < 0: result = 0
|
||||
|
||||
proc gcAlloc(size: int): pointer =
|
||||
result = alloc0(size)
|
||||
|
|
@ -162,7 +169,7 @@ proc GC_setStrategy(strategy: TGC_Strategy) =
|
|||
of gcOptimizeTime: nil
|
||||
|
||||
proc GC_enableMarkAndSweep() =
|
||||
cycleThreshold = InitialThreshold
|
||||
cycleThreshold = InitialCycleThreshold
|
||||
|
||||
proc GC_disableMarkAndSweep() =
|
||||
cycleThreshold = high(cycleThreshold)-1
|
||||
|
|
@ -174,7 +181,7 @@ proc nextTry(h, maxHash: int): int {.inline.} =
|
|||
# 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) -------------
|
||||
# ------------------ Any table (AT) -------------
|
||||
|
||||
# these values are for DL-malloc known for sure (and other allocators
|
||||
# can only be worse):
|
||||
|
|
@ -200,8 +207,7 @@ when BitsPerPage mod BitsPerUnit != 0:
|
|||
|
||||
# ------------------- 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.
|
||||
# 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
|
||||
|
|
@ -217,17 +223,59 @@ type
|
|||
|
||||
TBitIndex = range[0..UnitsPerPage-1]
|
||||
|
||||
TPageDesc = record
|
||||
TPageDesc {.final.} = object
|
||||
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
|
||||
TCellSet {.final.} = object
|
||||
counter, max: int
|
||||
head: PPageDesc
|
||||
data: PPageDescArray
|
||||
|
||||
PCellArray = ptr array[0..100_000_000, PCell]
|
||||
TCellSeq {.final.} = object
|
||||
len, cap: int
|
||||
d: PCellArray
|
||||
|
||||
TSlowSet {.final.} = object # used for debugging purposes only
|
||||
L: int # current length
|
||||
cap: int # capacity
|
||||
d: PCellArray
|
||||
|
||||
TGcHeap {.final.} = object # this contains the zero count and
|
||||
# non-zero count table
|
||||
mask: TAddress # mask for fast pointer detection
|
||||
zct: TCellSeq # the zero count table
|
||||
at: TCellSet # a table that contains all references
|
||||
newAT: TCellSet
|
||||
stackCells: TCellSeq # cells that need to be decremented because they
|
||||
# are in the hardware stack; a cell may occur
|
||||
# several times in this data structure
|
||||
|
||||
var
|
||||
stackBottom: pointer
|
||||
gch: TGcHeap
|
||||
|
||||
proc add(s: var TCellSeq, c: PCell) {.inline.} =
|
||||
if s.len >= s.cap:
|
||||
s.cap = s.cap * 3 div 2
|
||||
s.d = cast[PCellArray](realloc(s.d, s.cap * sizeof(PCell)))
|
||||
if s.d == nil: raiseOutOfMem()
|
||||
s.d[s.len] = c
|
||||
inc(s.len)
|
||||
|
||||
proc inOperator(s: TCellSeq, c: PCell): bool {.inline.} =
|
||||
for i in 0 .. s.len-1:
|
||||
if s.d[i] == c: return True
|
||||
return False
|
||||
|
||||
proc init(s: var TCellSeq, cap: int = 1024) =
|
||||
s.len = 0
|
||||
s.cap = cap
|
||||
s.d = cast[PCellArray](gcAlloc(cap * sizeof(PCell)))
|
||||
|
||||
const
|
||||
InitCellSetSize = 1024 # must be a power of two!
|
||||
|
||||
|
|
@ -284,7 +332,8 @@ proc CellSetPut(t: var TCellSet, key: TAddress): PPageDesc =
|
|||
if x.key == key: return x
|
||||
h = nextTry(h, t.max)
|
||||
|
||||
if (t.max+1) * 2 < t.counter * 3: CellSetEnlarge(t)
|
||||
if ((t.max+1)*2 < t.counter*3) or ((t.max+1)-t.counter < 4):
|
||||
CellSetEnlarge(t)
|
||||
inc(t.counter)
|
||||
h = cast[int](key) and t.max
|
||||
while t.data[h] != nil: h = nextTry(h, t.max)
|
||||
|
|
@ -303,7 +352,7 @@ proc in_Operator(s: TCellSet, cell: PCell): bool =
|
|||
u: TAddress
|
||||
t: PPageDesc
|
||||
u = cast[TAddress](cell)
|
||||
t = CellSetGet(s, u /% PageSize)
|
||||
t = CellSetGet(s, u shr PageShift)
|
||||
if t != nil:
|
||||
u = (u %% PageSize) /% MemAlignment
|
||||
result = (t.bits[u /% BitsPerUnit] and (1 shl (u %% BitsPerUnit))) != 0
|
||||
|
|
@ -315,7 +364,7 @@ proc incl(s: var TCellSet, cell: PCell) =
|
|||
u: TAddress
|
||||
t: PPageDesc
|
||||
u = cast[TAddress](cell)
|
||||
t = CellSetPut(s, u /% PageSize)
|
||||
t = CellSetPut(s, u shr PageShift)
|
||||
u = (u %% PageSize) /% MemAlignment
|
||||
t.bits[u /% BitsPerUnit] = t.bits[u /% BitsPerUnit] or
|
||||
(1 shl (u %% BitsPerUnit))
|
||||
|
|
@ -325,7 +374,7 @@ proc excl(s: var TCellSet, cell: PCell) =
|
|||
u: TAddress
|
||||
t: PPageDesc
|
||||
u = cast[TAddress](cell)
|
||||
t = CellSetGet(s, u /% PageSize)
|
||||
t = CellSetGet(s, u shr PageShift)
|
||||
if t != nil:
|
||||
u = (u %% PageSize) /% MemAlignment
|
||||
t.bits[u /% BitsPerUnit] = (t.bits[u /% BitsPerUnit] and
|
||||
|
|
@ -342,7 +391,7 @@ iterator elements(t: TCellSet): PCell {.inline.} =
|
|||
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) +%
|
||||
yield cast[PCell]((r.key shl PageShift) or # +%
|
||||
(i*%BitsPerUnit+%j) *% MemAlignment)
|
||||
inc(j)
|
||||
w = w shr 1
|
||||
|
|
@ -354,68 +403,121 @@ iterator elements(t: TCellSet): PCell {.inline.} =
|
|||
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))
|
||||
#var u = 10_000
|
||||
#while u <= 20_000:
|
||||
# incl(root, cast[PCell](u))
|
||||
# inc(u, 8)
|
||||
|
||||
# testPageDescs()
|
||||
incl(root, cast[PCell](0x81cdfb8))
|
||||
for cell in elements(root):
|
||||
c_fprintf(c_stdout, "%p\n", cast[int](cell))
|
||||
|
||||
#testPageDescs()
|
||||
|
||||
when defined(debugGC):
|
||||
proc writeCell(msg: CString, c: PCell) =
|
||||
c_fprintf(c_stdout, "%s: %p\n", msg, c)
|
||||
if c.typ != nil:
|
||||
if c.typ.kind == tyString:
|
||||
c_fprintf(c_stdout, "%s\n", cast[TAddress](cellToUsr(c)) + sizeof(int)*2)
|
||||
c_fprintf(c_stdout, "%s: %p %d\n", msg, c, c.typ.kind)
|
||||
else: c_fprintf(c_stdout, "%s: %p (nil type)\n", msg, c)
|
||||
proc writePtr(msg: CString, p: Pointer) =
|
||||
c_fprintf(c_stdout, "%s: %p\n", msg, p)
|
||||
|
||||
|
||||
when traceGC:
|
||||
# traceGC is a special switch to enable extensive debugging
|
||||
type
|
||||
TCellState = enum
|
||||
csAllocated, csZctFreed, csCycFreed
|
||||
|
||||
proc cellSetInit(s: var TSlowSet) =
|
||||
s.L = 0
|
||||
s.cap = 4096
|
||||
s.d = cast[PCellArray](gcAlloc(s.cap * sizeof(PCell)))
|
||||
|
||||
proc cellSetDeinit(s: var TSlowSet) =
|
||||
s.L = 0
|
||||
s.cap = 0
|
||||
dealloc(s.d)
|
||||
|
||||
proc incl(s: var TSlowSet, c: PCell) =
|
||||
if s.L >= s.cap:
|
||||
s.cap = s.cap * 3 div 2
|
||||
s.d = cast[PCellArray](realloc(s.d, s.cap * sizeof(PCell)))
|
||||
if s.d == nil: raiseOutOfMem()
|
||||
s.d[s.L] = c
|
||||
inc(s.L)
|
||||
|
||||
proc excl(s: var TSlowSet, c: PCell) =
|
||||
var i = 0
|
||||
while i < s.L:
|
||||
if s.d[i] == c:
|
||||
s.d[i] = s.d[s.L-1]
|
||||
dec(s.L)
|
||||
break
|
||||
inc(i)
|
||||
|
||||
proc inOperator(s: TSlowSet, c: PCell): bool =
|
||||
var i = 0
|
||||
while i < s.L:
|
||||
if s.d[i] == c: return true
|
||||
inc(i)
|
||||
|
||||
iterator elements(s: TSlowSet): PCell =
|
||||
var i = 0
|
||||
while i < s.L:
|
||||
yield s.d[i]
|
||||
inc(i)
|
||||
|
||||
var
|
||||
states: array[TCellState, TSlowSet] # TCellSet]
|
||||
|
||||
proc traceCell(c: PCell, state: TCellState) =
|
||||
case state
|
||||
of csAllocated:
|
||||
if c in states[csAllocated]:
|
||||
writeCell("attempt to alloc a already allocated cell", c)
|
||||
assert(false)
|
||||
excl(states[csCycFreed], c)
|
||||
excl(states[csZctFreed], c)
|
||||
of csZctFreed:
|
||||
if c notin states[csAllocated]:
|
||||
writeCell("attempt to free a not allocated cell", c)
|
||||
assert(false)
|
||||
if c in states[csZctFreed]:
|
||||
writeCell("attempt to free zct cell twice", c)
|
||||
assert(false)
|
||||
if c in states[csCycFreed]:
|
||||
writeCell("attempt to free with zct, but already freed with cyc", c)
|
||||
assert(false)
|
||||
excl(states[csAllocated], c)
|
||||
of csCycFreed:
|
||||
if c notin states[csAllocated]:
|
||||
writeCell("attempt to free a not allocated cell", c)
|
||||
assert(false)
|
||||
if c in states[csCycFreed]:
|
||||
writeCell("attempt to free cyc cell twice", c)
|
||||
assert(false)
|
||||
if c in states[csZctFreed]:
|
||||
writeCell("attempt to free with cyc, but already freed with zct", c)
|
||||
assert(false)
|
||||
excl(states[csAllocated], c)
|
||||
incl(states[state], c)
|
||||
|
||||
template gcTrace(cell, state: expr): stmt =
|
||||
when traceGC: traceCell(cell, state)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
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
|
||||
# forward declarations:
|
||||
proc collectCT(gch: var TGcHeap)
|
||||
proc IsOnStack(p: pointer): bool
|
||||
proc forAllChildren(cell: PCell, op: TWalkOp)
|
||||
proc collectCycles(gch: var TGcHeap)
|
||||
|
||||
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 reprAny(p: pointer, typ: PNimType): string {.compilerproc.}
|
||||
# we need the prototype here for debugging purposes
|
||||
|
||||
proc prepareDealloc(cell: PCell) =
|
||||
if cell.typ.finalizer != nil:
|
||||
|
|
@ -433,79 +535,95 @@ proc prepareDealloc(cell: PCell) =
|
|||
else:
|
||||
memUsed = memUsed - cell.typ.size
|
||||
|
||||
proc checkZCT(): bool =
|
||||
if recGcLock >= 1: return true # prevent endless recursion
|
||||
inc(recGcLock)
|
||||
result = true
|
||||
for i in 0..gch.zct.len-1:
|
||||
var c = gch.zct.d[i]
|
||||
if c.refcount > 0: # should be in the ZCT!
|
||||
writeCell("wrong ZCT entry", c)
|
||||
result = false
|
||||
elif gch.zct.d[-c.refcount] != c:
|
||||
writeCell("wrong ZCT position", c)
|
||||
result = false
|
||||
dec(recGcLock)
|
||||
|
||||
proc GC_invariant(): bool =
|
||||
if recGcLock >= 1: return true # prevent endless recursion
|
||||
inc(recGcLock)
|
||||
result = True
|
||||
block checks:
|
||||
if not checkZCT():
|
||||
result = false
|
||||
break checks
|
||||
# set counters back to zero:
|
||||
for c in elements(gch.AT):
|
||||
var t = c.typ
|
||||
if t == nil or t.kind notin {tySequence, tyString, tyRef}:
|
||||
writeCell("corrupt cell?", c)
|
||||
result = false
|
||||
break checks
|
||||
when stressGC: c.drefc = 0
|
||||
for c in elements(gch.AT):
|
||||
forAllChildren(c, waDebugIncRef)
|
||||
when stressGC:
|
||||
for c in elements(gch.AT):
|
||||
var rc = c.refcount
|
||||
if rc < 0: rc = 0
|
||||
if c.drefc > rc + 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)
|
||||
break checks
|
||||
dec(recGcLock)
|
||||
|
||||
when stressGC:
|
||||
proc GCdebugHook() =
|
||||
if not GC_invariant():
|
||||
assert(false)
|
||||
|
||||
dbgLineHook = GCdebugHook
|
||||
|
||||
proc setStackBottom(theStackBottom: pointer) {.compilerproc.} =
|
||||
stackBottom = theStackBottom
|
||||
|
||||
proc initGC() =
|
||||
when traceGC:
|
||||
for i in low(TCellState)..high(TCellState): CellSetInit(states[i])
|
||||
# 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
|
||||
init(gch.zct)
|
||||
CellSetInit(gch.at)
|
||||
init(gch.stackCells)
|
||||
gch.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))
|
||||
when stressGC: assert(cell in gch.AT)
|
||||
dec(cell.refcount)
|
||||
if cell.refcount == 0:
|
||||
incl(ct.zct, cell)
|
||||
cell.refcount = -gch.zct.len
|
||||
when stressGC: assert(cell notin gch.zct)
|
||||
add(gch.zct, cell)
|
||||
when stressGC: assert(checkZCT())
|
||||
|
||||
proc incRef(cell: PCell) {.inline.} =
|
||||
assert(seqCheck(cell))
|
||||
inc(cell.refcount)
|
||||
var rc = cell.refcount
|
||||
if rc <= 0:
|
||||
# remove from zero count table:
|
||||
when stressGC: assert(gch.zct.len > -rc)
|
||||
when stressGC: assert(gch.zct.d[-rc] == cell)
|
||||
gch.zct.d[-rc] = gch.zct.d[gch.zct.len-1]
|
||||
gch.zct.d[-rc].refcount = rc
|
||||
dec(gch.zct.len)
|
||||
cell.refcount = 1
|
||||
when stressGC: assert(checkZCT())
|
||||
else:
|
||||
inc(cell.refcount)
|
||||
when stressGC: assert(checkZCT())
|
||||
|
||||
proc asgnRef(dest: ppointer, src: pointer) =
|
||||
# the code generator calls this proc!
|
||||
|
|
@ -514,18 +632,18 @@ proc asgnRef(dest: ppointer, src: pointer) =
|
|||
if src != nil: incRef(usrToCell(src))
|
||||
if dest^ != nil: decRef(usrToCell(dest^))
|
||||
dest^ = src
|
||||
#assert(checkRefc())
|
||||
when stressGC: assert(GC_invariant())
|
||||
|
||||
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())
|
||||
when stressGC: assert(GC_invariant())
|
||||
|
||||
proc restore(cell: PCell) =
|
||||
if cell notin ct.newAT:
|
||||
incl(ct.newAT, Cell)
|
||||
if cell notin gch.newAT:
|
||||
incl(gch.newAT, Cell)
|
||||
forAllChildren(cell, waCycleIncRef)
|
||||
|
||||
proc doOperation(p: pointer, op: TWalkOp) =
|
||||
|
|
@ -536,19 +654,15 @@ proc doOperation(p: pointer, op: TWalkOp) =
|
|||
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)
|
||||
decRef(cell)
|
||||
of waCycleDecRef:
|
||||
assert(cell.refcount != 0)
|
||||
assert(cell.refcount > 0)
|
||||
dec(cell.refcount)
|
||||
of waCycleIncRef:
|
||||
inc(cell.refcount) # restore proper reference counts!
|
||||
restore(cell)
|
||||
of waDebugIncRef:
|
||||
inc(cell.drefc)
|
||||
when stressGC: inc(cell.drefc)
|
||||
|
||||
type
|
||||
TByteArray = array[0..1000_0000, byte]
|
||||
|
|
@ -590,16 +704,20 @@ proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) =
|
|||
if m != nil: forAllSlotsAux(dest, m, op)
|
||||
|
||||
proc forAllChildrenAux(dest: Pointer, mt: PNimType, op: TWalkOp) =
|
||||
const
|
||||
handledTypes = {tyArray, tyArrayConstr, tyOpenArray, tyRef,
|
||||
tyString, tySequence, tyObject, tyPureObject, tyTuple}
|
||||
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)
|
||||
if mt.base.kind in handledTypes:
|
||||
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:
|
||||
of tyObject, tyTuple, tyPureObject:
|
||||
forAllSlotsAux(dest, mt.node, op)
|
||||
else: nil
|
||||
|
||||
|
|
@ -608,6 +726,13 @@ proc forAllChildren(cell: PCell, op: TWalkOp) =
|
|||
when defined(debugGC):
|
||||
if cell.typ == nil:
|
||||
writeCell("cell has no type descriptor", cell)
|
||||
when traceGC:
|
||||
if cell notin states[csAllocated]:
|
||||
writeCell("cell has never been allocated!", cell)
|
||||
if cell in states[csCycFreed]:
|
||||
writeCell("cell has been freed by Cyc", cell)
|
||||
if cell in states[csZctFreed]:
|
||||
writeCell("cell has been freed by Zct", cell)
|
||||
assert(cell.typ != nil)
|
||||
case cell.typ.Kind
|
||||
of tyRef: # common case
|
||||
|
|
@ -625,36 +750,36 @@ proc forAllChildren(cell: PCell, op: TWalkOp) =
|
|||
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)
|
||||
collectCT(gch)
|
||||
|
||||
proc newObj(typ: PNimType, size: int): pointer =
|
||||
# generates a new object and sets its reference counter to 0
|
||||
var
|
||||
res: PCell
|
||||
when stressGC: assert(checkZCT())
|
||||
assert(typ.kind in {tyRef, tyString, tySequence})
|
||||
# check if we have to collect:
|
||||
checkCollection()
|
||||
res = cast[PCell](Alloc0(size + sizeof(TCell)))
|
||||
when stressGC: assert((cast[TAddress](res) and (MemAlignment-1)) == 0)
|
||||
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)
|
||||
res.refcount = -gch.zct.len
|
||||
add(gch.zct, res) # its refcount is zero, so add it to the ZCT
|
||||
incl(gch.at, res) # add it to the any table too
|
||||
gch.mask = gch.mask or cast[TAddress](res)
|
||||
when defined(debugGC):
|
||||
writeCell("new cell", res)
|
||||
assert(gcInvariant())
|
||||
when defined(logGC): writeCell("new cell", res)
|
||||
gcTrace(res, csAllocated)
|
||||
result = cellToUsr(res)
|
||||
assert(res.typ == typ)
|
||||
when stressGC: assert(checkZCT())
|
||||
|
||||
proc newSeq(typ: PNimType, len: int): pointer =
|
||||
# XXX: overflow checks!
|
||||
|
|
@ -665,16 +790,19 @@ proc newSeq(typ: PNimType, len: int): pointer =
|
|||
proc growObj(old: pointer, newsize: int): pointer =
|
||||
var
|
||||
res, ol: PCell
|
||||
when stressGC: assert(checkZCT())
|
||||
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
|
||||
# pity that we don't know the old size
|
||||
res = cast[PCell](realloc(ol, newsize + sizeof(TCell)))
|
||||
#res = cast[PCell](gcAlloc(newsize + sizeof(TCell)))
|
||||
#copyMem(res, ol, nimSize(ol))
|
||||
assert((cast[TAddress](res) and (MemAlignment-1)) == 0)
|
||||
when defined(nimSize):
|
||||
memUsed = memUsed + nimSize(res)
|
||||
else:
|
||||
|
|
@ -682,74 +810,69 @@ proc growObj(old: pointer, newsize: int): pointer =
|
|||
|
||||
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):
|
||||
if res.refcount <= 0:
|
||||
assert(gch.zct.d[-res.refcount] == ol)
|
||||
gch.zct.d[-res.refcount] = res
|
||||
excl(gch.at, ol)
|
||||
incl(gch.at, res)
|
||||
gch.mask = gch.mask or cast[TAddress](res)
|
||||
when defined(logGC):
|
||||
writeCell("growObj old cell", ol)
|
||||
writeCell("growObj new cell", res)
|
||||
gcTrace(ol, csZctFreed)
|
||||
gcTrace(res, csAllocated)
|
||||
result = cellToUsr(res)
|
||||
#assert(checkRefc())
|
||||
when stressGC: assert(checkZCT())
|
||||
|
||||
proc collectCycles() =
|
||||
when defined(debugGC):
|
||||
echo("collecting cycles!\n")
|
||||
proc collectCycles(gch: var TGcHeap) =
|
||||
when defined(logGC):
|
||||
c_fprintf(c_stdout, "collecting cycles!\n")
|
||||
|
||||
# step 1: pretend that any node is dead
|
||||
for c in elements(ct.at):
|
||||
for c in elements(gch.at):
|
||||
forallChildren(c, waCycleDecRef)
|
||||
CellSetInit(ct.newAt)
|
||||
CellSetInit(gch.newAt)
|
||||
# step 2: restore life cells
|
||||
for c in elements(ct.at):
|
||||
for c in elements(gch.at):
|
||||
if c.refcount > 0: restore(c)
|
||||
# step 3: free dead cells:
|
||||
for cell in elements(ct.at):
|
||||
for cell in elements(gch.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):
|
||||
gcTrace(cell, csCycFreed)
|
||||
when defined(logGC):
|
||||
writeCell("cycle collector dealloc cell", cell)
|
||||
CellSetDeinit(ct.at)
|
||||
ct.at = ct.newAt
|
||||
#ct.newAt = nil
|
||||
when reallyDealloc: dealloc(cell)
|
||||
CellSetDeinit(gch.at)
|
||||
gch.at = gch.newAt
|
||||
|
||||
proc gcMark(p: pointer) =
|
||||
proc gcMark(gch: var TGcHeap, 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:
|
||||
if ((c and gch.mask) == c) and cell in gch.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)
|
||||
incRef(cell)
|
||||
when stressGC: inc(cell.stackcount)
|
||||
add(gch.stackCells, cell)
|
||||
|
||||
proc unmarkStackAndRegisters() =
|
||||
for i in 0 .. ct.stackLen-1:
|
||||
var cell = ct.stackCells[i]
|
||||
proc unmarkStackAndRegisters(gch: var TGcHeap) =
|
||||
when stressGC: assert(checkZCT())
|
||||
for i in 0 .. gch.stackCells.len-1:
|
||||
var cell = gch.stackCells.d[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
|
||||
when stressGC:
|
||||
assert(cell.stackcount > 0)
|
||||
dec(cell.stackcount)
|
||||
decRef(cell)
|
||||
gch.stackCells.len = 0 # reset to zero
|
||||
when stressGC: assert(checkZCT())
|
||||
|
||||
# ----------------- stack management --------------------------------------
|
||||
# inspired from Smart Eiffel (c)
|
||||
|
|
@ -765,7 +888,7 @@ when defined(sparc): # For SPARC architecture.
|
|||
stackTop: array[0..1, pointer]
|
||||
result = p >= addr(stackTop[0]) and p <= stackBottom
|
||||
|
||||
proc markStackAndRegisters() =
|
||||
proc markStackAndRegisters(gch: var TGcHeap) =
|
||||
when defined(sparcv9):
|
||||
asm " flushw"
|
||||
else:
|
||||
|
|
@ -780,7 +903,7 @@ when defined(sparc): # For SPARC architecture.
|
|||
sp = addr(stackTop[0])
|
||||
# Addresses decrease as the stack grows.
|
||||
while sp <= max:
|
||||
gcMark(sp^)
|
||||
gcMark(gch, sp^)
|
||||
sp = cast[ppointer](cast[TAddress](sp) +% sizeof(pointer))
|
||||
|
||||
elif defined(ELATE):
|
||||
|
|
@ -802,7 +925,7 @@ elif defined(hppa) or defined(hp9000) or defined(hp9000s300) or
|
|||
# a little hack to get the size of a TJmpBuf in the generated C code
|
||||
# in a platform independant way
|
||||
|
||||
proc markStackAndRegisters() =
|
||||
proc markStackAndRegisters(gch: var TGcHeap) =
|
||||
var
|
||||
max = stackBottom
|
||||
registers: C_JmpBuf # The jmp_buf buffer is in the C stack.
|
||||
|
|
@ -814,7 +937,7 @@ elif defined(hppa) or defined(hp9000) or defined(hp9000s300) or
|
|||
# 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^)
|
||||
gcMark(gch, sp^)
|
||||
sp = cast[ppointer](cast[TAddress](sp) -% sizeof(pointer))
|
||||
|
||||
else:
|
||||
|
|
@ -826,7 +949,7 @@ else:
|
|||
stackTop: array [0..1, pointer]
|
||||
result = p >= addr(stackTop[0]) and p <= stackBottom
|
||||
|
||||
proc markStackAndRegisters() =
|
||||
proc markStackAndRegisters(gch: var TGcHeap) =
|
||||
var
|
||||
max = stackBottom
|
||||
registers: C_JmpBuf # The jmp_buf buffer is in the C stack.
|
||||
|
|
@ -835,63 +958,58 @@ else:
|
|||
c_setjmp(registers) # To fill the C stack with registers.
|
||||
sp = cast[ppointer](addr(registers))
|
||||
while sp <= max:
|
||||
gcMark(sp^)
|
||||
gcMark(gch, 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 CollectZCT(gch: var TGcHeap) =
|
||||
while gch.zct.len > 0:
|
||||
var c = gch.zct.d[0]
|
||||
assert(c.refcount <= 0)
|
||||
# remove from ZCT:
|
||||
gch.zct.d[0] = gch.zct.d[gch.zct.len-1]
|
||||
gch.zct.d[0].refcount = 0
|
||||
dec(gch.zct.len)
|
||||
# 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():
|
||||
gcTrace(c, csZctFreed)
|
||||
prepareDealloc(c)
|
||||
forAllChildren(c, waZctDecRef)
|
||||
excl(gch.at, c)
|
||||
when defined(logGC):
|
||||
writeCell("zct dealloc cell", c)
|
||||
#when defined(debugGC) and defined(nimSize): zeroMem(c, nimSize(c))
|
||||
when reallyDealloc: dealloc(c)
|
||||
|
||||
proc collectCT(ct: var TCountTables) =
|
||||
when defined(debugGC):
|
||||
proc collectCT(gch: var TGcHeap) =
|
||||
when defined(logGC):
|
||||
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()
|
||||
when stressGC: assert(checkZCT())
|
||||
if gch.zct.len >= ZctThreshold or memUsed >= cycleThreshold or stressGC:
|
||||
markStackAndRegisters(gch)
|
||||
when stressGC: assert(GC_invariant())
|
||||
collectZCT(gch)
|
||||
when stressGC: assert(GC_invariant())
|
||||
assert(gch.zct.len == 0)
|
||||
when defined(cycleGC):
|
||||
if memUsed >= cycleThreshold or stressGC:
|
||||
when defined(logGC):
|
||||
c_fprintf(c_stdout, "collecting cycles; memory used: %ld\n", memUsed)
|
||||
collectCycles(gch)
|
||||
cycleThreshold = max(InitialCycleThreshold, memUsed * cycleIncrease)
|
||||
when defined(logGC):
|
||||
c_fprintf(c_stdout, "now used: %ld; threshold: %ld\n",
|
||||
memUsed, cycleThreshold)
|
||||
unmarkStackAndRegisters(gch)
|
||||
when stressGC: assert(GC_invariant())
|
||||
|
||||
proc GC_fullCollect() =
|
||||
var oldThreshold = cycleThreshold
|
||||
cycleThreshold = 0 # forces cycle collection
|
||||
collectCT(ct)
|
||||
collectCT(gch)
|
||||
cycleThreshold = oldThreshold
|
||||
|
|
|
|||
51
lib/hti.nim
51
lib/hti.nim
|
|
@ -10,29 +10,38 @@
|
|||
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,
|
||||
tyNone, # 0
|
||||
tyBool, # 1
|
||||
tyChar, # 2
|
||||
tyEmptySet, # 3
|
||||
tyArrayConstr, # 4
|
||||
tyNil, # 5
|
||||
tyGeneric, # 6
|
||||
tyGenericInst, # 7
|
||||
tyGenericParam, # 8
|
||||
tyEnum, # 9
|
||||
tyAnyEnum, # 10
|
||||
tyArray, # 11
|
||||
tyObject, # 12
|
||||
tyTuple, # 13
|
||||
tySet, # 14
|
||||
tyRange, # 15
|
||||
tyPtr, # 16
|
||||
tyRef, # 17
|
||||
tyVar, # 18
|
||||
tySequence, # 19
|
||||
tyProc, # 20
|
||||
tyPointer, # 21
|
||||
tyOpenArray, # 22
|
||||
tyString, # 23
|
||||
tyCString, # 24
|
||||
tyForward, # 25
|
||||
tyInt, tyInt8, tyInt16, tyInt32, tyInt64,
|
||||
tyFloat, tyFloat32, tyFloat64, tyFloat128
|
||||
tyFloat, tyFloat32, tyFloat64, tyFloat128,
|
||||
tyPureObject # 35: signals that object has no `n_type` field
|
||||
|
||||
TNimNodeKind = enum nkNone, nkSlot, nkList, nkCase
|
||||
TNimNode {.compilerproc.} = record
|
||||
TNimNode {.compilerproc, final.} = object
|
||||
kind: TNimNodeKind
|
||||
offset: int
|
||||
typ: ptr TNimType
|
||||
|
|
@ -40,7 +49,7 @@ type # This should be he same as ast.TTypeKind
|
|||
len: int
|
||||
sons: ptr array [0..0x7fff, ptr TNimNode]
|
||||
|
||||
TNimType {.compilerproc.} = record
|
||||
TNimType {.compilerproc, final.} = object
|
||||
size: int
|
||||
kind: TNimKind
|
||||
base: ptr TNimType
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@
|
|||
# 64 bit integers for platforms that don't have those
|
||||
|
||||
type
|
||||
IInt64 = record # "internal" int64
|
||||
lo, hi: int32
|
||||
IInt64 = tuple[lo, hi: int32]
|
||||
|
||||
proc cmpI64(x, y: IInt64): int32 {.compilerproc.} =
|
||||
result = x.hi -% y.hi
|
||||
|
|
|
|||
220
lib/math.nim
220
lib/math.nim
|
|
@ -1,75 +1,22 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
# (c) Copyright 2008 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
|
||||
|
||||
# math routines
|
||||
|
||||
# interface
|
||||
## Basic math routines for Nimrod.
|
||||
## This module is available for the ECMAScript target.
|
||||
|
||||
{.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.
|
||||
when defined(Posix):
|
||||
{.passl: "-lm".}
|
||||
|
||||
type
|
||||
TFloatClass* = enum ## describes the class a floating point value belongs to.
|
||||
|
|
@ -82,34 +29,11 @@ type
|
|||
fcInf, ## value is positive infinity
|
||||
fcNegInf ## value is negative infinity
|
||||
|
||||
proc classify*(x: float): TFloatClass
|
||||
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 =
|
||||
## `TFloatClass`.
|
||||
|
||||
# ECMAScript and most C compilers have no classify:
|
||||
if x == 0.0:
|
||||
if 1.0/x == 1.0/0.0:
|
||||
return fcZero
|
||||
|
|
@ -122,10 +46,130 @@ proc classify(x: float): TFloatClass =
|
|||
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
|
||||
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.
|
||||
return (x and -x) == x
|
||||
|
||||
proc nextPowerOfTwo*(x: int): int =
|
||||
## returns the nearest power of two, so that
|
||||
## result**2 >= x > (result-1)**2.
|
||||
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)
|
||||
|
||||
proc countBits*(n: int32): int {.noSideEffect.}
|
||||
## counts the set bits in `n`.
|
||||
|
||||
include cntbits
|
||||
|
||||
|
||||
when not defined(ECMAScript):
|
||||
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. Note: Does nothing for the ECMAScript target,
|
||||
## as ECMAScript does not support this.
|
||||
|
||||
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 log10*(x: float): float {.importc: "log10", header: "<math.h>".}
|
||||
proc log2*(x: float): float = return ln(x) / ln(2.0)
|
||||
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 round*(x: float): int {.importc: "lrint", nodecl.}
|
||||
## converts a float to an int by rounding.
|
||||
|
||||
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, y: float): float {.importc: "hypot", header: "<math.h>".}
|
||||
## same as ``sqrt(x*x + y*y)``.
|
||||
|
||||
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: "pow", header: "<math.h>".}
|
||||
## computes x to power raised of y.
|
||||
|
||||
# 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.}
|
||||
|
||||
proc randomize() = srand(gettime(nil))
|
||||
proc random(max: int): int = return rand() mod max
|
||||
|
||||
else:
|
||||
proc mathrandom(): float {.importc: "Math.random", nodecl.}
|
||||
proc mathfloor(x: float): float {.importc: "Math.floor", nodecl.}
|
||||
proc random*(max: int): int = return mathfloor(mathrandom() * max)
|
||||
proc randomize*() = nil
|
||||
|
||||
proc sqrt*(x: float): float {.importc: "Math.sqrt", nodecl.}
|
||||
proc ln*(x: float): float {.importc: "Math.log", nodecl.}
|
||||
proc log10*(x: float): float = return ln(x) / ln(10.0)
|
||||
proc log2*(x: float): float = return ln(x) / ln(2.0)
|
||||
|
||||
proc exp*(x: float): float {.importc: "Math.exp", nodecl.}
|
||||
proc round*(x: float): int {.importc: "Math.round", nodecl.}
|
||||
proc pow*(x, y: float): float {.importc: "Math.pow", nodecl.}
|
||||
|
||||
proc frexp*(x: float, exponent: var int): float =
|
||||
if x == 0.0:
|
||||
exponent = 0.0
|
||||
result = 0.0
|
||||
elif x < 0.0:
|
||||
result = -frexp(-x, exponent)
|
||||
else:
|
||||
var ex = mathfloor(log2(x))
|
||||
exponent = round(ex)
|
||||
result = x / pow(2.0, ex)
|
||||
|
||||
proc arccos*(x: float): float {.importc: "Math.acos", nodecl.}
|
||||
proc arcsin*(x: float): float {.importc: "Math.asin", nodecl.}
|
||||
proc arctan*(x: float): float {.importc: "Math.atan", nodecl.}
|
||||
proc arctan2*(y, x: float): float {.importc: "Math.atan2", nodecl.}
|
||||
|
||||
proc cos*(x: float): float {.importc: "Math.cos", nodecl.}
|
||||
proc cosh*(x: float): float = return (exp(x)+exp(-x))*0.5
|
||||
proc hypot*(x, y: float): float = return sqrt(x*x + y*y)
|
||||
proc sinh*(x: float): float = return (exp(x)-exp(-x))*0.5
|
||||
proc tan*(x: float): float {.importc: "Math.tan", nodecl.}
|
||||
proc tanh*(x: float): float =
|
||||
var y = exp(2.0*x)
|
||||
return (y-1.0)/(y+1.0)
|
||||
|
||||
{.pop.}
|
||||
{.pop.}
|
||||
|
|
|
|||
209
lib/memman.nim
209
lib/memman.nim
|
|
@ -37,24 +37,24 @@ const
|
|||
realFli = MaxFli - fliOffset
|
||||
|
||||
type
|
||||
TFreePtr = record
|
||||
TFreePtr {.final.} = object
|
||||
prev, next: PBhdr
|
||||
Pbhdr = ptr Tbhdr
|
||||
Tbhdr = record
|
||||
Tbhdr {.final.} = object
|
||||
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
|
||||
TAreaInfo {.final.} = object # 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 {.final.} = object
|
||||
tlsf_signature: int32 # the TLSF's structure signature
|
||||
usedSize, maxSize: int
|
||||
areaHead: PAreaInfo # A linked list holding all the existing areas
|
||||
|
|
@ -147,6 +147,7 @@ elif defined(windows):
|
|||
if result == nil: raiseOutOfMem()
|
||||
|
||||
else:
|
||||
{.warning: "Generic code for allocating pages is used".}
|
||||
# generic implementation relying on malloc:
|
||||
proc malloc(size: int): pointer {.nodecl, importc.}
|
||||
|
||||
|
|
@ -155,6 +156,124 @@ else:
|
|||
result = malloc(size)
|
||||
if result == nil: raiseOutOfMem()
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# small fixed size allocator:
|
||||
|
||||
# Design: We manage pages. A page is of constant size, but not necessarily
|
||||
# the OS's page size. Pages are managed in a hash table taking advantage of
|
||||
# the fact that the OS is likely to give us pages with contingous numbers.
|
||||
# A page contains either small fixed size objects of the same size or
|
||||
# variable length objects. An object's size is always aligned at 16 byte
|
||||
# boundry. Huge objects are dealt with the TLSF algorithm.
|
||||
# The design supports iterating over any object in a fast way.
|
||||
|
||||
# A bitset contains any page that starts an allocated page. The page may be
|
||||
# empty however. This bitset can be used to quickly determine if a given
|
||||
# page belongs to the GC heap. The design of the memory allocator makes it
|
||||
# simple to return unused pages back to the OS.
|
||||
|
||||
|
||||
# Small bocks
|
||||
# -----------
|
||||
#
|
||||
# If we use a list in the free object's space. Allocation and deallocation are
|
||||
# O(1). Since any object is of the same size, iteration is quite efficient too.
|
||||
# However, pointer detection is easy too: Just check if the type-field is nil.
|
||||
# Deallocation sets it to nil.
|
||||
# Algorithm:
|
||||
|
||||
# i = 0
|
||||
# f = b.f # first free address
|
||||
# while i < max:
|
||||
# if a[i] == f: # not a valid block
|
||||
# f = f.next # next free address
|
||||
# else:
|
||||
# a[i] is a valid object of size s
|
||||
# inc(i)
|
||||
|
||||
# The zero count table is an array. Since we know that the RC is zero, we can
|
||||
# use the bits for an index into this array. Thus multiple ZCT tables are not
|
||||
# difficult to support and insertion and removal is O(1). We use negative
|
||||
# indexes for this. This makes it even fast enough (and necessary!) to do a ZCT
|
||||
# removal if the RC is incremented.
|
||||
#
|
||||
|
||||
# Huge blocks
|
||||
# -----------
|
||||
#
|
||||
# Huge blocks are always rounded up to a multiple of the page size. These are
|
||||
# called *strides*. We also need to keep an index structure
|
||||
# of (stridesize, pagelist).
|
||||
#
|
||||
|
||||
const
|
||||
MemAlign = 8
|
||||
PageShift = if sizeof(int) == 4: 12 else: 13
|
||||
PageSize = 1 shl PageShift
|
||||
type
|
||||
TFreeList {.final.} = object
|
||||
next, prev: ptr TFreeList
|
||||
|
||||
TPageDesc {.final.} = object # the start of a stride always starts with this!
|
||||
size: int # lowest bit is set, if it is a huge block
|
||||
free: ptr TFreeList # only used if it manages multiple cells
|
||||
snext, sprev: ptr TPageDesc # next and prev pagedescs with the same size
|
||||
|
||||
TCellArray {.final.} = object
|
||||
i: int # length
|
||||
d: ptr array [0..1000_000, TCell]
|
||||
|
||||
TPageManager = table[page, ptr TPageDesc]
|
||||
|
||||
TGcHeap {.final.} = object
|
||||
# structure that manages the garbage collected heap
|
||||
zct: TCellArray
|
||||
stackCells: TCellArray
|
||||
smallBlocks: array [PageSize div MemAlign, ptr TPageDesc]
|
||||
pages: TPageManager
|
||||
usedPages: TPageList
|
||||
freePages: TPageList
|
||||
|
||||
# small blocks:
|
||||
proc allocSmall(var h: TGcHeap, size: int): pointer =
|
||||
var s = align(size)
|
||||
var p = h.smallBlocks[s]
|
||||
if p == nil or p.free == nil:
|
||||
p = newSmallBlock(s, p)
|
||||
h.smallBlocks[s] = p
|
||||
|
||||
|
||||
|
||||
proc decRef(cell: PCell) {.inline.} =
|
||||
assert(cell in ct.AT)
|
||||
assert(cell.refcount > 0) # this should be the case!
|
||||
assert(seqCheck(cell))
|
||||
dec(cell.refcount)
|
||||
if cell.refcount == 0:
|
||||
# add to zero count table:
|
||||
zct.d[zct.i] = cell
|
||||
cell.recfcount = -zct.i
|
||||
inc(zct.i)
|
||||
|
||||
proc incRef(cell: PCell) {.inline.} =
|
||||
assert(seqCheck(cell))
|
||||
if cell.refcount < 0:
|
||||
# remove from zero count table:
|
||||
zct.d[-cell.refcount] = zct.d[zct.i-1]
|
||||
dec(zct.i)
|
||||
cell.refcount = 1
|
||||
else:
|
||||
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
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# helpers
|
||||
|
||||
|
|
@ -261,7 +380,7 @@ proc extractBlock(b: Pbhdr, t: var TLSF, fl, sl: int) {.inline.} =
|
|||
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:
|
||||
if t.matrix[fl][sl] != nil:
|
||||
t.matrix[fl][sl].freePtr.prev = b
|
||||
t.matrix[fl][sl] = b
|
||||
set_bit(sl, t.slBitmap[fl])
|
||||
|
|
@ -295,9 +414,6 @@ proc processArea(area: pointer, size: int): Pbhdr =
|
|||
# ----------------------------------------------------------------------------
|
||||
# Begin of the allocator code
|
||||
|
||||
var
|
||||
mp: pointer # default memory pool.
|
||||
|
||||
proc initMemoryPool(memPoolSize: int, memPool: pointer): int =
|
||||
var
|
||||
t: PLSF
|
||||
|
|
@ -307,16 +423,14 @@ proc initMemoryPool(memPoolSize: int, memPool: pointer): int =
|
|||
writeToStdErr("initMemoryPool(): memory_pool invalid\n")
|
||||
return -1
|
||||
|
||||
if (memPool and ptrMask) != 0:
|
||||
if (cast[TAddress](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)))
|
||||
b = getNextBlock(memPool, roundupSize(sizeof(TLSF)))
|
||||
return b.size and blockSize
|
||||
mp = memPool
|
||||
zeroMem(memPool, sizeof(TLSF))
|
||||
|
||||
t.signature = tlsfSignature
|
||||
|
|
@ -456,7 +570,7 @@ proc freeEx(p: pointer, t: var TLSF) =
|
|||
b.freePtr.prev = nil
|
||||
b.freePtr.next = nil
|
||||
tmpB = getNextBlock(getBuffer(b), b.size and blockSize)
|
||||
if tmpB.size and freeBlock != 0:
|
||||
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)
|
||||
|
|
@ -549,51 +663,30 @@ proc ansiCrealloc(p: pointer, newSize: int, t: var TLSF): pointer =
|
|||
else:
|
||||
result = reallocEx(p, newSize, t)
|
||||
|
||||
proc InitTLSF(t: var TLSF) =
|
||||
var areaSize = sizeof(TLSF) + BHDR_OVERHEAD * 8 # Just a safety constant
|
||||
areaSize = max(areaSize, DEFAULT_areaSize)
|
||||
var area = getNewArea(areaSize)
|
||||
|
||||
|
||||
initMemoryPool(areaSize, area)
|
||||
|
||||
void *tlsf_malloc(size_t size)
|
||||
{
|
||||
void *ret
|
||||
var
|
||||
t: PLSF
|
||||
b, ib: Pbhdr
|
||||
|
||||
#if USE_MMAP || USE_SBRK
|
||||
if (!mp) {
|
||||
size_t areaSize
|
||||
void *area
|
||||
t = cast[PLSF](memPool)
|
||||
|
||||
zeroMem(area, areaSize)
|
||||
|
||||
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
|
||||
t.signature = tlsfSignature
|
||||
var ib = processArea(getNextBlock(memPool, roundupSize(sizeof(TLSF))),
|
||||
rounddownSize(memPoolSize - sizeof(TLSF)))
|
||||
var b = getNextBlock(getBuffer(ib), ib.size and blockSize)
|
||||
freeEx(getBuffer(b), t)
|
||||
t.areaHead = cast[PAreaInfo](getBuffer(ib))
|
||||
|
||||
TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock)
|
||||
t.used_size = memPoolSize - (b.size and blockSize)
|
||||
t.max_size = t.used_size
|
||||
|
||||
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
|
||||
}
|
||||
# XXX
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
|
||||
Nimrod's Runtime Library
|
||||
(c) Copyright 2006 Andreas Rumpf
|
||||
(c) Copyright 2008 Andreas Rumpf
|
||||
|
||||
See the file "copying.txt", included in this
|
||||
distribution, for details about the copyright.
|
||||
|
|
@ -11,7 +11,8 @@
|
|||
#define NIMBASE_H
|
||||
|
||||
/* calling convention mess ----------------------------------------------- */
|
||||
#if defined(__GNUC__) || defined(__LCC__) || defined(__POCC__)
|
||||
#if defined(__GNUC__) || defined(__LCC__) || defined(__POCC__) \
|
||||
|| defined(__TINYC__)
|
||||
/* 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. */
|
||||
|
|
@ -30,10 +31,18 @@
|
|||
# define N_INLINE(rettype, name) rettype __inline name
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(__POCC__) || defined(_MSC_VER)
|
||||
# define HAVE_LRINT 1
|
||||
#endif
|
||||
|
||||
#if defined(__POCC__)
|
||||
# define NIM_CONST /* PCC is really picky with const modifiers */
|
||||
#elif defined(__cplusplus)
|
||||
# define NIM_CONST /* C++ is picky with const modifiers */
|
||||
#else
|
||||
# define NIM_CONST const
|
||||
#endif
|
||||
|
||||
/* --------------- how int64 constants should be declared: ----------- */
|
||||
#if defined(__GNUC__) || defined(__LCC__) || \
|
||||
defined(__POCC__) || defined(__DMC__)
|
||||
|
|
@ -136,8 +145,7 @@
|
|||
** long int lrint (double x);
|
||||
*/
|
||||
|
||||
#if defined(__LCC__) || defined(__POCC__) \
|
||||
|| (defined(__GNUC__) && defined(WIN32))
|
||||
#if defined(__LCC__) || (defined(__GNUC__) && defined(WIN32))
|
||||
/* Linux' GCC does not seem to have these. Why? */
|
||||
# define HAVE_LRINT
|
||||
# define HAVE_LRINTF
|
||||
|
|
@ -159,7 +167,7 @@
|
|||
# include <math.h>
|
||||
|
||||
#elif (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) \
|
||||
&& !defined(__BORLANDC__)
|
||||
&& !defined(__BORLANDC__) && !defined(__POCC__)
|
||||
|
||||
# include <math.h>
|
||||
|
||||
|
|
@ -206,6 +214,17 @@ static N_INLINE(long int, lrintf)(float flt) {
|
|||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#ifndef NAN
|
||||
static unsigned long nimNaN[2]={0xffffffff, 0x7fffffff};
|
||||
# define NAN (*(double*) nimNaN)
|
||||
#endif
|
||||
|
||||
/*
|
||||
#ifndef INF
|
||||
static unsigned long nimInf[2]={0xffffffff, 0x7fffffff};
|
||||
# define INF (*(double*) nimInf)
|
||||
#endif */
|
||||
|
||||
/* compiler symbols:
|
||||
__BORLANDC__
|
||||
_MSC_VER
|
||||
|
|
@ -214,6 +233,7 @@ __LCC__
|
|||
__GNUC__
|
||||
__DMC__
|
||||
__POCC__
|
||||
__TINYC__
|
||||
*/
|
||||
|
||||
/* C99 compiler? */
|
||||
|
|
@ -250,50 +270,41 @@ __POCC__
|
|||
#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 */
|
||||
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 int8_t NI8;
|
||||
typedef int16_t NI16;
|
||||
typedef int32_t NI32;
|
||||
typedef int64_t NI64;
|
||||
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;
|
||||
typedef signed char NI8;
|
||||
typedef signed short int NI16;
|
||||
typedef signed int NI32;
|
||||
/* XXX: Float128? */
|
||||
typedef unsigned char NU8;
|
||||
typedef unsigned short int NU16;
|
||||
typedef unsigned __int64 NU64;
|
||||
typedef __int64 NS64;
|
||||
typedef __int64 NI64;
|
||||
typedef unsigned int NU32;
|
||||
#else
|
||||
typedef signed char NS8;
|
||||
typedef signed short int NS16;
|
||||
typedef signed int NS32;
|
||||
typedef signed char NI8;
|
||||
typedef signed short int NI16;
|
||||
typedef signed int NI32;
|
||||
/* XXX: Float128? */
|
||||
typedef unsigned char NU8;
|
||||
typedef unsigned short int NU16;
|
||||
typedef unsigned long long int NU64;
|
||||
typedef long long int NS64;
|
||||
typedef long long int NI64;
|
||||
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;
|
||||
|
|
@ -307,13 +318,13 @@ typedef char* NCSTRING;
|
|||
# define NIM_IMAN 0
|
||||
#endif
|
||||
|
||||
static N_INLINE(NS32, float64ToInt32)(double val) {
|
||||
static N_INLINE(NI32, 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 */
|
||||
return ((NI32*)&val)[NIM_IMAN] >> 16; /* 16.16 fixed point representation */
|
||||
}
|
||||
|
||||
static N_INLINE(NS32, float32ToInt32)(float val) {
|
||||
static N_INLINE(NI32, float32ToInt32)(float val) {
|
||||
return float64ToInt32((double)val);
|
||||
}
|
||||
|
||||
|
|
@ -322,7 +333,7 @@ static N_INLINE(NS32, float32ToInt32)(float val) {
|
|||
|
||||
#define STRING_LITERAL(name, str, length) \
|
||||
static const struct { \
|
||||
NS len, space; \
|
||||
NI len, space; \
|
||||
NIM_CHAR data[length + 1]; \
|
||||
} name = {length, length, str}
|
||||
|
||||
|
|
@ -357,7 +368,7 @@ typedef struct TStringDesc* string;
|
|||
/*
|
||||
typedef struct TSafePoint TSafePoint;
|
||||
struct TSafePoint {
|
||||
NS exc;
|
||||
NI exc;
|
||||
NCSTRING excname;
|
||||
NCSTRING msg;
|
||||
TSafePoint* prev;
|
||||
|
|
@ -368,19 +379,19 @@ typedef struct TFrame TFrame;
|
|||
struct TFrame {
|
||||
TFrame* prev;
|
||||
NCSTRING procname;
|
||||
NS line;
|
||||
NI line;
|
||||
NCSTRING filename;
|
||||
NS len;
|
||||
NI len;
|
||||
};
|
||||
|
||||
extern TFrame* volatile framePtr;
|
||||
/*extern TSafePoint* volatile excHandler; */
|
||||
extern TFrame* framePtr;
|
||||
/*extern TSafePoint* excHandler; */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
struct NimException {
|
||||
TSafePoint sp;
|
||||
|
||||
NimException(NS aExc, NCSTRING aExcname, NCSTRING aMsg) {
|
||||
NimException(NI aExc, NCSTRING aExcname, NCSTRING aMsg) {
|
||||
sp.exc = aExc; sp.excname = aExcname; sp.msg = aMsg;
|
||||
sp.prev = excHandler;
|
||||
excHandler = &sp;
|
||||
|
|
@ -389,13 +400,13 @@ struct NimException {
|
|||
#endif
|
||||
|
||||
typedef struct TStringDesc {
|
||||
NS len;
|
||||
NS space;
|
||||
NI len;
|
||||
NI space;
|
||||
NIM_CHAR data[1]; /* SEQ_DECL_SIZE]; */
|
||||
} TStringDesc;
|
||||
|
||||
typedef struct {
|
||||
NS len, space;
|
||||
NI len, space;
|
||||
} TGenericSeq;
|
||||
|
||||
typedef TGenericSeq* PGenericSeq;
|
||||
|
|
|
|||
|
|
@ -1,39 +0,0 @@
|
|||
#
|
||||
#
|
||||
# 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.}
|
||||
90
lib/os.nim
90
lib/os.nim
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
# (c) Copyright 2008 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
|
|
@ -10,7 +10,9 @@
|
|||
## 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.
|
||||
## platform independant. However, the ECMAScript target is not supported,
|
||||
## as there is no way to perform these operations in ECMAScript portably
|
||||
## or at all.
|
||||
|
||||
{.push debugger:off.}
|
||||
|
||||
|
|
@ -18,7 +20,7 @@ import
|
|||
strutils, times
|
||||
|
||||
# copied from excpt.nim, because I don't want to make this template public
|
||||
template newException(exceptn, message: expr): expr =
|
||||
template newException(exceptn, message: expr): expr =
|
||||
block: # open a new scope
|
||||
var
|
||||
e: ref exceptn
|
||||
|
|
@ -294,7 +296,7 @@ proc existsDir*(dir: string): bool
|
|||
proc getLastModificationTime*(file: string): TTime
|
||||
## Gets the time of the `file`'s last modification.
|
||||
|
||||
proc fileNewer*(a, b: string): bool
|
||||
proc fileNewer*(a, b: string): bool
|
||||
## returns true if the file `a` is newer than file `b`, i.e. if `a`'s
|
||||
## modification time is later than `b`'s.
|
||||
|
||||
|
|
@ -371,8 +373,11 @@ proc UnixToNativePath(path: string): string =
|
|||
|
||||
# interface to C library:
|
||||
|
||||
const
|
||||
cunder = if defined(pcc): "_" else: ""
|
||||
|
||||
type
|
||||
TStat {.importc: "struct stat".} = record
|
||||
TStat {.importc: "struct " & cunder & "stat", final.} = object
|
||||
st_dev: int16
|
||||
st_ino: int16
|
||||
st_mode: int16
|
||||
|
|
@ -397,7 +402,8 @@ else:
|
|||
{.error: "os library not ported to your OS. Please help!".}
|
||||
|
||||
|
||||
proc chdir(path: CString): cint {.importc: "chdir", header: dirHeader.}
|
||||
proc chdir(path: CString): cint {.
|
||||
importc: cunder & "chdir", header: dirHeader.}
|
||||
|
||||
when defined(unix):
|
||||
proc mkdir(dir: CString, theAccess: cint): cint {.
|
||||
|
|
@ -412,7 +418,7 @@ elif defined(windows):
|
|||
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>".}
|
||||
importc: cunder & "getcwd", header: "<direct.h>".}
|
||||
|
||||
proc CreateDirectory(pathName: cstring, security: Pointer): cint {.
|
||||
importc: "CreateDirectory", header: "<windows.h>".}
|
||||
|
|
@ -421,7 +427,8 @@ else:
|
|||
{.error: "os library not ported to your OS. Please help!".}
|
||||
|
||||
|
||||
proc rmdir(dir: CString): cint {.importc: "rmdir", header: "<time.h>".}
|
||||
proc rmdir(dir: CString): cint {.
|
||||
importc: cunder & "rmdir", header: "<time.h>".}
|
||||
# rmdir is of course in ``dirHeader``, but we check here to include
|
||||
# time.h which is needed for stat(). stat() needs time.h and
|
||||
# sys/stat.h; we workaround a C library issue here.
|
||||
|
|
@ -432,17 +439,7 @@ proc free(c: cstring) {.importc: "free", nodecl.}
|
|||
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
|
||||
importc: cunder & "stat", header: "<sys/stat.h>".}
|
||||
|
||||
when defined(windows):
|
||||
proc getModuleFilename(handle: int32, buf: CString, size: int32): int32 {.
|
||||
|
|
@ -456,13 +453,13 @@ proc getLastModificationTime(file: string): TTime =
|
|||
|
||||
proc setCurrentDir(newDir: string) =
|
||||
if chdir(newDir) != 0:
|
||||
raise newException(EOS, "cannot change the working directory to '$1'" %
|
||||
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)
|
||||
|
|
@ -473,6 +470,13 @@ when defined(linux) or defined(solaris) or defined(bsd):
|
|||
|
||||
when defined(solaris) or defined(bsd):
|
||||
proc getpid(): int {.importc, header: "<unistd.h>", cdecl.}
|
||||
elif defined(macosx):
|
||||
# a really hacky solution: since we like to include 2 headers we have to
|
||||
# define two procs which in reality are the same
|
||||
proc getExecPath1(c: cstring, size: var int32) {.
|
||||
importc: "_NSGetExecutablePath", header: "<sys/param.h>".}
|
||||
proc getExecPath2(c: cstring, size: var int32): bool {.
|
||||
importc: "_NSGetExecutablePath", header: "<mach-o/dyld.h>".}
|
||||
|
||||
proc getApplicationFilename(): string =
|
||||
# Linux: /proc/<pid>/exe
|
||||
|
|
@ -491,6 +495,12 @@ proc getApplicationFilename(): string =
|
|||
result = getApplAux("/proc/" & $getpid() & "/path/a.out")
|
||||
elif defined(bsd):
|
||||
result = getApplAux("/proc/" & $getpid() & "file")
|
||||
elif defined(macosx):
|
||||
var size: int32
|
||||
getExecPath1(nil, size)
|
||||
result = newString(int(size))
|
||||
if getExecPath2(result, size):
|
||||
result = "" # error!
|
||||
else:
|
||||
# little heuristic that may work on other POSIX-like systems:
|
||||
result = getEnv("_")
|
||||
|
|
@ -612,7 +622,7 @@ when defined(wcc):
|
|||
proc cputenv(env: CString): cint {.importc: "putenv", header: "<process.h>".}
|
||||
|
||||
else: # is in <stdlib.h>
|
||||
proc cputenv(env: CString): cint {.importc: "putenv", noDecl.}
|
||||
proc cputenv(env: CString): cint {.importc: cunder & "putenv", noDecl.}
|
||||
|
||||
proc cgetenv(env: CString): CString {.importc: "getenv", noDecl.}
|
||||
|
||||
|
|
@ -621,7 +631,7 @@ proc cgetenv(env: CString): CString {.importc: "getenv", noDecl.}
|
|||
#int _findclose(long);
|
||||
when defined(windows):
|
||||
type
|
||||
TFindData {.importc: "struct _finddata_t".} = record
|
||||
TFindData {.importc: "struct _finddata_t", final.} = object
|
||||
attrib {.importc: "attrib".}: cint
|
||||
time_create {.importc: "time_create".}: cint
|
||||
time_access {.importc: "time_access".}: cint
|
||||
|
|
@ -636,7 +646,7 @@ when defined(windows):
|
|||
proc findclose(handle: cint) {.importc: "_findclose", header: "<io.h>".}
|
||||
else:
|
||||
type
|
||||
TFindData {.importc: "glob_t".} = record
|
||||
TFindData {.importc: "glob_t", final.} = object
|
||||
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
|
||||
|
|
@ -649,6 +659,30 @@ else:
|
|||
proc globfree(pglob: PFindData) {.
|
||||
importc: "globfree", header: "<glob.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.
|
||||
when defined(Windows):
|
||||
var
|
||||
a, b: TFindData
|
||||
var resA = findfirst(path1, addr(a))
|
||||
var resB = findfirst(path2, addr(b))
|
||||
if resA != -1 and resB != -1:
|
||||
result = $a.name == $b.name
|
||||
else:
|
||||
# work around some ``findfirst`` bugs
|
||||
result = cmpPaths(path1, path2) == 0
|
||||
if resA != -1: findclose(resA)
|
||||
if resB != -1: findclose(resB)
|
||||
else:
|
||||
var
|
||||
a, b: TStat
|
||||
if stat(path1, a) < 0 or stat(path2, b) < 0:
|
||||
result = cmpPaths(path1, path2) == 0 # be consistent with Windows
|
||||
else:
|
||||
result = int(a.st_dev) == b.st_dev and int(a.st_ino) == b.st_ino
|
||||
|
||||
proc cremove(filename: CString): cint {.importc: "remove", noDecl.}
|
||||
proc crename(oldname, newname: CString): cint {.importc: "rename", noDecl.}
|
||||
|
||||
|
|
@ -776,9 +810,9 @@ proc findEnvVar(key: string): int =
|
|||
|
||||
proc getEnv(key: string): string =
|
||||
var i = findEnvVar(key)
|
||||
if i >= 0:
|
||||
if i >= 0:
|
||||
return copy(environment[i], findSubStr("=", environment[i])+1)
|
||||
else:
|
||||
else:
|
||||
var env = cgetenv(key)
|
||||
if env == nil: return ""
|
||||
result = $env
|
||||
|
|
@ -787,7 +821,7 @@ proc existsEnv(key: string): bool =
|
|||
if cgetenv(key) != nil: return true
|
||||
else: return findEnvVar(key) >= 0
|
||||
|
||||
iterator iterOverEnvironment*(): tuple[string, string] =
|
||||
iterator iterOverEnvironment*(): tuple[key, value: 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()
|
||||
|
|
@ -798,7 +832,7 @@ iterator iterOverEnvironment*(): tuple[string, string] =
|
|||
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
|
||||
# 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:
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
## This is a raw POSIX interface module. It does not not provide any
|
||||
## convenience: cstrings are used instead of proper Nimrod strings and
|
||||
## return codes indicate errors. If you want exceptions
|
||||
## and a proper Nimrod-like interface, use the OS module.
|
||||
## and a proper Nimrod-like interface, use the OS module or write a wrapper.
|
||||
|
||||
## Coding conventions:
|
||||
## ALL types are named the same as in the POSIX standard except that they start
|
||||
|
|
@ -60,7 +60,7 @@ const
|
|||
STDOUT_FILENO = 1 ## File number of stdout;
|
||||
|
||||
type
|
||||
Taiocb* {.importc: "struct aiocb", header: "<aio.h>".} = record
|
||||
Taiocb* {.importc: "struct aiocb", header: "<aio.h>", final.} = object
|
||||
aio_fildes*: cint ## File descriptor.
|
||||
aio_offset*: TOff ## File offset.
|
||||
aio_buf*: pointer ## Location of buffer.
|
||||
|
|
@ -69,14 +69,14 @@ type
|
|||
aio_sigevent*: TSigEvent ## Signal number and value.
|
||||
aio_lio_opcode: cint ## Operation to be performed.
|
||||
|
||||
TDIR* {.importc: "DIR", header: "<dirent.h>".} = record
|
||||
TDIR* {.importc: "DIR", header: "<dirent.h>", final.} = object
|
||||
## A type representing a directory stream.
|
||||
|
||||
Tdirent* {.importc: "struct dirent", header: "<dirent.h>".} = record
|
||||
Tdirent* {.importc: "struct dirent", header: "<dirent.h>", final.} = object
|
||||
d_ino*: TIno ## File serial number.
|
||||
d_name*: array [0..255, char] ## Name of entry.
|
||||
|
||||
Tflock* {.importc: "flock", header: "<fcntl>".} = record
|
||||
Tflock* {.importc: "flock", header: "<fcntl>", final.} = object
|
||||
l_type*: cshort ## Type of lock; F_RDLCK, F_WRLCK, F_UNLCK.
|
||||
l_whence*: cshort ## Flag for starting offset.
|
||||
l_start*: Toff ## Relative offset in bytes.
|
||||
|
|
@ -84,13 +84,13 @@ type
|
|||
l_pid*: TPid ## Process ID of the process holding the lock;
|
||||
## returned with F_GETLK.
|
||||
|
||||
Tfenv* {.importc: "fenv_t", header: "<fenv.h>".} =
|
||||
record ## Represents the entire floating-point environment. The
|
||||
Tfenv* {.importc: "fenv_t", header: "<fenv.h>", final.} =
|
||||
object ## Represents the entire floating-point environment. The
|
||||
## floating-point environment refers collectively to any
|
||||
## floating-point status flags and control modes supported
|
||||
## by the implementation.
|
||||
Tfexcept* {.importc: "fexcept_t", header: "<fenv.h>".} =
|
||||
record ## Represents the floating-point status flags collectively,
|
||||
Tfexcept* {.importc: "fexcept_t", header: "<fenv.h>", final.} =
|
||||
object ## Represents the floating-point status flags collectively,
|
||||
## including any status the implementation associates with the
|
||||
## flags. A floating-point status flag is a system variable
|
||||
## whose value is set (but never cleared) when a floating-point
|
||||
|
|
@ -100,25 +100,25 @@ type
|
|||
## whose value may be set by the user to affect the subsequent
|
||||
## behavior of floating-point arithmetic.
|
||||
|
||||
TFTW* {.importc: "struct FTW", header: "<ftw.h>".} = record
|
||||
TFTW* {.importc: "struct FTW", header: "<ftw.h>", final.} = object
|
||||
base*: cint
|
||||
level*: cint
|
||||
|
||||
TGlob* {.importc: "glob_t", header: "<glob.h>".} = record
|
||||
TGlob* {.importc: "glob_t", header: "<glob.h>", final.} = object
|
||||
gl_pathc*: int ## Count of paths matched by pattern.
|
||||
gl_pathv*: ptr cstring ## Pointer to a list of matched pathnames.
|
||||
gl_offs*: int ## Slots to reserve at the beginning of gl_pathv.
|
||||
|
||||
TGroup* {.importc: "struct group", header: "<grp.h>".} = record
|
||||
TGroup* {.importc: "struct group", header: "<grp.h>", final.} = object
|
||||
gr_name*: cstring ## The name of the group.
|
||||
gr_gid*: TGid ## Numerical group ID.
|
||||
gr_mem*: cstringArray ## Pointer to a null-terminated array of character
|
||||
## pointers to member names.
|
||||
|
||||
Ticonv* {.importc: "iconv_t", header: "<iconv.h>".} =
|
||||
record ## Identifies the conversion from one codeset to another.
|
||||
Ticonv* {.importc: "iconv_t", header: "<iconv.h>", final.} =
|
||||
object ## Identifies the conversion from one codeset to another.
|
||||
|
||||
Tlconv* {.importc: "struct lconv", header: "<locale.h>".} = record
|
||||
Tlconv* {.importc: "struct lconv", header: "<locale.h>", final.} = object
|
||||
currency_symbol*: cstring
|
||||
decimal_point*: cstring
|
||||
frac_digits*: char
|
||||
|
|
@ -144,14 +144,14 @@ type
|
|||
p_sign_posn*: char
|
||||
thousands_sep*: cstring
|
||||
|
||||
TMqd* {.importc: "mqd_t", header: "<mqueue.h>".} = record
|
||||
TMqAttr* {.importc: "struct mq_attr", header: "<mqueue.h>".} = record
|
||||
TMqd* {.importc: "mqd_t", header: "<mqueue.h>", final.} = object
|
||||
TMqAttr* {.importc: "struct mq_attr", header: "<mqueue.h>", final.} = object
|
||||
mq_flags*: int ## Message queue flags.
|
||||
mq_maxmsg*: int ## Maximum number of messages.
|
||||
mq_msgsize*: int ## Maximum message size.
|
||||
mq_curmsgs*: int ## Number of messages currently queued.
|
||||
|
||||
TPasswd* {.importc: "struct passwd", header: "<pwd.h>".} = record
|
||||
TPasswd* {.importc: "struct passwd", header: "<pwd.h>", final.} = object
|
||||
pw_name*: cstring ## User's login name.
|
||||
pw_uid*: TUid ## Numerical user ID.
|
||||
pw_gid*: TGid ## Numerical group ID.
|
||||
|
|
@ -198,7 +198,7 @@ type
|
|||
Tuid* {.importc: "uid_t", header: "<sys/types.h>".} = int
|
||||
Tuseconds* {.importc: "useconds_t", header: "<sys/types.h>".} = int
|
||||
|
||||
Tutsname* {.importc: "struct utsname", header: "<sys/utsname.h>".} = record
|
||||
Tutsname* {.importc: "struct utsname", header: "<sys/utsname.h>", final.} = object
|
||||
sysname*, ## Name of this implementation of the operating system.
|
||||
nodename*, ## Name of this node within the communications
|
||||
## network to which this node is attached, if any.
|
||||
|
|
@ -207,15 +207,15 @@ type
|
|||
machine*: array [0..255, char] ## Name of the hardware type on which the
|
||||
## system is running.
|
||||
|
||||
TSem* {.importc: "sem_t", header: "<semaphore.h>".} = record
|
||||
Tipc_perm* {.importc: "struct ipc_perm", header: "<sys/ipc.h>".} = record
|
||||
TSem* {.importc: "sem_t", header: "<semaphore.h>", final.} = object
|
||||
Tipc_perm* {.importc: "struct ipc_perm", header: "<sys/ipc.h>", final.} = object
|
||||
uid*: tuid ## Owner's user ID.
|
||||
gid*: tgid ## Owner's group ID.
|
||||
cuid*: Tuid ## Creator's user ID.
|
||||
cgid*: Tgid ## Creator's group ID.
|
||||
mode*: TMode ## Read/write permission.
|
||||
|
||||
TStat* {.importc: "struct stat", header: "<sys/stat.h>".} = record
|
||||
TStat* {.importc: "struct stat", header: "<sys/stat.h>", final.} = object
|
||||
st_dev*: TDev ## Device ID of device containing file.
|
||||
st_ino*: TIno ## File serial number.
|
||||
st_mode*: TMode ## Mode of file (see below).
|
||||
|
|
@ -239,7 +239,7 @@ type
|
|||
st_blocks*: Tblkcnt ## Number of blocks allocated for this object.
|
||||
|
||||
|
||||
TStatvfs* {.importc: "struct statvfs", header: "<sys/statvfs.h>".} = record
|
||||
TStatvfs* {.importc: "struct statvfs", header: "<sys/statvfs.h>", final.} = object
|
||||
f_bsize*: int ## File system block size.
|
||||
f_frsize*: int ## Fundamental file system block size.
|
||||
f_blocks*: Tfsblkcnt ## Total number of blocks on file system in units of f_frsize.
|
||||
|
|
@ -255,10 +255,10 @@ type
|
|||
f_namemax*: int ## Maximum filename length.
|
||||
|
||||
Tposix_typed_mem_info* {.importc: "struct posix_typed_mem_info",
|
||||
header: "<sys/mman.h>".} = record
|
||||
header: "<sys/mman.h>", final.} = object
|
||||
posix_tmi_length*: int
|
||||
|
||||
Ttm* {.importc: "struct tm", header: "<time.h>".} = record
|
||||
Ttm* {.importc: "struct tm", header: "<time.h>", final.} = object
|
||||
tm_sec*: cint ## Seconds [0,60].
|
||||
tm_min*: cint ## Minutes [0,59].
|
||||
tm_hour*: cint ## Hour [0,23].
|
||||
|
|
@ -268,10 +268,10 @@ type
|
|||
tm_wday*: cint ## Day of week [0,6] (Sunday =0).
|
||||
tm_yday*: cint ## Day of year [0,365].
|
||||
tm_isdst*: cint ## Daylight Savings flag.
|
||||
Ttimespec* {.importc: "struct timespec", header: "<time.h>".} = record
|
||||
Ttimespec* {.importc: "struct timespec", header: "<time.h>", final.} = object
|
||||
tv_sec*: Ttime ## Seconds.
|
||||
tv_nsec*: int ## Nanoseconds.
|
||||
titimerspec* {.importc: "struct itimerspec", header: "<time.h>".} = record
|
||||
titimerspec* {.importc: "struct itimerspec", header: "<time.h>", final.} = object
|
||||
it_interval*: ttimespec ## Timer period.
|
||||
it_value*: ttimespec ## Timer expiration.
|
||||
|
||||
|
|
@ -279,19 +279,19 @@ type
|
|||
## Possibly volatile-qualified integer type of an object that can be
|
||||
## accessed as an atomic entity, even in the presence of asynchronous
|
||||
## interrupts.
|
||||
Tsigset* {.importc: "sigset_t", header: "<signal.h>".} = record
|
||||
Tsigset* {.importc: "sigset_t", header: "<signal.h>", final.} = object
|
||||
|
||||
TsigEvent* {.importc: "struct sigevent", header: "<signal.h>".} = record
|
||||
TsigEvent* {.importc: "struct sigevent", header: "<signal.h>", final.} = object
|
||||
sigev_notify*: cint ## Notification type.
|
||||
sigev_signo*: cint ## Signal number.
|
||||
sigev_value*: Tsigval ## Signal value.
|
||||
sigev_notify_function*: proc (x: TSigval) {.noconv.} ## Notification function.
|
||||
sigev_notify_attributes*: ptr Tpthreadattr ## Notification attributes.
|
||||
|
||||
TsigVal* {.importc: "union sigval", header: "<signal.h>".} = record
|
||||
TsigVal* {.importc: "union sigval", header: "<signal.h>", final.} = object
|
||||
sival_ptr*: pointer ## pointer signal value;
|
||||
## integer signal value not defined!
|
||||
TSigaction* {.importc: "struct sigaction", header: "<signal.h>".} = record
|
||||
TSigaction* {.importc: "struct sigaction", header: "<signal.h>", final.} = object
|
||||
sa_handler*: proc (x: cint) {.noconv.} ## Pointer to a signal-catching
|
||||
## function or one of the macros
|
||||
## SIG_IGN or SIG_DFL.
|
||||
|
|
@ -300,16 +300,16 @@ type
|
|||
sa_flags*: cint ## Special flags.
|
||||
sa_sigaction*: proc (x: cint, y: var TSigInfo, z: pointer) {.noconv.}
|
||||
|
||||
TStack* {.importc: "stack_t", header: "<signal.h>".} = record
|
||||
TStack* {.importc: "stack_t", header: "<signal.h>", final.} = object
|
||||
ss_sp*: pointer ## Stack base or pointer.
|
||||
ss_size*: int ## Stack size.
|
||||
ss_flags*: cint ## Flags.
|
||||
|
||||
TSigStack* {.importc: "struct sigstack", header: "<signal.h>".} = record
|
||||
TSigStack* {.importc: "struct sigstack", header: "<signal.h>", final.} = object
|
||||
ss_onstack*: cint ## Non-zero when signal stack is in use.
|
||||
ss_sp*: pointer ## Signal stack pointer.
|
||||
|
||||
TsigInfo* {.importc: "siginfo_t", header: "<signal.h>".} = record
|
||||
TsigInfo* {.importc: "siginfo_t", header: "<signal.h>", final.} = object
|
||||
si_signo*: cint ## Signal number.
|
||||
si_code*: cint ## Signal code.
|
||||
si_errno*: cint ## If non-zero, an errno value associated with
|
||||
|
|
@ -324,7 +324,7 @@ type
|
|||
Tnl_item* {.importc: "nl_item", header: "<nl_types.h>".} = cint
|
||||
Tnl_catd* {.importc: "nl_catd", header: "<nl_types.h>".} = cint
|
||||
|
||||
Tsched_param* {.importc: "struct sched_param", header: "<sched.h>".} = record
|
||||
Tsched_param* {.importc: "struct sched_param", header: "<sched.h>", final.} = object
|
||||
sched_priority*: cint
|
||||
sched_ss_low_priority*: cint ## Low scheduling priority for
|
||||
## sporadic server.
|
||||
|
|
@ -334,15 +334,15 @@ type
|
|||
sched_ss_max_repl*: cint ## Maximum pending replenishments for
|
||||
## sporadic server.
|
||||
|
||||
Ttimeval* {.importc: "struct timeval", header: "<sys/select.h>".} = record
|
||||
Ttimeval* {.importc: "struct timeval", header: "<sys/select.h>", final.} = object
|
||||
tv_sec*: ttime ## Seconds.
|
||||
tv_usec*: tsuseconds ## Microseconds.
|
||||
Tfd_set* {.importc: "struct fd_set", header: "<sys/select.h>".} = record
|
||||
Tfd_set* {.importc: "struct fd_set", header: "<sys/select.h>", final.} = object
|
||||
|
||||
Tposix_spawnattr* {.importc: "posix_spawnattr_t", header: "<spawn.h>".} = cint
|
||||
Tposix_spawn_file_actions* {.importc: "posix_spawn_file_actions_t", header: "<spawn.h>".} = cint
|
||||
Tmcontext* {.importc: "mcontext_t", header: "<ucontext.h>".} = record
|
||||
Tucontext* {.importc: "ucontext_t", header: "<ucontext.h>".} = record
|
||||
Tmcontext* {.importc: "mcontext_t", header: "<ucontext.h>", final.} = object
|
||||
Tucontext* {.importc: "ucontext_t", header: "<ucontext.h>", final.} = object
|
||||
uc_link*: ptr Tucontext ## Pointer to the context that is resumed
|
||||
## when this context returns.
|
||||
uc_sigmask*: Tsigset ## The set of signals that are blocked when this
|
||||
|
|
@ -729,7 +729,7 @@ var
|
|||
GLOB_NOSORT* {.importc, header: "<glob.h>".}: cint
|
||||
## Do not sort the pathnames returned.
|
||||
GLOB_ABORTED* {.importc, header: "<glob.h>".}: cint
|
||||
## The scan was stopped because GLOB_ERR was set or (*errfunc)()
|
||||
## The scan was stopped because GLOB_ERR was set or errfunc()
|
||||
## returned non-zero.
|
||||
GLOB_NOMATCH* {.importc, header: "<glob.h>".}: cint
|
||||
## The pattern does not match any existing pathname, and GLOB_NOCHECK
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
# (c) Copyright 2008 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ type
|
|||
PPointer = ptr pointer
|
||||
|
||||
TCollectorData = int
|
||||
TCell = record
|
||||
TCell {.final.} = object
|
||||
refcount: TCollectorData # the refcount and bit flags
|
||||
typ: PNimType
|
||||
stackcount: int # stack counter for debugging
|
||||
|
|
@ -67,18 +67,18 @@ type
|
|||
|
||||
TBitIndex = range[0..UnitsPerPage-1]
|
||||
|
||||
TPageDesc = record
|
||||
TPageDesc {.final.} = object
|
||||
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
|
||||
TCellSet {.final.} = object
|
||||
counter, max: int
|
||||
head: PPageDesc
|
||||
data: PPageDescArray
|
||||
|
||||
TSetNode = record
|
||||
TSetNode {.final.} = object
|
||||
n: array[0.. (1 shl bitsPerNode)-1, PSetNode]
|
||||
PSetNode = ptr TSetNode
|
||||
|
||||
|
|
|
|||
480
lib/repr.nim
480
lib/repr.nim
|
|
@ -1,233 +1,247 @@
|
|||
#
|
||||
#
|
||||
# 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)
|
||||
#
|
||||
#
|
||||
# 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 = 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 {.final.} = object # 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 tyTuple, tyPureObject: reprRecord(result, p, typ, cl)
|
||||
of tyObject:
|
||||
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 reprOpenArray(p: pointer, length: int, elemtyp: PNimType): string {.
|
||||
compilerproc.} =
|
||||
var
|
||||
cl: TReprClosure
|
||||
initReprClosure(cl)
|
||||
result = "["
|
||||
var bs = elemtyp.size
|
||||
for i in 0..length - 1:
|
||||
if i > 0: add result, ", "
|
||||
reprAux(result, cast[pointer](cast[TAddress](p) + i*bs), elemtyp, cl)
|
||||
add result, "]"
|
||||
deinitReprClosure(cl)
|
||||
|
||||
proc reprAny(p: pointer, typ: PNimType): string =
|
||||
var
|
||||
cl: TReprClosure
|
||||
initReprClosure(cl)
|
||||
result = ""
|
||||
if typ.kind in {tyObject, tyPureObject, tyTuple, tyArray, tySet}:
|
||||
reprAux(result, p, typ, cl)
|
||||
else:
|
||||
var p = p
|
||||
reprAux(result, addr(p), typ, cl)
|
||||
add result, "\n"
|
||||
deinitReprClosure(cl)
|
||||
|
|
|
|||
|
|
@ -7,16 +7,16 @@
|
|||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
|
||||
|
||||
## This module contains various string utility routines.
|
||||
## See the module `regexprs` for regular expression support.
|
||||
## All the routines here are avaiable for the EMCAScript target
|
||||
## too!
|
||||
|
||||
{.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 =
|
||||
template newException(exceptn, message: expr): expr =
|
||||
block: # open a new scope
|
||||
var
|
||||
e: ref exceptn
|
||||
|
|
@ -153,6 +153,10 @@ proc ParseInt*(s: string): int {.noSideEffect.}
|
|||
## a valid integer, `EInvalidValue` is raised.
|
||||
# XXX: make this biggestint!
|
||||
|
||||
proc ParseBiggestInt*(s: string): biggestInt {.noSideEffect.}
|
||||
## Parses a decimal integer value contained in `s`. If `s` is not
|
||||
## a valid integer, `EInvalidValue` is raised.
|
||||
|
||||
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.
|
||||
|
|
@ -187,7 +191,7 @@ proc `%` *(formatstr: string, a: openarray[string]): string {.noSideEffect.}
|
|||
##
|
||||
## "The cat eats fish."
|
||||
##
|
||||
## The variables are compared with `cmpIgnoreStyle`. `EInvalidValue` is
|
||||
## 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.}
|
||||
|
|
@ -213,7 +217,13 @@ proc allCharsInSet*(s: string, theSet: TCharSet): bool =
|
|||
if not (c in theSet): return false
|
||||
return true
|
||||
|
||||
proc c_strcmp(a, b: CString): int {.importc: "strcmp", nodecl.}
|
||||
proc quoteIfSpaceExists*(s: string): string =
|
||||
## returns ``'"' & s & '"'`` if `s` contains a space and does not
|
||||
## start with a quote, else returns `s`
|
||||
if findSubStr(' ', s) >= 0 and s[0] != '"':
|
||||
result = '"' & s & '"'
|
||||
else:
|
||||
result = s
|
||||
|
||||
proc startsWith(s, prefix: string): bool =
|
||||
var i = 0
|
||||
|
|
@ -262,7 +272,7 @@ proc findNormalized(x: string, inArray: openarray[string]): int =
|
|||
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 ...
|
||||
# security whole ...
|
||||
return -1
|
||||
|
||||
proc `%`(formatstr: string, a: openarray[string]): string =
|
||||
|
|
@ -306,11 +316,9 @@ proc `%`(formatstr: string, a: openarray[string]): string =
|
|||
|
||||
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])
|
||||
var aa = toLower(a[i])
|
||||
var bb = toLower(b[i])
|
||||
result = ord(aa) - ord(bb)
|
||||
if result != 0: break
|
||||
|
||||
|
|
@ -319,14 +327,13 @@ proc cmpIgnoreCase(a, b: string): int =
|
|||
|
||||
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])
|
||||
var aa = toLower(a[i])
|
||||
var bb = toLower(b[j])
|
||||
result = ord(aa) - ord(bb)
|
||||
if result != 0 or aa == '\0': break
|
||||
inc(i)
|
||||
|
|
@ -475,15 +482,12 @@ proc deleteStr(s: var string, first, last: int) =
|
|||
|
||||
# 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
|
||||
|
|
@ -497,11 +501,8 @@ proc rawParseInt(s: string, index: var int): BiggestInt =
|
|||
# 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
|
||||
i: int = index # a local i is more efficient than accessing a var parameter
|
||||
sign: BiggestInt = -1
|
||||
if s[i] == '+':
|
||||
inc(i)
|
||||
elif s[i] == '-':
|
||||
|
|
@ -523,10 +524,8 @@ proc rawParseInt(s: string, index: var int): BiggestInt =
|
|||
|
||||
proc parseInt(s: string): int =
|
||||
var
|
||||
index: int
|
||||
res: BiggestInt
|
||||
index = strStart
|
||||
res = rawParseInt(s, index)
|
||||
index: int = 0
|
||||
res = rawParseInt(s, index)
|
||||
if index == -1:
|
||||
raise newException(EInvalidValue, "invalid integer: " & s)
|
||||
elif (sizeof(int) <= 4) and
|
||||
|
|
@ -535,17 +534,20 @@ proc parseInt(s: string): int =
|
|||
else:
|
||||
result = int(res) # convert to smaller integer type
|
||||
|
||||
proc ParseBiggestInt(s: string): biggestInt =
|
||||
var
|
||||
index: int = 0
|
||||
result = rawParseInt(s, index)
|
||||
if index == -1:
|
||||
raise newException(EInvalidValue, "invalid integer: " & s)
|
||||
|
||||
proc ParseFloat(s: string): float =
|
||||
var
|
||||
hd, esign, sign: float
|
||||
esign = 1.0
|
||||
sign = 1.0
|
||||
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
|
||||
|
|
@ -558,7 +560,7 @@ proc ParseFloat(s: string): float =
|
|||
while s[i] == '_': inc(i)
|
||||
# Decimal?
|
||||
if s[i] == '.':
|
||||
hd = 1.0
|
||||
var hd = 1.0
|
||||
inc(i)
|
||||
while s[i] in {'0'..'9'}:
|
||||
# Read fractional part
|
||||
|
|
@ -579,14 +581,14 @@ proc ParseFloat(s: string): float =
|
|||
elif s[i] == '-':
|
||||
esign = -1.0
|
||||
inc(i)
|
||||
if s[i] notin {'0'..'9'}:
|
||||
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
|
||||
var hd = 1.0
|
||||
for j in 1..exponent:
|
||||
hd = hd * 10.0
|
||||
if esign > 0.0: result = result * hd
|
||||
|
|
@ -600,11 +602,10 @@ 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
|
||||
mask: BiggestInt = 7
|
||||
shift: BiggestInt = 0
|
||||
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
|
||||
|
|
@ -614,11 +615,10 @@ 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
|
||||
mask: BiggestInt = 1
|
||||
shift: BiggestInt = 0
|
||||
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
|
||||
|
|
|
|||
|
|
@ -33,10 +33,6 @@ 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
|
||||
|
|
@ -81,6 +77,8 @@ proc write(f: TFile, b: bool) =
|
|||
else: write(f, "false")
|
||||
proc write(f: TFile, r: float) = fprintf(f, "%g", r)
|
||||
proc write(f: TFile, c: Char) = putc(c, f)
|
||||
proc write(f: TFile, a: openArray[string]) =
|
||||
for x in items(a): write(f, x)
|
||||
|
||||
proc EndOfFile(f: TFile): bool =
|
||||
# do not blame me; blame the ANSI C standard this is so brain-damaged
|
||||
|
|
@ -93,6 +91,11 @@ proc EndOfFile(f: TFile): bool =
|
|||
proc writeln[Ty](f: TFile, x: Ty) =
|
||||
write(f, x)
|
||||
write(f, "\n")
|
||||
|
||||
proc writeln[Ty](f: TFile, x: openArray[Ty]) =
|
||||
write(f, x)
|
||||
write(f, "\n")
|
||||
|
||||
proc echo[Ty](x: Ty) = writeln(stdout, x)
|
||||
|
||||
# interface to the C procs:
|
||||
|
|
@ -128,7 +131,6 @@ 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)
|
||||
|
|
@ -140,9 +142,11 @@ 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)
|
||||
var x = cast[ptr array[0..1000_000_000, byte]](a)
|
||||
result = writeBuffer(f, addr(x[start]), len)
|
||||
proc writeChars(f: TFile, a: openarray[char], start, len: int): int =
|
||||
result = writeBuffer(f, addr(a[start]), len)
|
||||
var x = cast[ptr array[0..1000_000_000, byte]](a)
|
||||
result = writeBuffer(f, addr(x[start]), len)
|
||||
proc writeBuffer(f: TFile, buffer: pointer, len: int): int =
|
||||
result = fwrite(buffer, 1, len, f)
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
# the programmer may not want
|
||||
|
||||
type
|
||||
TStringDesc {.importc, nodecl.} = record
|
||||
TStringDesc {.importc, nodecl, final.} = object
|
||||
len, space: int # len and space without counting the terminating zero
|
||||
data: array[0..0, char] # for the '\0' character
|
||||
|
||||
|
|
@ -25,7 +25,6 @@ type
|
|||
# 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
|
||||
|
|
@ -64,6 +63,7 @@ proc cstrToNimstr(str: CString): mstring {.compilerProc.} =
|
|||
return toNimstr(str, c_strlen(str))
|
||||
|
||||
proc copyString(src: mstring): mstring {.compilerProc.} =
|
||||
if src == nil: return nil
|
||||
result = rawNewString(src.space)
|
||||
result.len = src.len
|
||||
c_memcpy(result.data, src.data, (src.len + 1) * sizeof(Char))
|
||||
|
|
@ -220,7 +220,7 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
|
|||
result.len = newLen
|
||||
|
||||
# --------------- other string routines ----------------------------------
|
||||
proc `$`(x: int): string =
|
||||
proc nimIntToStr(x: int): string {.compilerproc.} =
|
||||
result = newString(sizeof(x)*4)
|
||||
var i = 0
|
||||
var y = x
|
||||
|
|
@ -238,14 +238,12 @@ proc `$`(x: int): string =
|
|||
for j in 0..i div 2 - 1:
|
||||
swap(result[j], result[i-j-1])
|
||||
|
||||
{.push warnings: off.}
|
||||
proc `$`(x: float): string =
|
||||
proc nimFloatToStr(x: float): string {.compilerproc.} =
|
||||
var buf: array [0..59, char]
|
||||
c_sprintf(buf, "%#g", x)
|
||||
return $buf
|
||||
{.pop.}
|
||||
|
||||
proc `$`(x: int64): string =
|
||||
proc nimInt64ToStr(x: int64): string {.compilerproc.} =
|
||||
# we don't rely on C's runtime here as some C compiler's
|
||||
# int64 support is weak
|
||||
result = newString(sizeof(x)*4)
|
||||
|
|
@ -265,19 +263,13 @@ proc `$`(x: int64): 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 nimBoolToStr(x: bool): string {.compilerproc.} =
|
||||
return if x: "true" else: "false"
|
||||
|
||||
proc `$`(x: char): string =
|
||||
proc nimCharToStr(x: char): string {.compilerproc.} =
|
||||
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
|
||||
|
|
|
|||
642
lib/system.nim
642
lib/system.nim
|
|
@ -58,10 +58,10 @@ proc new*[T](a: var ref T) {.magic: "New".}
|
|||
proc new*[T](a: var ref T, finalizer: proc (x: ref T)) {.magic: "NewFinalize".}
|
||||
## creates a new object of type ``T`` and returns a safe (traced)
|
||||
## reference to it in ``a``. When the garbage collector frees the object,
|
||||
## `finalizer` is called. The `finalizer` may not keep a reference to the
|
||||
## `finalizer` is called. The `finalizer` may not keep a reference to the
|
||||
## object pointed to by `x`. The `finalizer` cannot prevent the GC from
|
||||
## freeing the object. Note: The `finalizer` refers to the type `T`, not to
|
||||
## the object! This means that for each object of type `T` the finalizer
|
||||
## the object! This means that for each object of type `T` the finalizer
|
||||
## will be called!
|
||||
|
||||
# for low and high the return type T may not be correct, but
|
||||
|
|
@ -86,7 +86,6 @@ type
|
|||
## length field.
|
||||
seq*{.magic: "Seq".}[T] ## Generic type to construct sequences.
|
||||
set*{.magic: "Set".}[T] ## Generic type to construct bit sets.
|
||||
tuple*{.magic: "Tuple".}[T] ## Generic type to construct tuple types.
|
||||
|
||||
Byte* = Int8 ## this is an alias for ``int8``, that is a signed
|
||||
## int 8 bits wide.
|
||||
|
|
@ -104,14 +103,15 @@ type
|
|||
## objects that have no ancestor are allowed.
|
||||
PObject* = ref TObject ## reference to TObject
|
||||
|
||||
E_Base* {.compilerproc.} = object of TObject ## base exception class;
|
||||
E_Base* {.compilerproc.} = object of TObject ## base exception class;
|
||||
## each exception has to
|
||||
## inherit from `E_Base`.
|
||||
name*: cstring ## The exception's name is its Nimrod identifier.
|
||||
## This field is filled automatically in the
|
||||
## ``raise`` statement.
|
||||
msg*: cstring ## the exception's message. Not providing an
|
||||
## exception message is bad style.
|
||||
msg* {.exportc: "message".}: cstring ## the exception's message. Not
|
||||
## providing an
|
||||
## exception message is bad style.
|
||||
|
||||
EAsynch* = object of E_Base ## Abstract exception class for
|
||||
## *asynchronous exceptions* (interrupts).
|
||||
|
|
@ -129,18 +129,21 @@ type
|
|||
## could not be fullfilled.
|
||||
EArithmetic* = object of ESynch ## raised if any kind of arithmetic
|
||||
## error occured.
|
||||
EDivByZero* = object of EArithmetic ## is the exception class for integer
|
||||
## divide-by-zero errors.
|
||||
EOverflow* = object of EArithmetic ## is the exception class for integer
|
||||
## calculations whose results are too
|
||||
## large to fit in the provided bits.
|
||||
EDivByZero* {.compilerproc.} =
|
||||
object of EArithmetic ## is the exception class for integer divide-by-zero
|
||||
## errors.
|
||||
EOverflow* {.compilerproc.} =
|
||||
object of EArithmetic ## is the exception class for integer calculations
|
||||
## whose results are too large to fit in the
|
||||
## provided bits.
|
||||
|
||||
EAccessViolation* = object of ESynch ## the exception class for
|
||||
## invalid memory access errors
|
||||
EAccessViolation* {.compilerproc.} =
|
||||
object of ESynch ## the exception class for invalid memory access errors
|
||||
|
||||
EAssertionFailed* = object of ESynch ## is the exception class for Assert
|
||||
## procedures that is raised if the
|
||||
## assertion proves wrong
|
||||
EAssertionFailed* {.compilerproc.} =
|
||||
object of ESynch ## is the exception class for Assert
|
||||
## procedures that is raised if the
|
||||
## assertion proves wrong
|
||||
|
||||
EControlC* = object of EAsynch ## is the exception class for Ctrl+C
|
||||
## key presses in console applications.
|
||||
|
|
@ -154,6 +157,9 @@ type
|
|||
|
||||
EInvalidIndex* = object of ESynch ## is raised if an array index is out
|
||||
## of bounds.
|
||||
EInvalidField* = object of ESynch ## is raised if a record field is not
|
||||
## accessible because its dicriminant's
|
||||
## value does not fit.
|
||||
|
||||
EOutOfRange* = object of ESynch ## is raised if a range check error
|
||||
## occured.
|
||||
|
|
@ -164,13 +170,13 @@ type
|
|||
ENoExceptionToReraise* = object of ESynch ## is raised if there is no
|
||||
## exception to reraise.
|
||||
|
||||
EInvalidObjectAssignment* = object of ESynch ## is raised if an object
|
||||
## gets assigned to its
|
||||
## farther's object.
|
||||
EInvalidObjectAssignment* =
|
||||
object of ESynch ## is raised if an object gets assigned to its
|
||||
## farther's object.
|
||||
|
||||
EInvalidObjectConversion* = object of ESynch ## is raised if an object is
|
||||
## converted to an incompatible
|
||||
## object type.
|
||||
EInvalidObjectConversion* =
|
||||
object of ESynch ## is raised if an object is converted to an incompatible
|
||||
## object type.
|
||||
|
||||
TResult* = enum Failure, Success
|
||||
|
||||
|
|
@ -394,7 +400,7 @@ proc in_Operator*[T](x: set[T], y: T): bool {.magic: "InSet", noSideEffect.}
|
|||
## writeln(stdout, 'b' in s)
|
||||
##
|
||||
## If ``in`` had been declared as ``[T](elem: T, s: set[T])`` then ``T`` would
|
||||
## have been bound to ``char``. But ``s`` is not compatible with type
|
||||
## have been bound to ``char``. But ``s`` is not compatible to type
|
||||
## ``set[char]``! The solution is to bind ``T`` to ``range['a'..'z']``. This
|
||||
## is achieved by reversing the parameters for ``in_operator``; ``in`` then
|
||||
## passes its arguments in reverse order.
|
||||
|
|
@ -418,25 +424,31 @@ proc cmp*(x, y: string): int {.noSideEffect.}
|
|||
## Compare proc for strings. More efficient than the generic version.
|
||||
|
||||
# concat operator:
|
||||
proc `&` * (x: string, y: char): string {.
|
||||
magic: "ConStrStr", noSideEffect, returnsNew.}
|
||||
proc `&` * (x: char, y: char): string {.
|
||||
magic: "ConStrStr", noSideEffect, returnsNew.}
|
||||
proc `&` * (x, y: string): string {.
|
||||
magic: "ConStrStr", noSideEffect, returnsNew.}
|
||||
proc `&` * (x: char, y: string): string {.
|
||||
magic: "ConStrStr", noSideEffect, returnsNew.}
|
||||
## is the `concatenation operator`. It
|
||||
## concatenates `x` and `y`.
|
||||
proc `&` * (x: string, y: char): string {.magic: "ConStrStr", noSideEffect.}
|
||||
proc `&` * (x: char, y: char): string {.magic: "ConStrStr", noSideEffect.}
|
||||
proc `&` * (x, y: string): string {.magic: "ConStrStr", noSideEffect.}
|
||||
proc `&` * (x: char, y: string): string {.magic: "ConStrStr", noSideEffect.}
|
||||
## is the `concatenation operator`. It concatenates `x` and `y`.
|
||||
|
||||
proc add * (x: var string, y: char) {.magic: "AppendStrCh".}
|
||||
proc add * (x: var string, y: string) {.magic: "AppendStrStr".}
|
||||
|
||||
proc add* (x: var string, y: cstring) =
|
||||
var i = 0
|
||||
while y[i] != '\0':
|
||||
add(x, y[i])
|
||||
inc(i)
|
||||
when not defined(ECMAScript):
|
||||
proc add* (x: var string, y: cstring) =
|
||||
var i = 0
|
||||
while y[i] != '\0':
|
||||
add(x, y[i])
|
||||
inc(i)
|
||||
else:
|
||||
proc add* (x: var string, y: cstring) {.pure.} =
|
||||
asm """
|
||||
var len = `x`[0].length-1;
|
||||
for (var i = 0; i < `y`.length; ++i) {
|
||||
`x`[0][len] = `y`.charCodeAt(i);
|
||||
++len;
|
||||
}
|
||||
`x`[0][len] = 0
|
||||
"""
|
||||
|
||||
proc add *[T](x: var seq[T], y: T) {.magic: "AppendSeqElem".}
|
||||
proc add *[T](x: var seq[T], y: seq[T]) {.magic: "AppendSeqSeq".}
|
||||
|
|
@ -493,7 +505,7 @@ type # these work for most platforms:
|
|||
|
||||
TEndian* = enum ## is a type describing the endianness of a processor.
|
||||
littleEndian, bigEndian
|
||||
|
||||
|
||||
PFloat32* = ptr Float32 ## an alias for ``ptr float32``
|
||||
PFloat64* = ptr Float64 ## an alias for ``ptr float64``
|
||||
PInt64* = ptr Int64 ## an alias for ``ptr int64``
|
||||
|
|
@ -675,20 +687,27 @@ proc swap*[T](a, b: var T) {.magic: "Swap".}
|
|||
## swaps the values `a` and `b`. This is often more efficient than
|
||||
## ``tmp = a; a = b; b = tmp``. Particularly useful for sorting algorithms.
|
||||
|
||||
proc ze*(x: int8): int {.magic: "Ze", noSideEffect.}
|
||||
proc ze*(x: int8): int {.magic: "Ze8ToI", noSideEffect.}
|
||||
## zero extends a smaller integer type to ``int``. This treats `x` as
|
||||
## unsigned.
|
||||
proc ze*(x: int16): int {.magic: "Ze", noSideEffect.}
|
||||
proc ze*(x: int16): int {.magic: "Ze16ToI", noSideEffect.}
|
||||
## zero extends a smaller integer type to ``int``. This treats `x` as
|
||||
## unsigned.
|
||||
|
||||
proc ze64*(x: int32): int64 {.magic: "Ze64", noSideEffect.}
|
||||
proc ze64*(x: int8): int64 {.magic: "Ze8ToI64", noSideEffect.}
|
||||
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
||||
## unsigned.
|
||||
proc ze*(x: int): int64 {.magic: "Ze", noDecl, noSideEffect.}
|
||||
proc ze64*(x: int16): int64 {.magic: "Ze16ToI64", noSideEffect.}
|
||||
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
||||
## unsigned.
|
||||
|
||||
proc ze64*(x: int32): int64 {.magic: "Ze32ToI64", noSideEffect.}
|
||||
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
||||
## unsigned.
|
||||
proc ze64*(x: int): int64 {.magic: "ZeIToI64", noDecl, noSideEffect.}
|
||||
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
||||
## unsigned. Does nothing if the size of an ``int`` is the same as ``int64``.
|
||||
## (This is the case an 64 bit processors.)
|
||||
## (This is the case on 64 bit processors.)
|
||||
|
||||
proc toU8*(x: int): int8 {.magic: "ToU8", noSideEffect.}
|
||||
## treats `x` as unsigned and converts it to a byte by taking the last 8 bits
|
||||
|
|
@ -749,39 +768,39 @@ template `>%` *(x, y: expr): expr = y <% x
|
|||
## treats `x` and `y` as unsigned and compares them.
|
||||
## Returns true iff ``unsigned(x) > unsigned(y)``.
|
||||
|
||||
proc `$` *(x: int): string {.noSideEffect.}
|
||||
proc `$` *(x: int): string {.magic: "IntToStr", noSideEffect.}
|
||||
## The stingify operator for an integer argument. Returns `x`
|
||||
## converted to a decimal string.
|
||||
|
||||
proc `$` *(x: int64): string {.noSideEffect.}
|
||||
proc `$` *(x: int64): string {.magic: "Int64ToStr", noSideEffect.}
|
||||
## The stingify operator for an integer argument. Returns `x`
|
||||
## converted to a decimal string.
|
||||
|
||||
proc `$` *(x: float): string {.noSideEffect.}
|
||||
proc `$` *(x: float): string {.magic: "FloatToStr", noSideEffect.}
|
||||
## The stingify operator for a float argument. Returns `x`
|
||||
## converted to a decimal string.
|
||||
|
||||
proc `$` *(x: bool): string {.noSideEffect.}
|
||||
proc `$` *(x: bool): string {.magic: "BoolToStr", noSideEffect.}
|
||||
## The stingify operator for a boolean argument. Returns `x`
|
||||
## converted to the string "false" or "true".
|
||||
|
||||
proc `$` *(x: char): string {.noSideEffect.}
|
||||
proc `$` *(x: char): string {.magic: "CharToStr", noSideEffect.}
|
||||
## The stingify operator for a character argument. Returns `x`
|
||||
## converted to a string.
|
||||
|
||||
proc `$` *(x: Cstring): string {.noSideEffect, importc: "cstrToNimstr".}
|
||||
proc `$` *(x: Cstring): string {.magic: "CStrToStr", noSideEffect.}
|
||||
## The stingify operator for a CString argument. Returns `x`
|
||||
## converted to a string.
|
||||
|
||||
proc `$` *(x: string): string {.noSideEffect.}
|
||||
proc `$` *(x: string): string {.magic: "StrToStr", noSideEffect.}
|
||||
## The stingify operator for a string argument. Returns `x`
|
||||
## as it is. This operator is useful for generic code, so
|
||||
## that ``$expr`` works if ``expr`` is already a string.
|
||||
## that ``$expr`` also works if ``expr`` is already a string.
|
||||
|
||||
# undocumented:
|
||||
proc getRefcount*[T](x: ref T): int {.importc: "getRefcount".}
|
||||
## retrieves the reference count of an heap-allocated object. The
|
||||
## value is implementation-dependant.
|
||||
## value is implementation-dependant.
|
||||
|
||||
#proc writeStackTrace() {.export: "writeStackTrace".}
|
||||
proc getCurrentExceptionMsg*(): string {.exportc.}
|
||||
|
|
@ -790,10 +809,12 @@ proc getCurrentExceptionMsg*(): string {.exportc.}
|
|||
|
||||
# new constants:
|
||||
const
|
||||
inf* = 1.0 / 0.0
|
||||
inf* {.magic: "Inf".} = 0.0
|
||||
## contains the IEEE floating point value of positive infinity.
|
||||
nan* = 0.0 / 0.0
|
||||
## contains the IEEE floating point value of *Not A Number*. Note
|
||||
neginf* {.magic: "NegInf".} = 0.0
|
||||
## contains the IEEE floating point value of negative infinity.
|
||||
nan* {.magic: "NaN".} = 0.0
|
||||
## contains an IEEE floating point value of *Not A Number*. Note
|
||||
## that you cannot compare a floating point value to this value
|
||||
## and expect a reasonable result - use the `classify` procedure
|
||||
## in the module ``math`` for checking for NaN.
|
||||
|
|
@ -805,18 +826,18 @@ var
|
|||
## Only code compiled with the ``debugger:on`` switch calls this hook.
|
||||
|
||||
# GC interface:
|
||||
when defined(Unix) and not defined(macosX) and not defined(linux):
|
||||
when defined(Unix) and not defined(macosX) and not defined(linux):
|
||||
# BUGFIX for macosX
|
||||
{.define: nativeDL.}
|
||||
|
||||
when defined(useDL) or defined(nativeDL):
|
||||
proc getOccupiedMem*(): int
|
||||
## returns the number of bytes that are owned by the process and hold data.
|
||||
|
||||
|
||||
proc getFreeMem*(): int
|
||||
## returns the number of bytes that are owned by the process, but do not
|
||||
## hold any meaningful data.
|
||||
|
||||
|
||||
proc getTotalMem*(): int
|
||||
## returns the number of bytes that are owned by the process.
|
||||
|
||||
|
|
@ -885,11 +906,22 @@ iterator items*(a: cstring): char {.inline.} =
|
|||
yield a[i]
|
||||
inc(i)
|
||||
|
||||
|
||||
proc isNil*[T](x: seq[T]): bool {.noSideEffect, magic: "IsNil".}
|
||||
proc isNil*[T](x: ref T): bool {.noSideEffect, magic: "IsNil".}
|
||||
proc isNil*(x: string): bool {.noSideEffect, magic: "IsNil".}
|
||||
proc isNil*[T](x: ptr T): bool {.noSideEffect, magic: "IsNil".}
|
||||
proc isNil*(x: pointer): bool {.noSideEffect, magic: "IsNil".}
|
||||
proc isNil*(x: cstring): bool {.noSideEffect, magic: "IsNil".}
|
||||
## Fast check whether `x` is nil. This is sometimes more efficient than
|
||||
## ``== nil``.
|
||||
|
||||
|
||||
# Fixup some magic symbols here:
|
||||
{.fixup_system.} # This is an undocumented pragma that can only be used
|
||||
# once in the system module.
|
||||
|
||||
proc `&` *[T](x, y: seq[T]): seq[T] {.noSideEffect, returnsNew.} =
|
||||
proc `&` *[T](x, y: seq[T]): seq[T] {.noSideEffect.} =
|
||||
result = []
|
||||
setLen(result, x.len + y.len)
|
||||
for i in 0..x.len-1:
|
||||
|
|
@ -897,76 +929,92 @@ proc `&` *[T](x, y: seq[T]): seq[T] {.noSideEffect, returnsNew.} =
|
|||
for i in 0..y.len-1:
|
||||
result[i] = y[i]
|
||||
|
||||
proc `&` *[T](x: seq[T], y: T): seq[T] {.noSideEffect, returnsNew.} =
|
||||
proc `&` *[T](x: seq[T], y: T): seq[T] {.noSideEffect.} =
|
||||
result = []
|
||||
setLen(x.len + 1)
|
||||
for i in 0..x.len-1:
|
||||
result[i] = x[i]
|
||||
result[x.len] = y
|
||||
|
||||
proc `&` *[T](x: T, y: seq[T]): seq[T] {.noSideEffect, returnsNew.} =
|
||||
proc `&` *[T](x: T, y: seq[T]): seq[T] {.noSideEffect.} =
|
||||
result = []
|
||||
setLen(y.len + 1)
|
||||
for i in 0..y.len-1:
|
||||
result[i] = y[i]
|
||||
result[y.len] = x
|
||||
|
||||
proc `&` *[T](x, y: T): seq[T] {.noSideEffect, returnsNew.} =
|
||||
proc `&` *[T](x, y: T): seq[T] {.noSideEffect.} =
|
||||
return [x, y]
|
||||
|
||||
when not defined(ECMAScript): # XXX make this local procs
|
||||
proc seqToPtr*[T](x: seq[T]): pointer {.inline, nosideeffect.} =
|
||||
result = cast[pointer](x)
|
||||
else:
|
||||
proc seqToPtr*[T](x: seq[T]): pointer {.pure, nosideeffect.} =
|
||||
asm """return `x`"""
|
||||
|
||||
proc `==` *[T](x, y: seq[T]): bool {.noSideEffect.} =
|
||||
## Generic equals operator for sequences: relies on a equals operator for
|
||||
## the element type `T`.
|
||||
if cast[pointer](x) == cast[pointer](y):
|
||||
if seqToPtr(x) == seqToPtr(y):
|
||||
result = true
|
||||
elif cast[pointer](x) == nil or cast[pointer](y) == nil:
|
||||
elif seqToPtr(x) == nil or seqToPtr(y) == nil:
|
||||
result = false
|
||||
elif x.len == y.len:
|
||||
for i in 0..x.len-1:
|
||||
if x[i] != y[i]: return false
|
||||
result = true
|
||||
|
||||
# ----------------- FPU ------------------------------------------------------
|
||||
|
||||
#proc disableFPUExceptions*()
|
||||
# disables all floating point unit exceptions
|
||||
|
||||
#proc enableFPUExceptions*()
|
||||
# enables all floating point unit exceptions
|
||||
|
||||
# ----------------- GC interface ---------------------------------------------
|
||||
|
||||
proc GC_disable*()
|
||||
## disables the GC. If called n-times, n calls to `GC_enable` are needed to
|
||||
## reactivate the GC. Note that in most circumstances one should only disable
|
||||
## the mark and sweep phase with `GC_disableMarkAndSweep`.
|
||||
|
||||
proc GC_enable*()
|
||||
## enables the GC again.
|
||||
|
||||
proc GC_fullCollect*()
|
||||
## forces a full garbage collection pass.
|
||||
## Ordinary code does not need to call this.
|
||||
|
||||
type
|
||||
TGC_Strategy* = enum ## the strategy the GC should use for the application
|
||||
gcThroughput, ## optimize for throughput
|
||||
gcResponsiveness, ## optimize for responsiveness (default)
|
||||
gcOptimizeTime, ## optimize for speed
|
||||
gcOptimizeSpace ## optimize for memory footprint
|
||||
|
||||
proc GC_setStrategy*(strategy: TGC_Strategy)
|
||||
## tells the GC the desired strategy for the application.
|
||||
|
||||
proc GC_enableMarkAndSweep*()
|
||||
proc GC_disableMarkAndSweep*()
|
||||
## the current implementation uses a reference counting garbage collector
|
||||
## with a seldomly run mark and sweep phase to free cycles. The mark and
|
||||
## sweep phase may take a long time and is not needed if the application
|
||||
## does not create cycles. Thus the mark and sweep phase can be deactivated
|
||||
## and activated separately from the rest of the GC.
|
||||
|
||||
|
||||
{.push checks: off, line_dir: off, debugger: off,
|
||||
assertions: on.} # obviously we cannot generate checking operations here :-)
|
||||
# because it would yield into an endless recursion
|
||||
# however, stack-traces are available for most parts
|
||||
# of the code
|
||||
|
||||
include hti
|
||||
|
||||
proc initGC()
|
||||
|
||||
var
|
||||
strDesc: TNimType
|
||||
|
||||
strDesc.size = sizeof(string)
|
||||
strDesc.kind = tyString
|
||||
initGC() # BUGFIX: need to be called here!
|
||||
|
||||
{.push stack_trace: off.}
|
||||
|
||||
include ansi_c
|
||||
|
||||
proc cmp(x, y: string): int =
|
||||
return c_strcmp(x, y)
|
||||
|
||||
when defined(windows):
|
||||
# work-around C's sucking abstraction:
|
||||
# BUGFIX: stdin and stdout should be binary files!
|
||||
const pccHack = if defined(pcc): "_" else: "" # Hack for PCC
|
||||
proc setmode(handle, mode: int) {.importc: pccHack & "setmode",
|
||||
header: "<io.h>".}
|
||||
proc fileno(f: C_TextFileStar): int {.importc: pccHack & "fileno",
|
||||
header: "<fcntl.h>".}
|
||||
var
|
||||
O_BINARY {.importc: pccHack & "O_BINARY", nodecl.}: int
|
||||
|
||||
# we use binary mode in Windows:
|
||||
setmode(fileno(c_stdin), O_BINARY)
|
||||
setmode(fileno(c_stdout), O_BINARY)
|
||||
|
||||
when defined(endb):
|
||||
proc endbStep()
|
||||
proc echo*[Ty](x: Ty) {.inline.}
|
||||
## equivalent to ``writeln(stdout, x); flush(stdout)``. BUT: This is
|
||||
## available for the ECMAScript target too!
|
||||
|
||||
|
||||
template newException(exceptn, message: expr): expr =
|
||||
|
|
@ -976,209 +1024,223 @@ template newException(exceptn, message: expr): expr =
|
|||
new(e)
|
||||
e.msg = message
|
||||
e
|
||||
|
||||
# ----------------- GC interface ---------------------------------------------
|
||||
|
||||
proc GC_disable*()
|
||||
## disables the GC. If called n-times, n calls to `GC_enable` are needed to
|
||||
## reactivate the GC. Note that in most circumstances one should only disable
|
||||
## the mark and sweep phase with `GC_disableMarkAndSweep`.
|
||||
when not defined(EcmaScript):
|
||||
|
||||
proc GC_enable*()
|
||||
## enables the GC again.
|
||||
|
||||
proc GC_fullCollect*()
|
||||
## forces a full garbage collection pass.
|
||||
## Ordinary code does not need to call this.
|
||||
include hti
|
||||
|
||||
type
|
||||
TGC_Strategy* = enum ## the strategy the GC should use for the application
|
||||
gcThroughput , ## optimize for throughput
|
||||
gcResponsiveness, ## optimize for responsiveness (default)
|
||||
gcOptimizeTime, ## optimize for speed
|
||||
gcOptimizeSpace ## optimize for memory footprint
|
||||
proc initGC()
|
||||
|
||||
proc GC_setStrategy*(strategy: TGC_Strategy)
|
||||
## tells the GC the desired strategy for the application.
|
||||
|
||||
proc GC_enableMarkAndSweep*()
|
||||
proc GC_disableMarkAndSweep*()
|
||||
## the current implementation uses a reference counting garbage collector
|
||||
## with a seldomly run mark and sweep phase to free cycles. The mark and
|
||||
## sweep phase may take a long time and is not needed if the application
|
||||
## does not create cycles. Thus the mark and sweep phase can be deactivated
|
||||
## and activated separately from the rest of the GC.
|
||||
|
||||
|
||||
# ----------------- IO Part --------------------------------------------------
|
||||
|
||||
type
|
||||
CFile {.importc: "FILE", nodecl.} = record # empty record for
|
||||
# data hiding
|
||||
TFile* = ptr CFile ## The type representing a file handle.
|
||||
|
||||
TFileMode* = enum ## The file mode when opening a file.
|
||||
fmRead, ## Open the file for read access only.
|
||||
fmWrite, ## Open the file for write access only.
|
||||
fmReadWrite, ## Open the file for read and write access.
|
||||
## If the file does not exist, it will be
|
||||
## created.
|
||||
fmReadWriteExisting, ## Open the file for read and write access.
|
||||
## If the file does not exist, it will not be
|
||||
## created.
|
||||
fmAppend ## Open the file for writing only; append data
|
||||
## at the end.
|
||||
|
||||
# text file handling:
|
||||
var
|
||||
stdin* {.importc: "stdin", noDecl.}: TFile ## The standard input stream.
|
||||
stdout* {.importc: "stdout", noDecl.}: TFile ## The standard output stream.
|
||||
stderr* {.importc: "stderr", noDecl.}: TFile
|
||||
## The standard error stream.
|
||||
##
|
||||
## Note: In my opinion, this should not be used -- the concept of a
|
||||
## separate error stream is a design flaw of UNIX. A seperate *message
|
||||
## stream* is a good idea, but since it is named ``stderr`` there are few
|
||||
## programs out there that distinguish properly between ``stdout`` and
|
||||
## ``stderr``. So, that's what you get if you don't name your variables
|
||||
## appropriately. It also annoys people if redirection via ``>output.txt``
|
||||
## does not work because the program writes to ``stderr``.
|
||||
|
||||
proc OpenFile*(f: var TFile, filename: string,
|
||||
mode: TFileMode = fmRead, bufSize: int = -1): Bool
|
||||
## Opens a file named `filename` with given `mode`.
|
||||
##
|
||||
## Default mode is readonly. Returns true iff the file could be opened.
|
||||
## This throws no exception if the file could not be opened. The reason is
|
||||
## that the programmer needs to provide an appropriate error message anyway
|
||||
## (yes, even in scripts).
|
||||
|
||||
proc CloseFile*(f: TFile) {.importc: "fclose", nodecl.}
|
||||
## Closes the file.
|
||||
proc EndOfFile*(f: TFile): Bool
|
||||
## Returns true iff `f` is at the end.
|
||||
proc readChar*(f: TFile): char {.importc: "fgetc", nodecl.}
|
||||
## Reads a single character from the stream `f`. If the stream
|
||||
## has no more characters, `EEndOfFile` is raised.
|
||||
proc FlushFile*(f: TFile) {.importc: "fflush", noDecl.}
|
||||
## Flushes `f`'s buffer.
|
||||
|
||||
proc readFile*(filename: string): string
|
||||
## Opens a file name `filename` for reading. Then reads the
|
||||
## file's content completely into a string and
|
||||
## closes the file afterwards. Returns the string. Returns nil if there was
|
||||
## an error. Does not throw an IO exception.
|
||||
|
||||
proc write*(f: TFile, r: float)
|
||||
proc write*(f: TFile, i: int)
|
||||
proc write*(f: TFile, s: string)
|
||||
proc write*(f: TFile, b: Bool)
|
||||
proc write*(f: TFile, c: char)
|
||||
proc write*(f: TFile, c: cstring)
|
||||
## Writes a value to the file `f`. May throw an IO exception.
|
||||
|
||||
proc readLine*(f: TFile): string
|
||||
## reads a line of text from the file `f`. May throw an IO exception.
|
||||
## Reading from an empty file buffer, does not throw an exception, but
|
||||
## returns nil. A line of text may be delimited by ``CR``, ``LF`` or
|
||||
## ``CRLF``. The newline character(s) are not part of the returned string.
|
||||
|
||||
proc writeln*[Ty](f: TFile, x: Ty) {.inline.}
|
||||
## writes a value `x` to `f` and then writes "\n". May throw an IO exception.
|
||||
proc echo*[Ty](x: Ty) {.inline.}
|
||||
## equivalent to ``writeln(stdout, x); flush(stdout)``.
|
||||
|
||||
proc getFileSize*(f: TFile): int64
|
||||
## retrieves the file size (in bytes) of `f`.
|
||||
|
||||
proc ReadBytes*(f: TFile, a: var openarray[byte], start, len: int): int
|
||||
## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns
|
||||
## the actual number of bytes that have been read which may be less than
|
||||
## `len` (if not as many bytes are remaining), but not greater.
|
||||
|
||||
proc ReadChars*(f: TFile, a: var openarray[char], start, len: int): int
|
||||
## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns
|
||||
## the actual number of bytes that have been read which may be less than
|
||||
## `len` (if not as many bytes are remaining), but not greater.
|
||||
|
||||
proc readBuffer*(f: TFile, buffer: pointer, len: int): int
|
||||
## reads `len` bytes into the buffer pointed to by `buffer`. Returns
|
||||
## the actual number of bytes that have been read which may be less than
|
||||
## `len` (if not as many bytes are remaining), but not greater.
|
||||
|
||||
proc writeBytes*(f: TFile, a: openarray[byte], start, len: int): int
|
||||
## writes the bytes of ``a[start..start+len-1]`` to the file `f`. Returns
|
||||
## the number of actual written bytes, which may be less than `len` in case
|
||||
## of an error.
|
||||
|
||||
proc writeChars*(f: tFile, a: openarray[char], start, len: int): int
|
||||
## writes the bytes of ``a[start..start+len-1]`` to the file `f`. Returns
|
||||
## the number of actual written bytes, which may be less than `len` in case
|
||||
## of an error.
|
||||
|
||||
proc writeBuffer*(f: TFile, buffer: pointer, len: int): int
|
||||
## writes the bytes of buffer pointed to by the parameter `buffer` to the
|
||||
## file `f`. Returns the number of actual written bytes, which may be less
|
||||
## than `len` in case of an error.
|
||||
|
||||
proc setFilePos*(f: TFile, pos: int64)
|
||||
## sets the position of the file pointer that is used for read/write
|
||||
## operations. The file's first byte has the index zero.
|
||||
|
||||
proc getFilePos*(f: TFile): int64
|
||||
## retrieves the current position of the file pointer that is used to
|
||||
## read from the file `f`. The file's first byte has the index zero.
|
||||
|
||||
include sysio
|
||||
|
||||
iterator lines*(filename: string): string =
|
||||
## Iterate over any line in the file named `filename`.
|
||||
## If the file does not exist `EIO` is raised.
|
||||
var
|
||||
f: TFile
|
||||
if not openFile(f, filename):
|
||||
raise newException(EIO, "cannot open: " & filename)
|
||||
var res = ""
|
||||
while not endOfFile(f):
|
||||
rawReadLine(f, res)
|
||||
yield res
|
||||
CloseFile(f)
|
||||
strDesc: TNimType
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
strDesc.size = sizeof(string)
|
||||
strDesc.kind = tyString
|
||||
initGC() # BUGFIX: need to be called here!
|
||||
|
||||
include excpt
|
||||
# we cannot compile this with stack tracing on
|
||||
# as it would recurse endlessly!
|
||||
include arithm
|
||||
{.pop.} # stack trace
|
||||
{.push stack_trace: off.}
|
||||
|
||||
# sequence type declarations here because the GC needs them too:
|
||||
type
|
||||
TGenericSeq {.importc, nodecl.} = record
|
||||
len, space: int
|
||||
include ansi_c
|
||||
|
||||
PGenericSeq {.importc, nodecl.} = ptr TGenericSeq
|
||||
proc cmp(x, y: string): int =
|
||||
return c_strcmp(x, y)
|
||||
|
||||
const
|
||||
GenericSeqSize = (2 * sizeof(int))
|
||||
when defined(windows):
|
||||
# work-around C's sucking abstraction:
|
||||
# BUGFIX: stdin and stdout should be binary files!
|
||||
const pccHack = if defined(pcc): "_" else: "" # Hack for PCC
|
||||
proc setmode(handle, mode: int) {.importc: pccHack & "setmode",
|
||||
header: "<io.h>".}
|
||||
proc fileno(f: C_TextFileStar): int {.importc: pccHack & "fileno",
|
||||
header: "<fcntl.h>".}
|
||||
var
|
||||
O_BINARY {.importc: pccHack & "O_BINARY", nodecl.}: int
|
||||
|
||||
when not defined(boehmgc) and not defined(nogc):
|
||||
include gc
|
||||
# we use binary mode in Windows:
|
||||
setmode(fileno(c_stdin), O_BINARY)
|
||||
setmode(fileno(c_stdout), O_BINARY)
|
||||
|
||||
include sysstr
|
||||
include assign
|
||||
include dyncalls
|
||||
include repr
|
||||
when defined(endb):
|
||||
proc endbStep()
|
||||
|
||||
# we have to implement it here after gentostr for the cstrToNimStrDummy proc
|
||||
proc getCurrentExceptionMsg(): string =
|
||||
if excHandler == nil: return ""
|
||||
return $excHandler.exc.msg
|
||||
# ----------------- IO Part --------------------------------------------------
|
||||
|
||||
type
|
||||
CFile {.importc: "FILE", nodecl, final.} = object # empty record for
|
||||
# data hiding
|
||||
TFile* = ptr CFile ## The type representing a file handle.
|
||||
|
||||
TFileMode* = enum ## The file mode when opening a file.
|
||||
fmRead, ## Open the file for read access only.
|
||||
fmWrite, ## Open the file for write access only.
|
||||
fmReadWrite, ## Open the file for read and write access.
|
||||
## If the file does not exist, it will be
|
||||
## created.
|
||||
fmReadWriteExisting, ## Open the file for read and write access.
|
||||
## If the file does not exist, it will not be
|
||||
## created.
|
||||
fmAppend ## Open the file for writing only; append data
|
||||
## at the end.
|
||||
|
||||
# text file handling:
|
||||
var
|
||||
stdin* {.importc: "stdin", noDecl.}: TFile ## The standard input stream.
|
||||
stdout* {.importc: "stdout", noDecl.}: TFile ## The standard output stream.
|
||||
stderr* {.importc: "stderr", noDecl.}: TFile
|
||||
## The standard error stream.
|
||||
##
|
||||
## Note: In my opinion, this should not be used -- the concept of a
|
||||
## separate error stream is a design flaw of UNIX. A seperate *message
|
||||
## stream* is a good idea, but since it is named ``stderr`` there are few
|
||||
## programs out there that distinguish properly between ``stdout`` and
|
||||
## ``stderr``. So, that's what you get if you don't name your variables
|
||||
## appropriately. It also annoys people if redirection via ``>output.txt``
|
||||
## does not work because the program writes to ``stderr``.
|
||||
|
||||
proc OpenFile*(f: var TFile, filename: string,
|
||||
mode: TFileMode = fmRead, bufSize: int = -1): Bool
|
||||
## Opens a file named `filename` with given `mode`.
|
||||
##
|
||||
## Default mode is readonly. Returns true iff the file could be opened.
|
||||
## This throws no exception if the file could not be opened. The reason is
|
||||
## that the programmer needs to provide an appropriate error message anyway
|
||||
## (yes, even in scripts).
|
||||
|
||||
proc CloseFile*(f: TFile) {.importc: "fclose", nodecl.}
|
||||
## Closes the file.
|
||||
proc EndOfFile*(f: TFile): Bool
|
||||
## Returns true iff `f` is at the end.
|
||||
proc readChar*(f: TFile): char {.importc: "fgetc", nodecl.}
|
||||
## Reads a single character from the stream `f`. If the stream
|
||||
## has no more characters, `EEndOfFile` is raised.
|
||||
proc FlushFile*(f: TFile) {.importc: "fflush", noDecl.}
|
||||
## Flushes `f`'s buffer.
|
||||
|
||||
proc readFile*(filename: string): string
|
||||
## Opens a file name `filename` for reading. Then reads the
|
||||
## file's content completely into a string and
|
||||
## closes the file afterwards. Returns the string. Returns nil if there was
|
||||
## an error. Does not throw an IO exception.
|
||||
|
||||
proc write*(f: TFile, r: float)
|
||||
proc write*(f: TFile, i: int)
|
||||
proc write*(f: TFile, s: string)
|
||||
proc write*(f: TFile, b: Bool)
|
||||
proc write*(f: TFile, c: char)
|
||||
proc write*(f: TFile, c: cstring)
|
||||
proc write*(f: TFile, a: openArray[string])
|
||||
## Writes a value to the file `f`. May throw an IO exception.
|
||||
|
||||
proc readLine*(f: TFile): string
|
||||
## reads a line of text from the file `f`. May throw an IO exception.
|
||||
## Reading from an empty file buffer, does not throw an exception, but
|
||||
## returns nil. A line of text may be delimited by ``CR``, ``LF`` or
|
||||
## ``CRLF``. The newline character(s) are not part of the returned string.
|
||||
|
||||
proc writeln*[Ty](f: TFile, x: Ty) {.inline.}
|
||||
## writes a value `x` to `f` and then writes "\n".
|
||||
## May throw an IO exception.
|
||||
|
||||
proc writeln*[Ty](f: TFile, x: openArray[Ty]) {.inline.}
|
||||
## writes a value `x` to `f` and then writes "\n".
|
||||
## May throw an IO exception.
|
||||
|
||||
proc getFileSize*(f: TFile): int64
|
||||
## retrieves the file size (in bytes) of `f`.
|
||||
|
||||
proc ReadBytes*(f: TFile, a: var openarray[byte], start, len: int): int
|
||||
## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns
|
||||
## the actual number of bytes that have been read which may be less than
|
||||
## `len` (if not as many bytes are remaining), but not greater.
|
||||
|
||||
proc ReadChars*(f: TFile, a: var openarray[char], start, len: int): int
|
||||
## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns
|
||||
## the actual number of bytes that have been read which may be less than
|
||||
## `len` (if not as many bytes are remaining), but not greater.
|
||||
|
||||
proc readBuffer*(f: TFile, buffer: pointer, len: int): int
|
||||
## reads `len` bytes into the buffer pointed to by `buffer`. Returns
|
||||
## the actual number of bytes that have been read which may be less than
|
||||
## `len` (if not as many bytes are remaining), but not greater.
|
||||
|
||||
proc writeBytes*(f: TFile, a: openarray[byte], start, len: int): int
|
||||
## writes the bytes of ``a[start..start+len-1]`` to the file `f`. Returns
|
||||
## the number of actual written bytes, which may be less than `len` in case
|
||||
## of an error.
|
||||
|
||||
proc writeChars*(f: tFile, a: openarray[char], start, len: int): int
|
||||
## writes the bytes of ``a[start..start+len-1]`` to the file `f`. Returns
|
||||
## the number of actual written bytes, which may be less than `len` in case
|
||||
## of an error.
|
||||
|
||||
proc writeBuffer*(f: TFile, buffer: pointer, len: int): int
|
||||
## writes the bytes of buffer pointed to by the parameter `buffer` to the
|
||||
## file `f`. Returns the number of actual written bytes, which may be less
|
||||
## than `len` in case of an error.
|
||||
|
||||
proc setFilePos*(f: TFile, pos: int64)
|
||||
## sets the position of the file pointer that is used for read/write
|
||||
## operations. The file's first byte has the index zero.
|
||||
|
||||
proc getFilePos*(f: TFile): int64
|
||||
## retrieves the current position of the file pointer that is used to
|
||||
## read from the file `f`. The file's first byte has the index zero.
|
||||
|
||||
include sysio
|
||||
|
||||
iterator lines*(filename: string): string =
|
||||
## Iterate over any line in the file named `filename`.
|
||||
## If the file does not exist `EIO` is raised.
|
||||
var
|
||||
f: TFile
|
||||
if not openFile(f, filename):
|
||||
raise newException(EIO, "cannot open: " & filename)
|
||||
var res = ""
|
||||
while not endOfFile(f):
|
||||
rawReadLine(f, res)
|
||||
yield res
|
||||
CloseFile(f)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
include excpt
|
||||
# we cannot compile this with stack tracing on
|
||||
# as it would recurse endlessly!
|
||||
include arithm
|
||||
{.pop.} # stack trace
|
||||
|
||||
# sequence type declarations here because the GC needs them too:
|
||||
type
|
||||
TGenericSeq {.importc, nodecl, final.} = object
|
||||
len, space: int
|
||||
|
||||
PGenericSeq {.importc, nodecl.} = ptr TGenericSeq
|
||||
|
||||
const
|
||||
GenericSeqSize = (2 * sizeof(int))
|
||||
|
||||
when not defined(boehmgc) and not defined(nogc):
|
||||
include gc
|
||||
|
||||
include sysstr
|
||||
include assign
|
||||
include dyncalls
|
||||
include repr
|
||||
|
||||
# we have to implement it here after gentostr for the cstrToNimStrDummy proc
|
||||
proc getCurrentExceptionMsg(): string =
|
||||
if excHandler == nil: return ""
|
||||
return $excHandler.exc.msg
|
||||
|
||||
{.push stack_trace: off.}
|
||||
when defined(endb):
|
||||
include debugger
|
||||
{.pop.} # stacktrace
|
||||
|
||||
else:
|
||||
include ecmasys
|
||||
|
||||
include macros
|
||||
|
||||
{.push stack_trace: off.}
|
||||
when defined(endb):
|
||||
include debugger
|
||||
{.pop.} # stacktrace
|
||||
{.pop.} # checks
|
||||
|
||||
{.pop.} # hints
|
||||
|
|
|
|||
272
lib/times.nim
272
lib/times.nim
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2006 Andreas Rumpf
|
||||
# (c) Copyright 2008 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
|
||||
## This module contains routines and types for dealing with time.
|
||||
## This module is available for the ECMAScript target.
|
||||
|
||||
{.push debugger:off .} # the user does not want to trace a part
|
||||
# of the standard library!
|
||||
|
|
@ -22,9 +23,49 @@ type
|
|||
TWeekDay* = enum ## represents a weekday
|
||||
dMon, dTue, dWed, dThu, dFri, dSat, dSun
|
||||
|
||||
TTime* {.importc: "time_t".} = record ## abstract type that represents a time
|
||||
TTime* {.importc: "time_t", final.} = object ## abstract type that
|
||||
## represents a time
|
||||
when defined(ECMAScript):
|
||||
getDay: proc (): int
|
||||
getFullYear: proc (): int
|
||||
getHours: proc (): int
|
||||
getMilliseconds: proc (): int
|
||||
getMinutes: proc (): int
|
||||
getMonth: proc (): int
|
||||
getSeconds: proc (): int
|
||||
getTime: proc (): int
|
||||
getTimezoneOffset: proc (): int
|
||||
getUTCDate: proc (): int
|
||||
getUTCFullYear: proc (): int
|
||||
getUTCHours: proc (): int
|
||||
getUTCMilliseconds: proc (): int
|
||||
getUTCMinutes: proc (): int
|
||||
getUTCMonth: proc (): int
|
||||
getUTCSeconds: proc (): int
|
||||
getYear: proc (): int
|
||||
parse: proc (s: cstring): TTime
|
||||
setDate: proc (x: int)
|
||||
setFullYear: proc (x: int)
|
||||
setHours: proc (x: int)
|
||||
setMilliseconds: proc (x: int)
|
||||
setMinutes: proc (x: int)
|
||||
setMonth: proc (x: int)
|
||||
setSeconds: proc (x: int)
|
||||
setTime: proc (x: int)
|
||||
setUTCDate: proc (x: int)
|
||||
setUTCFullYear: proc (x: int)
|
||||
setUTCHours: proc (x: int)
|
||||
setUTCMilliseconds: proc (x: int)
|
||||
setUTCMinutes: proc (x: int)
|
||||
setUTCMonth: proc (x: int)
|
||||
setUTCSeconds: proc (x: int)
|
||||
setYear: proc (x: int)
|
||||
toGMTString: proc (): cstring
|
||||
toLocaleString: proc (): cstring
|
||||
UTC: proc (): int
|
||||
|
||||
TTimeInfo* = record ## represents a time in different parts
|
||||
|
||||
TTimeInfo* = object of TObject ## 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.
|
||||
|
|
@ -38,6 +79,7 @@ type
|
|||
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.
|
||||
## Always 0 if the target is ECMAScript.
|
||||
|
||||
proc getTime*(): TTime ## gets the current calendar time
|
||||
proc getLocalTime*(t: TTime): TTimeInfo
|
||||
|
|
@ -54,7 +96,7 @@ proc TimeInfoToTime*(timeInfo: TTimeInfo): TTime
|
|||
## them from the other information in the broken-down time structure.
|
||||
|
||||
proc `$` *(timeInfo: TTimeInfo): string
|
||||
## converts a `TTimeInfo` record to a
|
||||
## converts a `TTimeInfo` object to a
|
||||
## string representation.
|
||||
proc `$` *(time: TTime): string
|
||||
## converts a calendar time to a
|
||||
|
|
@ -72,92 +114,149 @@ proc `-` *(a, b: TTime): int64
|
|||
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
|
||||
when not defined(ECMAScript):
|
||||
|
||||
# C wrapper:
|
||||
type
|
||||
structTM {.importc: "struct tm", final.} = object
|
||||
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 `$`(timeInfo: TTimeInfo): string =
|
||||
return $asctime(timeInfoToTM(timeInfo))
|
||||
|
||||
proc `$`(time: TTime): string =
|
||||
var a = time
|
||||
return $ctime(addr(a))
|
||||
|
||||
PTimeInfo = ptr structTM
|
||||
PTime = ptr TTime
|
||||
else:
|
||||
proc getTime(): TTime {.importc: "new Date", nodecl.}
|
||||
|
||||
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 getLocalTime(t: TTime): TTimeInfo =
|
||||
result.second = t.getSeconds()
|
||||
result.minute = t.getMinutes()
|
||||
result.hour = t.getHours()
|
||||
result.monthday = t.getDate()
|
||||
result.month = TMonth(t.getMonth())
|
||||
result.year = t.getFullYear()
|
||||
result.weekday = weekDays[t.getDay()]
|
||||
result.yearday = 0
|
||||
|
||||
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 getGMTime(t: TTime): TTimeInfo =
|
||||
result.second = t.getUTCSeconds()
|
||||
result.minute = t.getUTCMinutes()
|
||||
result.hour = t.getUTCHours()
|
||||
result.monthday = t.getUTCDate()
|
||||
result.month = TMonth(t.getUTCMonth())
|
||||
result.year = t.getUTCFullYear()
|
||||
result.weekday = weekDays[t.getDay()]
|
||||
result.yearday = 0
|
||||
|
||||
proc TimeInfoToTime*(timeInfo: TTimeInfo): TTime =
|
||||
result = getTime()
|
||||
result.setSeconds(timeInfo.second)
|
||||
result.setMinutes(timeInfo.minute)
|
||||
result.setHours(timeInfo.hour)
|
||||
result.setMonth(ord(timeInfo.month))
|
||||
result.setFullYear(timeInfo.year)
|
||||
result.setDate(timeInfo.monthday)
|
||||
|
||||
proc `$`(timeInfo: TTimeInfo): string = return $(TimeInfoToTIme(timeInfo))
|
||||
proc `$`(time: TTime): string = $time.toLocaleString()
|
||||
|
||||
proc `-` (a, b: TTime): int64 =
|
||||
return a.getTime() - b.getTime()
|
||||
|
||||
var
|
||||
startMilsecs = getTime()
|
||||
|
||||
proc getStartMilsecs(): int =
|
||||
## get the miliseconds from the start of the program
|
||||
return int(getTime() - startMilsecs)
|
||||
|
||||
proc getDateStr(): string =
|
||||
var ti = getLocalTime(getTime())
|
||||
|
|
@ -169,11 +268,4 @@ proc getClockStr(): string =
|
|||
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
221
lib/typeinfo.nim
|
|
@ -1,221 +0,0 @@
|
|||
#
|
||||
#
|
||||
# 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
|
||||
|
|
@ -980,7 +980,7 @@ const
|
|||
#/////////////////////////////////////////////////////////
|
||||
|
||||
type
|
||||
mmtime* = record
|
||||
mmtime* {.final.} = object
|
||||
wType*: UINT
|
||||
hour*, min*, sec*, frame*, fps*, dummy*: int8
|
||||
pad*: array[0..1, int8]
|
||||
|
|
@ -990,7 +990,7 @@ type
|
|||
LPMMTIME* = ptr mmtime
|
||||
PWAVEHDR* = ptr wavehdr
|
||||
TMMTime* = mmtime
|
||||
wavehdr* = record
|
||||
wavehdr* {.final.} = object
|
||||
lpData*: cstring
|
||||
dwBufferLength*: DWORD
|
||||
dwBytesRecorded*: DWORD
|
||||
|
|
@ -1003,7 +1003,7 @@ type
|
|||
TWAVEHDR* = WAVEHDR
|
||||
NPWAVEHDR* = ptr wavehdr
|
||||
LPWAVEHDR* = ptr wavehdr
|
||||
WAVEOUTCAPSA* = record
|
||||
WAVEOUTCAPSA* {.final.} = object
|
||||
wMid*: int16
|
||||
wPid*: int16
|
||||
vDriverVersion*: MMVERSION
|
||||
|
|
@ -1017,7 +1017,7 @@ type
|
|||
PWAVEOUTCAPSA* = ptr WAVEOUTCAPSA
|
||||
NPWAVEOUTCAPSA* = ptr WAVEOUTCAPSA
|
||||
LPWAVEOUTCAPSA* = ptr WAVEOUTCAPSA
|
||||
WAVEOUTCAPSW* = record
|
||||
WAVEOUTCAPSW* {.final.} = object
|
||||
wMid*: int16
|
||||
wPid*: int16
|
||||
vDriverVersion*: MMVERSION
|
||||
|
|
@ -1046,7 +1046,7 @@ else:
|
|||
LPWAVEOUTCAPS* = LPWAVEOUTCAPSA
|
||||
type
|
||||
TWAVEOUTCAPS* = WAVEOUTCAPS
|
||||
WAVEINCAPSA* = record
|
||||
WAVEINCAPSA* {.final.} = object
|
||||
wMid*: int16
|
||||
wPid*: int16
|
||||
vDriverVersion*: MMVERSION
|
||||
|
|
@ -1059,7 +1059,7 @@ type
|
|||
NPWAVEINCAPSA* = ptr WAVEINCAPSA
|
||||
LPWAVEINCAPSA* = ptr WAVEINCAPSA
|
||||
TWAVEINCAPSA* = WAVEINCAPSA
|
||||
WAVEINCAPSW* = record
|
||||
WAVEINCAPSW* {.final.} = object
|
||||
wMid*: int16
|
||||
wPid*: int16
|
||||
vDriverVersion*: MMVERSION
|
||||
|
|
@ -1087,7 +1087,7 @@ else:
|
|||
LPWAVEINCAPS* = LPWAVEINCAPSA
|
||||
type
|
||||
TWAVEINCAPS* = WAVEINCAPS
|
||||
waveformat* = record
|
||||
waveformat* {.final.} = object
|
||||
wFormatTag*: int16
|
||||
nChannels*: int16
|
||||
nSamplesPerSec*: DWORD
|
||||
|
|
@ -1103,7 +1103,7 @@ const
|
|||
WAVE_FORMAT_PCM* = 1
|
||||
|
||||
type
|
||||
pcmwaveformat* = record
|
||||
pcmwaveformat* {.final.} = object
|
||||
wf*: WAVEFORMAT
|
||||
wBitsPerSample*: int16
|
||||
|
||||
|
|
@ -1111,7 +1111,7 @@ type
|
|||
NPPCMWAVEFORMAT* = ptr pcmwaveformat
|
||||
LPPCMWAVEFORMAT* = ptr pcmwaveformat
|
||||
TPCMWAVEFORMAT* = PCMWAVEFORMAT
|
||||
WAVEFORMATEX* = record
|
||||
WAVEFORMATEX* {.final.} = object
|
||||
wFormatTag*: int16
|
||||
nChannels*: int16
|
||||
nSamplesPerSec*: DWORD
|
||||
|
|
@ -1143,7 +1143,7 @@ type
|
|||
LPPATCHARRAY* = ptr int16
|
||||
KEYARRAY* = array[0..Pred(MIDIPATCHSIZE), int16]
|
||||
LPKEYARRAY* = ptr int16
|
||||
MIDIOUTCAPSA* = record
|
||||
MIDIOUTCAPSA* {.final.} = object
|
||||
wMid*: int16
|
||||
wPid*: int16
|
||||
vDriverVersion*: MMVERSION
|
||||
|
|
@ -1158,7 +1158,7 @@ type
|
|||
NPMIDIOUTCAPSA* = ptr MIDIOUTCAPSA
|
||||
LPMIDIOUTCAPSA* = ptr MIDIOUTCAPSA
|
||||
TMIDIOUTCAPSA* = MIDIOUTCAPSA
|
||||
MIDIOUTCAPSW* = record
|
||||
MIDIOUTCAPSW* {.final.} = object
|
||||
wMid*: int16
|
||||
wPid*: int16
|
||||
vDriverVersion*: MMVERSION
|
||||
|
|
@ -1173,7 +1173,7 @@ type
|
|||
NPMIDIOUTCAPSW* = ptr MIDIOUTCAPSW
|
||||
LPMIDIOUTCAPSW* = ptr MIDIOUTCAPSW
|
||||
TMIDIOUTCAPSW* = MIDIOUTCAPSW
|
||||
MIDIINCAPSA* = record
|
||||
MIDIINCAPSA* {.final.} = object
|
||||
wMid*: int16
|
||||
wPid*: int16
|
||||
vDriverVersion*: MMVERSION
|
||||
|
|
@ -1184,7 +1184,7 @@ type
|
|||
NPMIDIINCAPSA* = ptr MIDIINCAPSA
|
||||
LPMIDIINCAPSA* = ptr MIDIINCAPSA
|
||||
TMIDIINCAPSA* = MIDIINCAPSA
|
||||
MIDIINCAPSW* = record
|
||||
MIDIINCAPSW* {.final.} = object
|
||||
wMid*: int16
|
||||
wPid*: int16
|
||||
vDriverVersion*: MMVERSION
|
||||
|
|
@ -1219,7 +1219,7 @@ else:
|
|||
type
|
||||
TMIDIINCAPS* = MIDIINCAPS
|
||||
PMIDIHDR* = ptr midihdr
|
||||
midihdr* = record
|
||||
midihdr* {.final.} = object
|
||||
lpData*: cstring
|
||||
dwBufferLength*: DWORD
|
||||
dwBytesRecorded*: DWORD
|
||||
|
|
@ -1233,30 +1233,30 @@ type
|
|||
NPMIDIHDR* = ptr midihdr
|
||||
LPMIDIHDR* = ptr midihdr
|
||||
TMIDIHDR* = MIDIHDR
|
||||
midievent* = record
|
||||
midievent* {.final.} = object
|
||||
dwDeltaTime*: DWORD
|
||||
dwStreamID*: DWORD
|
||||
dwEvent*: DWORD
|
||||
dwParms*: array[0..Pred(1), DWORD]
|
||||
|
||||
TMIDIEVENT* = MIDIEVENT
|
||||
midistrmbuffver* = record
|
||||
midistrmbuffver* {.final.} = object
|
||||
dwVersion*: DWORD
|
||||
dwMid*: DWORD
|
||||
dwOEMVersion*: DWORD
|
||||
|
||||
TMIDISTRMBUFFVER* = MIDISTRMBUFFVER
|
||||
Tmidiproptimediv* = record
|
||||
Tmidiproptimediv* {.final.} = object
|
||||
cbStruct*: DWORD
|
||||
dwTimeDiv*: DWORD
|
||||
|
||||
LPMIDIPROPTIMEDIV* = ptr Tmidiproptimediv
|
||||
Tmidiproptempo* = record
|
||||
Tmidiproptempo* {.final.} = object
|
||||
cbStruct*: DWORD
|
||||
dwTempo*: DWORD
|
||||
|
||||
LPMIDIPROPTEMPO* = ptr Tmidiproptempo
|
||||
AUXCAPSA* = record
|
||||
AUXCAPSA* {.final.} = object
|
||||
wMid*: int16
|
||||
wPid*: int16
|
||||
vDriverVersion*: MMVERSION
|
||||
|
|
@ -1269,7 +1269,7 @@ type
|
|||
NPAUXCAPSA* = ptr AUXCAPSA
|
||||
LPAUXCAPSA* = ptr AUXCAPSA
|
||||
TAUXCAPSA* = AUXCAPSA
|
||||
AUXCAPSW* = record
|
||||
AUXCAPSW* {.final.} = object
|
||||
wMid*: int16
|
||||
wPid*: int16
|
||||
vDriverVersion*: MMVERSION
|
||||
|
|
@ -1305,7 +1305,7 @@ type
|
|||
proc mixerGetNumDevs*(): UINT{.stdcall, dynlib: "winmm.dll",
|
||||
importc: "mixerGetNumDevs".}
|
||||
type
|
||||
MIXERCAPSA* = record
|
||||
MIXERCAPSA* {.final.} = object
|
||||
wMid*: int16
|
||||
wPid*: int16
|
||||
vDriverVersion*: MMVERSION
|
||||
|
|
@ -1316,7 +1316,7 @@ type
|
|||
PMIXERCAPSA* = ptr MIXERCAPSA
|
||||
LPMIXERCAPSA* = ptr MIXERCAPSA
|
||||
TMIXERCAPSA* = MIXERCAPSA
|
||||
MIXERCAPSW* = record
|
||||
MIXERCAPSW* {.final.} = object
|
||||
wMid*: int16
|
||||
wPid*: int16
|
||||
vDriverVersion*: MMVERSION
|
||||
|
|
@ -1340,7 +1340,7 @@ else:
|
|||
LPMIXERCAPS* = LPMIXERCAPSA
|
||||
type
|
||||
TMIXERCAPS* = MIXERCAPS
|
||||
MIXERLINEA* = record
|
||||
MIXERLINEA* {.final.} = object
|
||||
cbStruct*: DWORD
|
||||
dwDestination*: DWORD
|
||||
dwSource*: DWORD
|
||||
|
|
@ -1361,7 +1361,7 @@ type
|
|||
PMIXERLINEA* = ptr MIXERLINEA
|
||||
LPMIXERLINEA* = ptr MIXERLINEA
|
||||
TMIXERLINEA* = MIXERLINEA
|
||||
MIXERLINEW* = record
|
||||
MIXERLINEW* {.final.} = object
|
||||
cbStruct*: DWORD
|
||||
dwDestination*: DWORD
|
||||
dwSource*: DWORD
|
||||
|
|
@ -1395,7 +1395,7 @@ else:
|
|||
LPMIXERLINE* = LPMIXERLINEA
|
||||
type
|
||||
TMIXERLINE* = MIXERLINE
|
||||
MIXERCONTROLA* = record
|
||||
MIXERCONTROLA* {.final.} = object
|
||||
cbStruct*: DWORD
|
||||
dwControlID*: DWORD
|
||||
dwControlType*: DWORD
|
||||
|
|
@ -1411,7 +1411,7 @@ type
|
|||
PMIXERCONTROLA* = ptr MIXERCONTROLA
|
||||
LPMIXERCONTROLA* = ptr MIXERCONTROLA
|
||||
TMIXERCONTROLA* = MIXERCONTROLA
|
||||
MIXERCONTROLW* = record
|
||||
MIXERCONTROLW* {.final.} = object
|
||||
cbStruct*: DWORD
|
||||
dwControlID*: DWORD
|
||||
dwControlType*: DWORD
|
||||
|
|
@ -1440,7 +1440,7 @@ else:
|
|||
LPMIXERCONTROL* = LPMIXERCONTROLA
|
||||
type
|
||||
TMIXERCONTROL* = MIXERCONTROL
|
||||
MIXERLINECONTROLSA* = record
|
||||
MIXERLINECONTROLSA* {.final.} = object
|
||||
cbStruct*: DWORD
|
||||
dwLineID*: DWORD
|
||||
dwControlType*, cControls*, cbmxctrl*: DWORD
|
||||
|
|
@ -1449,7 +1449,7 @@ type
|
|||
PMIXERLINECONTROLSA* = ptr MIXERLINECONTROLSA
|
||||
LPMIXERLINECONTROLSA* = ptr MIXERLINECONTROLSA
|
||||
TMIXERLINECONTROLSA* = MIXERLINECONTROLSA
|
||||
MIXERLINECONTROLSW* = record
|
||||
MIXERLINECONTROLSW* {.final.} = object
|
||||
cbStruct*: DWORD
|
||||
dwLineID*: DWORD
|
||||
dwControlType*, cControls*, cbmxctrl*: DWORD
|
||||
|
|
@ -1471,7 +1471,7 @@ else:
|
|||
LPMIXERLINECONTROLS* = LPMIXERLINECONTROLSA
|
||||
type
|
||||
TMIXERLINECONTROLS* = MIXERLINECONTROLS
|
||||
TMIXERCONTROLDETAILS* = record
|
||||
TMIXERCONTROLDETAILS* {.final.} = object
|
||||
cbStruct*: DWORD
|
||||
dwControlID*: DWORD
|
||||
cChannels*: DWORD
|
||||
|
|
@ -1481,7 +1481,7 @@ type
|
|||
MIXERCONTROLDETAILS* = tMIXERCONTROLDETAILS
|
||||
PMIXERCONTROLDETAILS* = ptr tMIXERCONTROLDETAILS
|
||||
LPMIXERCONTROLDETAILS* = ptr tMIXERCONTROLDETAILS
|
||||
MIXERCONTROLDETAILS_LISTTEXTA* = record
|
||||
MIXERCONTROLDETAILS_LISTTEXTA* {.final.} = object
|
||||
dwParam1*: DWORD
|
||||
dwParam2*: DWORD
|
||||
szName*: array[0..Pred(MIXER_LONG_NAME_CHARS), CHAR]
|
||||
|
|
@ -1489,7 +1489,7 @@ type
|
|||
PMIXERCONTROLDETAILS_LISTTEXTA* = ptr MIXERCONTROLDETAILS_LISTTEXTA
|
||||
LPMIXERCONTROLDETAILS_LISTTEXTA* = ptr MIXERCONTROLDETAILS_LISTTEXTA
|
||||
TMIXERCONTROLDETAILS_LISTTEXTA* = MIXERCONTROLDETAILS_LISTTEXTA
|
||||
MIXERCONTROLDETAILS_LISTTEXTW* = record
|
||||
MIXERCONTROLDETAILS_LISTTEXTW* {.final.} = object
|
||||
dwParam1*: DWORD
|
||||
dwParam2*: DWORD
|
||||
szName*: array[0..Pred(MIXER_LONG_NAME_CHARS), WCHAR]
|
||||
|
|
@ -1510,19 +1510,19 @@ else:
|
|||
LPMIXERCONTROLDETAILS_LISTTEXT* = LPMIXERCONTROLDETAILS_LISTTEXTA
|
||||
type
|
||||
TMIXERCONTROLDETAILS_LISTTEXT* = MIXERCONTROLDETAILS_LISTTEXT
|
||||
MIXERCONTROLDETAILS_BOOLEAN* = record
|
||||
MIXERCONTROLDETAILS_BOOLEAN* {.final.} = object
|
||||
fValue*: int32
|
||||
|
||||
PMIXERCONTROLDETAILS_BOOLEAN* = ptr MIXERCONTROLDETAILS_BOOLEAN
|
||||
LPMIXERCONTROLDETAILS_BOOLEAN* = ptr MIXERCONTROLDETAILS_BOOLEAN
|
||||
TMIXERCONTROLDETAILS_BOOLEAN* = MIXERCONTROLDETAILS_BOOLEAN
|
||||
MIXERCONTROLDETAILS_SIGNED* = record
|
||||
MIXERCONTROLDETAILS_SIGNED* {.final.} = object
|
||||
lValue*: int32
|
||||
|
||||
PMIXERCONTROLDETAILS_SIGNED* = ptr MIXERCONTROLDETAILS_SIGNED
|
||||
LPMIXERCONTROLDETAILS_SIGNED* = ptr MIXERCONTROLDETAILS_SIGNED
|
||||
TMIXERCONTROLDETAILS_SIGNED* = MIXERCONTROLDETAILS_SIGNED
|
||||
MIXERCONTROLDETAILS_UNSIGNED* = record
|
||||
MIXERCONTROLDETAILS_UNSIGNED* {.final.} = object
|
||||
dwValue*: DWORD
|
||||
|
||||
PMIXERCONTROLDETAILS_UNSIGNED* = ptr MIXERCONTROLDETAILS_UNSIGNED
|
||||
|
|
@ -1531,7 +1531,7 @@ type
|
|||
LPTIMECALLBACK* = proc (uTimerID, uMsg: UINT, dwUser, dw1, dw2: DWORD){.
|
||||
stdcall.}
|
||||
TTIMECALLBACK* = LPTIMECALLBACK
|
||||
timecaps* = record
|
||||
timecaps* {.final.} = object
|
||||
wPeriodMin*: UINT
|
||||
wPeriodMax*: UINT
|
||||
|
||||
|
|
@ -1539,7 +1539,7 @@ type
|
|||
NPTIMECAPS* = ptr timecaps
|
||||
LPTIMECAPS* = ptr timecaps
|
||||
TTIMECAS* = TIMECAPS
|
||||
JOYCAPSA* = record
|
||||
JOYCAPSA* {.final.} = object
|
||||
wMid*: int16
|
||||
wPid*: int16
|
||||
szPname*: array[0..Pred(MAXPNAMELEN), CHAR]
|
||||
|
|
@ -1569,7 +1569,7 @@ type
|
|||
NPJOYCAPSA* = ptr JOYCAPSA
|
||||
LPJOYCAPSA* = ptr JOYCAPSA
|
||||
TJOYCAPSA* = JOYCAPSA
|
||||
JOYCAPSW* = record
|
||||
JOYCAPSW* {.final.} = object
|
||||
wMid*: int16
|
||||
wPid*: int16
|
||||
szPname*: array[0..Pred(MAXPNAMELEN), WCHAR]
|
||||
|
|
@ -1614,7 +1614,7 @@ else:
|
|||
LPJOYCAPS* = LPJOYCAPSA
|
||||
type
|
||||
TJOYCAPS* = JOYCAPS
|
||||
joyinfo* = record
|
||||
joyinfo* {.final.} = object
|
||||
wXpos*: UINT
|
||||
wYpos*: UINT
|
||||
wZpos*: UINT
|
||||
|
|
@ -1624,7 +1624,7 @@ type
|
|||
NPJOYINFO* = ptr joyinfo
|
||||
LPJOYINFO* = ptr joyinfo
|
||||
TJOYINFO* = JOYINFO
|
||||
joyinfoex* = record
|
||||
joyinfoex* {.final.} = object
|
||||
dwSize*: DWORD
|
||||
dwFlags*: DWORD
|
||||
wXpos*: UINT
|
||||
|
|
@ -1648,7 +1648,7 @@ type
|
|||
HMMIO* = THandle
|
||||
LPMMIOPROC* = proc (x1: LPSTR, x2: UINT, x3, x4: LPARAM): LRESULT{.stdcall.}
|
||||
TMMIOPROC* = LPMMIOPROC
|
||||
MMIOINFO* = record
|
||||
MMIOINFO* {.final.} = object
|
||||
dwFlags*: DWORD
|
||||
fccIOProc*: FOURCC
|
||||
pIOProc*: LPMMIOPROC
|
||||
|
|
@ -1671,7 +1671,7 @@ type
|
|||
LPMMIOINFO* = ptr MMIOINFO
|
||||
LPCMMIOINFO* = ptr MMIOINFO
|
||||
TMMIOINFO* = MMIOINFO
|
||||
MMCKINFO* = record
|
||||
MMCKINFO* {.final.} = object
|
||||
ckid*: FOURCC
|
||||
cksize*: DWORD
|
||||
fccType*: FOURCC
|
||||
|
|
@ -1687,13 +1687,13 @@ type
|
|||
MCIDEVICEID* = UINT
|
||||
YIELDPROC* = proc (mciId: MCIDEVICEID, dwYieldData: DWORD): UINT{.stdcall.}
|
||||
TYIELDPROC* = YIELDPROC
|
||||
MCI_GENERIC_PARMS* = record
|
||||
MCI_GENERIC_PARMS* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
|
||||
PMCI_GENERIC_PARMS* = ptr MCI_GENERIC_PARMS
|
||||
LPMCI_GENERIC_PARMS* = ptr MCI_GENERIC_PARMS
|
||||
TMCI_GENERIC_PARMS* = MCI_GENERIC_PARMS
|
||||
MCI_OPEN_PARMSA* = record
|
||||
MCI_OPEN_PARMSA* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
wDeviceID*: MCIDEVICEID
|
||||
lpstrDeviceType*: LPCSTR
|
||||
|
|
@ -1703,7 +1703,7 @@ type
|
|||
PMCI_OPEN_PARMSA* = ptr MCI_OPEN_PARMSA
|
||||
LPMCI_OPEN_PARMSA* = ptr MCI_OPEN_PARMSA
|
||||
TMCI_OPEN_PARMSA* = MCI_OPEN_PARMSA
|
||||
MCI_OPEN_PARMSW* = record
|
||||
MCI_OPEN_PARMSW* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
wDeviceID*: MCIDEVICEID
|
||||
lpstrDeviceType*: LPCWSTR
|
||||
|
|
@ -1726,7 +1726,7 @@ else:
|
|||
LPMCI_OPEN_PARMS* = LPMCI_OPEN_PARMSA
|
||||
type
|
||||
TMCI_OPEN_PARMS* = MCI_OPEN_PARMS
|
||||
MCI_PLAY_PARMS* = record
|
||||
MCI_PLAY_PARMS* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
dwFrom*: DWORD
|
||||
dwTo*: DWORD
|
||||
|
|
@ -1734,14 +1734,14 @@ type
|
|||
PMCI_PLAY_PARMS* = ptr MCI_PLAY_PARMS
|
||||
LPMCI_PLAY_PARMS* = ptr MCI_PLAY_PARMS
|
||||
TMCI_PLAY_PARMS* = MCI_PLAY_PARMS
|
||||
MCI_SEEK_PARMS* = record
|
||||
MCI_SEEK_PARMS* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
dwTo*: DWORD
|
||||
|
||||
PMCI_SEEK_PARMS* = ptr MCI_SEEK_PARMS
|
||||
LPMCI_SEEK_PARMS* = ptr MCI_SEEK_PARMS
|
||||
TMCI_SEEK_PARMS* = MCI_SEEK_PARMS
|
||||
MCI_STATUS_PARMS* = record
|
||||
MCI_STATUS_PARMS* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
dwReturn*: DWORD
|
||||
dwItem*: DWORD
|
||||
|
|
@ -1750,14 +1750,14 @@ type
|
|||
PMCI_STATUS_PARMS* = ptr MCI_STATUS_PARMS
|
||||
LPMCI_STATUS_PARMS* = ptr MCI_STATUS_PARMS
|
||||
TMCI_STATUS_PARMS* = MCI_STATUS_PARMS
|
||||
MCI_INFO_PARMSA* = record
|
||||
MCI_INFO_PARMSA* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
lpstrReturn*: cstring
|
||||
dwRetSize*: DWORD
|
||||
|
||||
LPMCI_INFO_PARMSA* = ptr MCI_INFO_PARMSA
|
||||
TMCI_INFO_PARMSA* = MCI_INFO_PARMSA
|
||||
MCI_INFO_PARMSW* = record
|
||||
MCI_INFO_PARMSW* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
lpstrReturn*: LPWSTR
|
||||
dwRetSize*: DWORD
|
||||
|
|
@ -1775,7 +1775,7 @@ else:
|
|||
LPMCI_INFO_PARMS* = LPMCI_INFO_PARMSA
|
||||
type
|
||||
TMCI_INFO_PARMS* = MCI_INFO_PARMS
|
||||
MCI_GETDEVCAPS_PARMS* = record
|
||||
MCI_GETDEVCAPS_PARMS* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
dwReturn*: DWORD
|
||||
dwItem*: DWORD
|
||||
|
|
@ -1783,7 +1783,7 @@ type
|
|||
PMCI_GETDEVCAPS_PARMS* = ptr MCI_GETDEVCAPS_PARMS
|
||||
LPMCI_GETDEVCAPS_PARMS* = ptr MCI_GETDEVCAPS_PARMS
|
||||
TMCI_GETDEVCAPS_PARMS* = MCI_GETDEVCAPS_PARMS
|
||||
MCI_SYSINFO_PARMSA* = record
|
||||
MCI_SYSINFO_PARMSA* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
lpstrReturn*: cstring
|
||||
dwRetSize*: DWORD
|
||||
|
|
@ -1793,7 +1793,7 @@ type
|
|||
PMCI_SYSINFO_PARMSA* = ptr MCI_SYSINFO_PARMSA
|
||||
LPMCI_SYSINFO_PARMSA* = ptr MCI_SYSINFO_PARMSA
|
||||
TMCI_SYSINFO_PARMSA* = MCI_SYSINFO_PARMSA
|
||||
MCI_SYSINFO_PARMSW* = record
|
||||
MCI_SYSINFO_PARMSW* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
lpstrReturn*: LPWSTR
|
||||
dwRetSize*: DWORD
|
||||
|
|
@ -1816,7 +1816,7 @@ else:
|
|||
LPMCI_SYSINFO_PARMS* = LPMCI_SYSINFO_PARMSA
|
||||
type
|
||||
TMCI_SYSINFO_PARMS* = MCI_SYSINFO_PARMS
|
||||
MCI_SET_PARMS* = record
|
||||
MCI_SET_PARMS* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
dwTimeFormat*: DWORD
|
||||
dwAudio*: DWORD
|
||||
|
|
@ -1824,7 +1824,7 @@ type
|
|||
PMCI_SET_PARMS* = ptr MCI_SET_PARMS
|
||||
LPMCI_SET_PARMS* = ptr MCI_SET_PARMS
|
||||
TMCI_SET_PARMS* = MCI_SET_PARMS
|
||||
MCI_BREAK_PARMS* = record
|
||||
MCI_BREAK_PARMS* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
nVirtKey*: int32
|
||||
hwndBreak*: HWND
|
||||
|
|
@ -1832,14 +1832,14 @@ type
|
|||
PMCI_BREAK_PARMS* = ptr MCI_BREAK_PARMS
|
||||
LPMCI_BREAK_PARMS* = ptr MCI_BREAK_PARMS
|
||||
TMCI_BREAK_PARMS* = MCI_BREAK_PARMS
|
||||
MCI_SAVE_PARMSA* = record
|
||||
MCI_SAVE_PARMSA* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
lpfilename*: LPCSTR
|
||||
|
||||
PMCI_SAVE_PARMSA* = ptr MCI_SAVE_PARMSA
|
||||
LPMCI_SAVE_PARMSA* = ptr MCI_SAVE_PARMSA
|
||||
TMCI_SAVE_PARMSA* = MCI_SAVE_PARMSA
|
||||
MCI_SAVE_PARMSW* = record
|
||||
MCI_SAVE_PARMSW* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
lpfilename*: LPCWSTR
|
||||
|
||||
|
|
@ -1859,14 +1859,14 @@ else:
|
|||
LPMCI_SAVE_PARMS* = LPMCI_SAVE_PARMSA
|
||||
type
|
||||
TMCI_SAVE_PARMS* = MCI_SAVE_PARMS
|
||||
MCI_LOAD_PARMSA* = record
|
||||
MCI_LOAD_PARMSA* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
lpfilename*: LPCSTR
|
||||
|
||||
PMCI_LOAD_PARMSA* = ptr MCI_LOAD_PARMSA
|
||||
LPMCI_LOAD_PARMSA* = ptr MCI_LOAD_PARMSA
|
||||
TMCI_LOAD_PARMSA* = MCI_LOAD_PARMSA
|
||||
MCI_LOAD_PARMSW* = record
|
||||
MCI_LOAD_PARMSW* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
lpfilename*: LPCWSTR
|
||||
|
||||
|
|
@ -1886,14 +1886,14 @@ else:
|
|||
LPMCI_LOAD_PARMS* = LPMCI_LOAD_PARMSA
|
||||
type
|
||||
TMCI_LOAD_PARMS* = MCI_LOAD_PARMS
|
||||
MCI_RECORD_PARMS* = record
|
||||
MCI_RECORD_PARMS* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
dwFrom*: DWORD
|
||||
dwTo*: DWORD
|
||||
|
||||
LPMCI_RECORD_PARMS* = ptr MCI_RECORD_PARMS
|
||||
TMCI_RECORD_PARMS* = MCI_RECORD_PARMS
|
||||
MCI_VD_PLAY_PARMS* = record
|
||||
MCI_VD_PLAY_PARMS* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
dwFrom*: DWORD
|
||||
dwTo*: DWORD
|
||||
|
|
@ -1902,20 +1902,20 @@ type
|
|||
PMCI_VD_PLAY_PARMS* = ptr MCI_VD_PLAY_PARMS
|
||||
LPMCI_VD_PLAY_PARMS* = ptr MCI_VD_PLAY_PARMS
|
||||
TMCI_VD_PLAY_PARMS* = MCI_VD_PLAY_PARMS
|
||||
MCI_VD_STEP_PARMS* = record
|
||||
MCI_VD_STEP_PARMS* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
dwFrames*: DWORD
|
||||
|
||||
PMCI_VD_STEP_PARMS* = ptr MCI_VD_STEP_PARMS
|
||||
LPMCI_VD_STEP_PARMS* = ptr MCI_VD_STEP_PARMS
|
||||
MCI_VD_ESCAPE_PARMSA* = record
|
||||
MCI_VD_ESCAPE_PARMSA* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
lpstrCommand*: LPCSTR
|
||||
|
||||
PMCI_VD_ESCAPE_PARMSA* = ptr MCI_VD_ESCAPE_PARMSA
|
||||
LPMCI_VD_ESCAPE_PARMSA* = ptr MCI_VD_ESCAPE_PARMSA
|
||||
TMCI_VD_ESCAPE_PARMSA* = MCI_VD_ESCAPE_PARMSA
|
||||
MCI_VD_ESCAPE_PARMSW* = record
|
||||
MCI_VD_ESCAPE_PARMSW* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
lpstrCommand*: LPCWSTR
|
||||
|
||||
|
|
@ -1935,7 +1935,7 @@ else:
|
|||
LPMCI_VD_ESCAPE_PARMS* = LPMCI_VD_ESCAPE_PARMSA
|
||||
type
|
||||
TMCI_VD_ESCAPE_PARMS* = MCI_VD_ESCAPE_PARMS
|
||||
MCI_WAVE_OPEN_PARMSA* = record
|
||||
MCI_WAVE_OPEN_PARMSA* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
wDeviceID*: MCIDEVICEID
|
||||
lpstrDeviceType*: LPCSTR
|
||||
|
|
@ -1946,7 +1946,7 @@ type
|
|||
PMCI_WAVE_OPEN_PARMSA* = ptr MCI_WAVE_OPEN_PARMSA
|
||||
LPMCI_WAVE_OPEN_PARMSA* = ptr MCI_WAVE_OPEN_PARMSA
|
||||
TMCI_WAVE_OPEN_PARMSA* = MCI_WAVE_OPEN_PARMSA
|
||||
MCI_WAVE_OPEN_PARMSW* = record
|
||||
MCI_WAVE_OPEN_PARMSW* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
wDeviceID*: MCIDEVICEID
|
||||
lpstrDeviceType*: LPCWSTR
|
||||
|
|
@ -1970,7 +1970,7 @@ else:
|
|||
LPMCI_WAVE_OPEN_PARMS* = LPMCI_WAVE_OPEN_PARMSA
|
||||
type
|
||||
TMCI_WAVE_OPEN_PARMS* = MCI_WAVE_OPEN_PARMS
|
||||
MCI_WAVE_DELETE_PARMS* = record
|
||||
MCI_WAVE_DELETE_PARMS* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
dwFrom*: DWORD
|
||||
dwTo*: DWORD
|
||||
|
|
@ -1978,7 +1978,7 @@ type
|
|||
PMCI_WAVE_DELETE_PARMS* = ptr MCI_WAVE_DELETE_PARMS
|
||||
LPMCI_WAVE_DELETE_PARMS* = ptr MCI_WAVE_DELETE_PARMS
|
||||
TMCI_WAVE_DELETE_PARMS* = MCI_WAVE_DELETE_PARMS
|
||||
MCI_WAVE_SET_PARMS* = record
|
||||
MCI_WAVE_SET_PARMS* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
dwTimeFormat*: DWORD
|
||||
dwAudio*: DWORD
|
||||
|
|
@ -1998,7 +1998,7 @@ type
|
|||
PMCI_WAVE_SET_PARMS* = ptr MCI_WAVE_SET_PARMS
|
||||
LPMCI_WAVE_SET_PARMS* = ptr MCI_WAVE_SET_PARMS
|
||||
TMCI_WAVE_SET_PARMS* = MCI_WAVE_SET_PARMS
|
||||
MCI_SEQ_SET_PARMS* = record
|
||||
MCI_SEQ_SET_PARMS* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
dwTimeFormat*: DWORD
|
||||
dwAudio*: DWORD
|
||||
|
|
@ -2011,7 +2011,7 @@ type
|
|||
PMCI_SEQ_SET_PARMS* = ptr MCI_SEQ_SET_PARMS
|
||||
LPMCI_SEQ_SET_PARMS* = ptr MCI_SEQ_SET_PARMS
|
||||
TMCI_SEQ_SET_PARMS* = MCI_SEQ_SET_PARMS
|
||||
MCI_ANIM_OPEN_PARMSA* = record
|
||||
MCI_ANIM_OPEN_PARMSA* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
wDeviceID*: MCIDEVICEID
|
||||
lpstrDeviceType*: LPCSTR
|
||||
|
|
@ -2023,7 +2023,7 @@ type
|
|||
PMCI_ANIM_OPEN_PARMSA* = ptr MCI_ANIM_OPEN_PARMSA
|
||||
LPMCI_ANIM_OPEN_PARMSA* = ptr MCI_ANIM_OPEN_PARMSA
|
||||
TMCI_ANIM_OPEN_PARMSA* = MCI_ANIM_OPEN_PARMSA
|
||||
MCI_ANIM_OPEN_PARMSW* = record
|
||||
MCI_ANIM_OPEN_PARMSW* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
wDeviceID*: MCIDEVICEID
|
||||
lpstrDeviceType*: LPCWSTR
|
||||
|
|
@ -2047,7 +2047,7 @@ else:
|
|||
LPMCI_ANIM_OPEN_PARMS* = LPMCI_ANIM_OPEN_PARMSA
|
||||
type
|
||||
TMCI_ANIM_OPEN_PARMS* = MCI_ANIM_OPEN_PARMS
|
||||
MCI_ANIM_WINDOW_PARMSW* = record
|
||||
MCI_ANIM_WINDOW_PARMSW* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
hWnd*: HWND
|
||||
nCmdShow*: UINT
|
||||
|
|
@ -2056,14 +2056,14 @@ type
|
|||
PMCI_ANIM_WINDOW_PARMSW* = ptr MCI_ANIM_WINDOW_PARMSW
|
||||
LPMCI_ANIM_WINDOW_PARMSW* = ptr MCI_ANIM_WINDOW_PARMSW
|
||||
TMCI_ANIM_WINDOW_PARMSW* = MCI_ANIM_WINDOW_PARMSW
|
||||
MCI_ANIM_STEP_PARMS* = record
|
||||
MCI_ANIM_STEP_PARMS* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
dwFrames*: DWORD
|
||||
|
||||
PMCI_ANIM_STEP_PARMS* = ptr MCI_ANIM_STEP_PARMS
|
||||
LPMCI_ANIM_STEP_PARMS* = ptr MCI_ANIM_STEP_PARMS
|
||||
TMCI_ANIM_STEP_PARMS* = MCI_ANIM_STEP_PARMS
|
||||
MCI_ANIM_WINDOW_PARMSA* = record
|
||||
MCI_ANIM_WINDOW_PARMSA* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
hWnd*: HWND
|
||||
nCmdShow*: UINT
|
||||
|
|
@ -2072,7 +2072,7 @@ type
|
|||
PMCI_ANIM_WINDOW_PARMSA* = ptr MCI_ANIM_WINDOW_PARMSA
|
||||
LPMCI_ANIM_WINDOW_PARMSA* = ptr MCI_ANIM_WINDOW_PARMSA
|
||||
TMCI_ANIM_WINDOW_PARMSA* = MCI_ANIM_WINDOW_PARMSA
|
||||
MCI_ANIM_PLAY_PARMS* = record
|
||||
MCI_ANIM_PLAY_PARMS* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
dwFrom*: DWORD
|
||||
dwTo*: DWORD
|
||||
|
|
@ -2092,14 +2092,14 @@ else:
|
|||
PMCI_ANIM_WINDOW_PARMS* = PMCI_ANIM_WINDOW_PARMSA
|
||||
LPMCI_ANIM_WINDOW_PARMS* = LPMCI_ANIM_WINDOW_PARMSA
|
||||
type
|
||||
MCI_ANIM_RECT_PARMS* = record
|
||||
MCI_ANIM_RECT_PARMS* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
rc*: TRECT
|
||||
|
||||
PMCI_ANIM_RECT_PARMS* = ptr MCI_ANIM_RECT_PARMS
|
||||
LPMCI_ANIM_RECT_PARMS* = ptr MCI_ANIM_RECT_PARMS
|
||||
TMCI_ANIM_RECT_PARMS* = MCI_ANIM_RECT_PARMS
|
||||
MCI_ANIM_UPDATE_PARMS* = record
|
||||
MCI_ANIM_UPDATE_PARMS* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
rc*: TRECT
|
||||
hDC*: HDC
|
||||
|
|
@ -2107,7 +2107,7 @@ type
|
|||
PMCI_ANIM_UPDATE_PARMS* = ptr MCI_ANIM_UPDATE_PARMS
|
||||
LPMCI_ANIM_UPDATE_PARMS* = ptr MCI_ANIM_UPDATE_PARMS
|
||||
TMCI_ANIM_UPDATE_PARMS* = MCI_ANIM_UPDATE_PARMS
|
||||
MCI_OVLY_OPEN_PARMSA* = record
|
||||
MCI_OVLY_OPEN_PARMSA* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
wDeviceID*: MCIDEVICEID
|
||||
lpstrDeviceType*: LPCSTR
|
||||
|
|
@ -2119,7 +2119,7 @@ type
|
|||
PMCI_OVLY_OPEN_PARMSA* = ptr MCI_OVLY_OPEN_PARMSA
|
||||
LPMCI_OVLY_OPEN_PARMSA* = ptr MCI_OVLY_OPEN_PARMSA
|
||||
TMCI_OVLY_OPEN_PARMSA* = MCI_OVLY_OPEN_PARMSA
|
||||
MCI_OVLY_OPEN_PARMSW* = record
|
||||
MCI_OVLY_OPEN_PARMSW* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
wDeviceID*: MCIDEVICEID
|
||||
lpstrDeviceType*: LPCWSTR
|
||||
|
|
@ -2144,7 +2144,7 @@ else:
|
|||
LPMCI_OVLY_OPEN_PARMS* = LPMCI_OVLY_OPEN_PARMSA
|
||||
type
|
||||
TMCI_OVLY_OPEN_PARMS* = MCI_OVLY_OPEN_PARMS
|
||||
MCI_OVLY_WINDOW_PARMSA* = record
|
||||
MCI_OVLY_WINDOW_PARMSA* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
hWnd*: HWND
|
||||
nCmdShow*: UINT
|
||||
|
|
@ -2153,7 +2153,7 @@ type
|
|||
PMCI_OVLY_WINDOW_PARMSA* = ptr MCI_OVLY_WINDOW_PARMSA
|
||||
LPMCI_OVLY_WINDOW_PARMSA* = ptr MCI_OVLY_WINDOW_PARMSA
|
||||
TMCI_OVLY_WINDOW_PARMSA* = MCI_OVLY_WINDOW_PARMSA
|
||||
MCI_OVLY_WINDOW_PARMSW* = record
|
||||
MCI_OVLY_WINDOW_PARMSW* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
hWnd*: HWND
|
||||
nCmdShow*: UINT
|
||||
|
|
@ -2175,14 +2175,14 @@ else:
|
|||
LPMCI_OVLY_WINDOW_PARMS* = LPMCI_OVLY_WINDOW_PARMSA
|
||||
type
|
||||
TMCI_OVLY_WINDOW_PARMS* = MCI_OVLY_WINDOW_PARMSW
|
||||
MCI_OVLY_RECT_PARMS* = record
|
||||
MCI_OVLY_RECT_PARMS* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
rc*: TRECT
|
||||
|
||||
PMCI_OVLY_RECT_PARMS* = ptr MCI_OVLY_RECT_PARMS
|
||||
LPMCI_OVLY_RECT_PARMS* = ptr MCI_OVLY_RECT_PARMS
|
||||
TMCI_OVLY_RECT_PARMS* = MCI_OVLY_RECT_PARMS
|
||||
MCI_OVLY_SAVE_PARMSA* = record
|
||||
MCI_OVLY_SAVE_PARMSA* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
lpfilename*: LPCSTR
|
||||
rc*: TRECT
|
||||
|
|
@ -2190,7 +2190,7 @@ type
|
|||
PMCI_OVLY_SAVE_PARMSA* = ptr MCI_OVLY_SAVE_PARMSA
|
||||
LPMCI_OVLY_SAVE_PARMSA* = ptr MCI_OVLY_SAVE_PARMSA
|
||||
TMCI_OVLY_SAVE_PARMSA* = MCI_OVLY_SAVE_PARMSA
|
||||
MCI_OVLY_SAVE_PARMSW* = record
|
||||
MCI_OVLY_SAVE_PARMSW* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
lpfilename*: LPCWSTR
|
||||
rc*: TRECT
|
||||
|
|
@ -2211,7 +2211,7 @@ else:
|
|||
LPMCI_OVLY_SAVE_PARMS* = LPMCI_OVLY_SAVE_PARMSA
|
||||
type
|
||||
TMCI_OVLY_SAVE_PARMS* = MCI_OVLY_SAVE_PARMS
|
||||
MCI_OVLY_LOAD_PARMSA* = record
|
||||
MCI_OVLY_LOAD_PARMSA* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
lpfilename*: LPCSTR
|
||||
rc*: TRECT
|
||||
|
|
@ -2219,7 +2219,7 @@ type
|
|||
PMCI_OVLY_LOAD_PARMSA* = ptr MCI_OVLY_LOAD_PARMSA
|
||||
LPMCI_OVLY_LOAD_PARMSA* = ptr MCI_OVLY_LOAD_PARMSA
|
||||
TMCI_OVLY_LOAD_PARMSA* = MCI_OVLY_LOAD_PARMSA
|
||||
MCI_OVLY_LOAD_PARMSW* = record
|
||||
MCI_OVLY_LOAD_PARMSW* {.final.} = object
|
||||
dwCallback*: DWORD
|
||||
lpfilename*: LPCWSTR
|
||||
rc*: TRECT
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
#
|
||||
# NetBIOS 3.0 interface unit
|
||||
|
||||
# This unit contains the definitions for portable NetBIOS 3.0 support.
|
||||
# This module contains the definitions for portable NetBIOS 3.0 support.
|
||||
|
||||
import # Data structure templates
|
||||
Windows
|
||||
|
|
@ -20,8 +20,8 @@ const
|
|||
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.
|
||||
TNCB* {.final.} = object # 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
|
||||
|
|
@ -42,7 +42,7 @@ type # Network Control Block
|
|||
# completes
|
||||
|
||||
PAdapterStatus* = ptr TAdapterStatus
|
||||
TAdapterStatus* = record
|
||||
TAdapterStatus* {.final.} = object
|
||||
adapter_address*: array[0..5, Char]
|
||||
rev_major*: Char
|
||||
reserved0*: Char
|
||||
|
|
@ -72,7 +72,7 @@ type # Network Control Block
|
|||
name_count*: int16
|
||||
|
||||
PNameBuffer* = ptr TNameBuffer
|
||||
TNameBuffer* = record
|
||||
TNameBuffer* {.final.} = object
|
||||
name*: array[0..NCBNAMSZ - 1, Char]
|
||||
name_num*: Char
|
||||
name_flags*: Char
|
||||
|
|
@ -93,14 +93,14 @@ type # Structure returned to the NCB command NCBSSTAT is SESSION_HEADER followed
|
|||
# asterisk then an array of these structures is returned containing the
|
||||
# status for all names.
|
||||
PSessionHeader* = ptr TSessionHeader
|
||||
TSessionHeader* = record
|
||||
TSessionHeader* {.final.} = object
|
||||
sess_name*: Char
|
||||
num_sess*: Char
|
||||
rcv_dg_outstanding*: Char
|
||||
rcv_any_outstanding*: Char
|
||||
|
||||
PSessionBuffer* = ptr TSessionBuffer
|
||||
TSessionBuffer* = record
|
||||
TSessionBuffer* {.final.} = object
|
||||
lsn*: Char
|
||||
state*: Char
|
||||
local_name*: array[0..NCBNAMSZ - 1, Char]
|
||||
|
|
@ -121,20 +121,20 @@ 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.
|
||||
TLanaEnum* {.final.} = object # 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
|
||||
TFindNameHeader* {.final.} = object
|
||||
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.
|
||||
TFindNameBuffer* {.final.} = object # Structure provided with NCBACTION. The purpose of NCBACTION is to provide
|
||||
# transport specific extensions to netbios.
|
||||
len*: Char
|
||||
access_control*: Char
|
||||
frame_control*: Char
|
||||
|
|
@ -143,7 +143,7 @@ type # Structure returned to the NCB command NCBENUM.
|
|||
routing_info*: array[0..17, Char]
|
||||
|
||||
PActionHeader* = ptr TActionHeader
|
||||
TActionHeader* = record
|
||||
TActionHeader* {.final.} = object
|
||||
transport_id*: int32
|
||||
action_code*: int16
|
||||
reserved*: int16
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ type
|
|||
DWORD_PTR* = ptr DWORD
|
||||
pHICON* = ptr HICON
|
||||
pBool* = ptr BOOL
|
||||
STARTUPINFOW* = record # a guess. Omission should get fixed in Windows.
|
||||
STARTUPINFOW* {.final.} = object # a guess. Omission should get fixed in Windows.
|
||||
cb*: DWORD
|
||||
lpReserved*: LPTSTR
|
||||
lpDesktop*: LPTSTR
|
||||
|
|
@ -122,7 +122,7 @@ proc ExtractIcon*(hInst: HINST, lpszExeFileName: LPCWSTR, nIconIndex: UINT): HIC
|
|||
stdcall, dynlib: "shell32.dll", importc: "ExtractIconW".}
|
||||
# if(WINVER >= 0x0400)
|
||||
type # init with sizeof(DRAGINFO)
|
||||
DRAGINFOA* = record
|
||||
DRAGINFOA* {.final.} = object
|
||||
uSize*: UINT
|
||||
pt*: POINT
|
||||
fNC*: BOOL
|
||||
|
|
@ -131,7 +131,7 @@ type # init with sizeof(DRAGINFO)
|
|||
|
||||
TDRAGINFOA* = DRAGINFOA
|
||||
LPDRAGINFOA* = ptr DRAGINFOA # init with sizeof(DRAGINFO)
|
||||
DRAGINFOW* = record
|
||||
DRAGINFOW* {.final.} = object
|
||||
uSize*: UINT
|
||||
pt*: POINT
|
||||
fNC*: BOOL
|
||||
|
|
@ -178,7 +178,7 @@ const
|
|||
ABE_BOTTOM* = 3
|
||||
|
||||
type
|
||||
AppBarData* = record
|
||||
AppBarData* {.final.} = object
|
||||
cbSize*: DWORD
|
||||
hWnd*: HWND
|
||||
uCallbackMessage*: UINT
|
||||
|
|
@ -286,7 +286,7 @@ type
|
|||
# only used if FOF_SIMPLEPROGRESS
|
||||
|
||||
type
|
||||
SHFILEOPSTRUCTA* = record
|
||||
SHFILEOPSTRUCTA* {.final.} = object
|
||||
hwnd*: HWND
|
||||
wFunc*: UINT
|
||||
pFrom*: LPCSTR
|
||||
|
|
@ -298,7 +298,7 @@ type
|
|||
|
||||
TSHFILEOPSTRUCTA* = SHFILEOPSTRUCTA
|
||||
LPSHFILEOPSTRUCTA* = ptr SHFILEOPSTRUCTA
|
||||
SHFILEOPSTRUCTW* = record
|
||||
SHFILEOPSTRUCTW* {.final.} = object
|
||||
hwnd*: HWND
|
||||
wFunc*: UINT
|
||||
pFrom*: LPCWSTR
|
||||
|
|
@ -332,7 +332,7 @@ proc SHFileOperation*(lpFileOp: LPSHFILEOPSTRUCTW): int32{.stdcall,
|
|||
proc SHFreeNameMappings*(hNameMappings: THandle){.stdcall,
|
||||
dynlib: "shell32.dll", importc: "SHFreeNameMappings".}
|
||||
type
|
||||
SHNAMEMAPPINGA* = record
|
||||
SHNAMEMAPPINGA* {.final.} = object
|
||||
pszOldPath*: LPSTR
|
||||
pszNewPath*: LPSTR
|
||||
cchOldPath*: int32
|
||||
|
|
@ -340,7 +340,7 @@ type
|
|||
|
||||
TSHNAMEMAPPINGA* = SHNAMEMAPPINGA
|
||||
LPSHNAMEMAPPINGA* = ptr SHNAMEMAPPINGA
|
||||
SHNAMEMAPPINGW* = record
|
||||
SHNAMEMAPPINGW* {.final.} = object
|
||||
pszOldPath*: LPWSTR
|
||||
pszNewPath*: LPWSTR
|
||||
cchOldPath*: int32
|
||||
|
|
@ -404,7 +404,7 @@ const
|
|||
# (_WIN32_IE >= 0x560)
|
||||
|
||||
type
|
||||
SHELLEXECUTEINFOA* = record
|
||||
SHELLEXECUTEINFOA* {.final.} = object
|
||||
cbSize*: DWORD
|
||||
fMask*: ULONG
|
||||
hwnd*: HWND
|
||||
|
|
@ -423,7 +423,7 @@ type
|
|||
|
||||
TSHELLEXECUTEINFOA* = SHELLEXECUTEINFOA
|
||||
LPSHELLEXECUTEINFOA* = ptr SHELLEXECUTEINFOA
|
||||
SHELLEXECUTEINFOW* = record
|
||||
SHELLEXECUTEINFOW* {.final.} = object
|
||||
cbSize*: DWORD
|
||||
fMask*: ULONG
|
||||
hwnd*: HWND
|
||||
|
|
@ -474,7 +474,7 @@ proc WinExecError*(HWND: hwnd, error: int32, lpstrFileName: LPCWSTR,
|
|||
lpstrTitle: LPCWSTR){.stdcall, dynlib: "shell32.dll",
|
||||
importc: "WinExecErrorW".}
|
||||
type
|
||||
SHCREATEPROCESSINFOW* = record
|
||||
SHCREATEPROCESSINFOW* {.final.} = object
|
||||
cbSize*: DWORD
|
||||
fMask*: ULONG
|
||||
hwnd*: HWND
|
||||
|
|
@ -502,7 +502,7 @@ proc SHCreateProcessAsUserW*(pscpi: PSHCREATEPROCESSINFOW): Bool{.stdcall,
|
|||
#
|
||||
# struct for query recycle bin info
|
||||
type
|
||||
SHQUERYRBINFO* = record
|
||||
SHQUERYRBINFO* {.final.} = object
|
||||
cbSize*: DWORD
|
||||
i64Size*: int64
|
||||
i64NumItems*: int64
|
||||
|
|
@ -538,7 +538,7 @@ proc SHEmptyRecycleBin*(hwnd: HWND, pszRootPath: LPCWSTR, dwFlags: DWORD): HRESU
|
|||
# Tray notification definitions
|
||||
#
|
||||
type
|
||||
NOTIFYICONDATAA* = record
|
||||
NOTIFYICONDATAA* {.final.} = object
|
||||
cbSize*: DWORD
|
||||
hWnd*: HWND
|
||||
uID*: UINT
|
||||
|
|
@ -556,7 +556,7 @@ type
|
|||
|
||||
TNOTIFYICONDATAA* = NOTIFYICONDATAA
|
||||
PNOTIFYICONDATAA* = ptr NOTIFYICONDATAA
|
||||
NOTIFYICONDATAW* = record
|
||||
NOTIFYICONDATAW* {.final.} = object
|
||||
cbSize*: DWORD
|
||||
hWnd*: HWND
|
||||
uID*: UINT
|
||||
|
|
@ -645,7 +645,7 @@ proc Shell_NotifyIcon*(dwMessage: Dword, lpData: PNOTIFYICONDATAW): Bool{.
|
|||
# out: display name (or path)
|
||||
# out: type name
|
||||
type
|
||||
SHFILEINFOA* = record
|
||||
SHFILEINFOA* {.final.} = object
|
||||
hIcon*: HICON # out: icon
|
||||
iIcon*: int32 # out: icon index
|
||||
dwAttributes*: DWORD # out: SFGAO_ flags
|
||||
|
|
@ -654,7 +654,7 @@ type
|
|||
|
||||
TSHFILEINFOA* = SHFILEINFOA
|
||||
pSHFILEINFOA* = ptr SHFILEINFOA
|
||||
SHFILEINFOW* = record
|
||||
SHFILEINFOW* {.final.} = object
|
||||
hIcon*: HICON # out: icon
|
||||
iIcon*: int32 # out: icon index
|
||||
dwAttributes*: DWORD # out: SFGAO_ flags
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue