threading code deactivated; tiny C bugfix: don't report warnings to error callback

This commit is contained in:
Araq
2010-09-19 21:35:44 +02:00
parent c065694598
commit 93b3c03dbd
15 changed files with 208 additions and 135 deletions

View File

@@ -1,3 +1,4 @@
Comex
Philippe Lhoste
Mario Ray Mahardhika
Dominik Picheta

View File

@@ -1,14 +1,13 @@
#
#
# Nimrod's Runtime Library
# (c) Copyright 2006 Andreas Rumpf
# (c) Copyright 2010 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## Declaration of the Document Object Model for the ECMAScript backend.
## (c) 2008 Andreas Rumpf
when not defined(ecmascript):
{.error: "This module only works on the ECMAScript platform".}

View File

@@ -1605,10 +1605,8 @@ when not defined(EcmaScript) and not defined(NimrodVM):
## can be used to mark a condition to be unlikely. This is a hint for the
## optimizer.
elif defined(ecmaScript):
include "system/ecmasys"
elif defined(NimrodVM):
# Stubs for the GC interface:
elif defined(ecmaScript) or defined(NimrodVM):
# Stubs:
proc GC_disable() = nil
proc GC_enable() = nil
proc GC_fullCollect() = nil
@@ -1620,16 +1618,19 @@ elif defined(NimrodVM):
proc getOccupiedMem(): int = return -1
proc getFreeMem(): int = return -1
proc getTotalMem(): int = return -1
proc cmp(x, y: string): int =
if x == y: return 0
if x < y: return -1
return 1
proc dealloc(p: pointer) = nil
proc alloc(size: int): pointer = nil
proc alloc0(size: int): pointer = nil
proc realloc(p: Pointer, newsize: int): pointer = nil
when defined(ecmaScript):
include "system/ecmasys"
elif defined(NimrodVM):
proc cmp(x, y: string): int =
if x == y: return 0
if x < y: return -1
return 1
{.pop.} # checks
{.pop.} # hints

View File

@@ -1,26 +1,12 @@
#
#
# Nimrod's Runtime Library
# (c) Copyright 2008 Andreas Rumpf
# (c) Copyright 2010 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## Stubs for the GC interface:
proc GC_disable() = nil
proc GC_enable() = nil
proc GC_fullCollect() = nil
proc GC_setStrategy(strategy: TGC_Strategy) = nil
proc GC_enableMarkAndSweep() = nil
proc GC_disableMarkAndSweep() = nil
proc GC_getStatistics(): string = return ""
proc getOccupiedMem(): int = return -1
proc getFreeMem(): int = return -1
proc getTotalMem(): int = return -1
proc alert(s: cstring) {.importc, nodecl.}
type
@@ -130,8 +116,6 @@ proc raiseIndexError() {.compilerproc, noreturn.} =
proc raiseFieldError(f: string) {.compilerproc, noreturn.} =
raise newException(EInvalidField, f & " is not accessible")
proc SetConstr() {.varargs, pure, compilerproc.} =
asm """
var result = {};
@@ -317,61 +301,58 @@ proc ewriteln(x: cstring) =
else:
raise newException(EInvalidValue, "<body> element does not exist yet!")
proc echo*(x: int) = ewriteln($x)
proc echo*(x: float) = ewriteln($x)
proc echo*(x: bool) = ewriteln(if x: cstring("true") else: cstring("false"))
proc echo*(x: string) = ewriteln(x)
proc echo*(x: cstring) = ewriteln(x)
proc echo[Ty](x: Ty) =
echo(x)
proc echo[Ty](x: openArray[Ty]) =
for a in items(x): echo(a)
proc rawEcho {.compilerproc.} =
var node = document.getElementsByTagName("body")[0]
if node == nil: raise newException(EIO, "<body> element does not exist yet!")
asm """
for (var i = 0; i < arguments.length; ++i) {
var x = `toEcmaStr`(arguments[i]);
`node`.appendChild(document.createTextNode(x))
}
"""
node.appendChild(document.createElement("br"))
# Arithmetic:
proc addInt(a, b: int): int {.pure, compilerproc.} =
asm """
var result = `a` + `b`;
if (result > 2147483647 || result < -2147483648) raiseOverflow();
if (result > 2147483647 || result < -2147483648) `raiseOverflow`();
return result;
"""
proc subInt(a, b: int): int {.pure, compilerproc.} =
asm """
var result = `a` - `b`;
if (result > 2147483647 || result < -2147483648) raiseOverflow();
if (result > 2147483647 || result < -2147483648) `raiseOverflow`();
return result;
"""
proc mulInt(a, b: int): int {.pure, compilerproc.} =
asm """
var result = `a` * `b`;
if (result > 2147483647 || result < -2147483648) raiseOverflow();
if (result > 2147483647 || result < -2147483648) `raiseOverflow`();
return result;
"""
proc divInt(a, b: int): int {.pure, compilerproc.} =
asm """
if (`b` == 0) raiseDivByZero();
if (`b` == -1 && `a` == 2147483647) raiseOverflow();
if (`b` == 0) `raiseDivByZero`();
if (`b` == -1 && `a` == 2147483647) `raiseOverflow`();
return Math.floor(`a` / `b`);
"""
proc modInt(a, b: int): int {.pure, compilerproc.} =
asm """
if (`b` == 0) raiseDivByZero();
if (`b` == -1 && `a` == 2147483647) raiseOverflow();
if (`b` == 0) `raiseDivByZero`();
if (`b` == -1 && `a` == 2147483647) `raiseOverflow`();
return Math.floor(`a` % `b`);
"""
proc addInt64(a, b: int): int {.pure, compilerproc.} =
asm """
var result = `a` + `b`;
if (result > 9223372036854775807
|| result < -9223372036854775808) raiseOverflow();
|| result < -9223372036854775808) `raiseOverflow`();
return result;
"""
@@ -379,7 +360,7 @@ proc subInt64(a, b: int): int {.pure, compilerproc.} =
asm """
var result = `a` - `b`;
if (result > 9223372036854775807
|| result < -9223372036854775808) raiseOverflow();
|| result < -9223372036854775808) `raiseOverflow`();
return result;
"""
@@ -387,21 +368,21 @@ proc mulInt64(a, b: int): int {.pure, compilerproc.} =
asm """
var result = `a` * `b`;
if (result > 9223372036854775807
|| result < -9223372036854775808) raiseOverflow();
|| result < -9223372036854775808) `raiseOverflow`();
return result;
"""
proc divInt64(a, b: int): int {.pure, compilerproc.} =
asm """
if (`b` == 0) raiseDivByZero();
if (`b` == -1 && `a` == 9223372036854775807) raiseOverflow();
if (`b` == 0) `raiseDivByZero`();
if (`b` == -1 && `a` == 9223372036854775807) `raiseOverflow`();
return Math.floor(`a` / `b`);
"""
proc modInt64(a, b: int): int {.pure, compilerproc.} =
asm """
if (`b` == 0) raiseDivByZero();
if (`b` == -1 && `a` == 9223372036854775807) raiseOverflow();
if (`b` == 0) `raiseDivByZero`();
if (`b` == -1 && `a` == 9223372036854775807) `raiseOverflow`();
return Math.floor(`a` % `b`);
"""
@@ -415,13 +396,13 @@ proc internalAssert(file: cstring, line: int) {.pure, compilerproc.} =
asm """`e`.message = "[Assertion failure] file: "+`file`+", line: "+`line`"""
raise e
include hti
include "system/hti"
proc isFatPointer(ti: PNimType): bool =
# This has to be consistent with the code generator!
return ti.base.kind notin {tyRecord, tyRecordConstr, tyObject,
return ti.base.kind notin {tyObject,
tyArray, tyArrayConstr, tyPureObject, tyTuple,
tyEmptySet, tyOpenArray, tySet, tyVar, tyRef, tyPtr}
tyOpenArray, tySet, tyVar, tyRef, tyPtr}
proc NimCopy(x: pointer, ti: PNimType): pointer {.compilerproc.}
@@ -452,7 +433,7 @@ proc NimCopy(x: pointer, ti: PNimType): pointer =
`result`[0] = `x`[0];
`result`[1] = `x`[1];
"""
of tyEmptySet, tySet:
of tySet:
asm """
`result` = {};
for (var key in `x`) { `result`[key] = `x`[key]; }

View File

@@ -10,6 +10,10 @@
# Exception handling code. This is difficult because it has
# to work if there is no more memory (but it doesn't yet!).
var
stackTraceNewLine* = "\n" ## undocumented feature; it is replaced by ``<br>``
## for CGI applications
when not defined(windows) or not defined(guiapp):
proc writeToStdErr(msg: CString) = write(stdout, msg)
@@ -32,7 +36,7 @@ type
TSafePoint {.compilerproc, final.} = object
prev: PSafePoint # points to next safe point ON THE STACK
status: int
exc: ref E_Base # XXX only needed for bootstrapping
exc: ref E_Base # XXX only needed for bootstrapping; unused
context: C_JmpBuf
var
@@ -55,6 +59,58 @@ proc pushCurrentException(e: ref E_Base) {.compilerRtl, inl.} =
proc popCurrentException {.compilerRtl, inl.} =
currException = currException.parent
# some platforms have native support for stack traces:
const
nimrodStackTrace = compileOption("stacktrace")
nativeStackTrace = (defined(macosx) or defined(linux)) and
not nimrodStackTrace and false
# `nativeStackTrace` does not work for me --> deactivated for now. Maybe for
# the next release version.
when nativeStacktrace:
type
TDl_info {.importc: "Dl_info", header: "<dlfcn.h>",
final, pure.} = object
dli_fname: CString
dli_fbase: pointer
dli_sname: CString
dli_saddr: pointer
proc backtrace(symbols: ptr pointer, size: int): int {.
importc: "backtrace", header: "<execinfo.h>".}
proc dladdr(addr1: pointer, info: ptr TDl_info): int {.
importc: "dladdr", header: "<dlfcn.h>".}
var
tempAddresses: array [0..127, pointer] # cannot be allocated on the stack!
tempDlInfo: TDl_info
proc auxWriteStackTraceWithBacktrace(s: var string) =
# This is allowed to be expensive since it only happens during crashes
# (but this way you don't need manual stack tracing)
var size = backtrace(cast[ptr pointer](addr(tempAddresses)),
len(tempAddresses))
var enabled = false
for i in 0..size-1:
var dlresult = dladdr(tempAddresses[i], addr(tempDlInfo))
if enabled:
if dlresult != 0:
var oldLen = s.len
add(s, tempDlInfo.dli_fname)
if tempDlInfo.dli_sname != nil:
for k in 1..max(1, 25-(s.len-oldLen)): add(s, ' ')
add(s, tempDlInfo.dli_sname)
else:
add(s, '?')
add(s, stackTraceNewLine)
else:
if dlresult != 0 and tempDlInfo.dli_sname != nil and
c_strcmp(tempDlInfo.dli_sname, "signalHandler") == 0'i32:
# Once we're past signalHandler, we're at what the user is
# interested in
enabled = true
type
PFrame = ptr TFrame
TFrame {.importc, nodecl, final.} = object
@@ -74,9 +130,6 @@ var
tempFrames: array [0..127, PFrame] # cannot be allocated on the stack!
stackTraceNewLine* = "\n" ## undocumented feature; it is replaced by ``<br>``
## for CGI applications
proc auxWriteStackTrace(f: PFrame, s: var string) =
const
firstCalls = 32
@@ -120,7 +173,7 @@ proc auxWriteStackTrace(f: PFrame, s: var string) =
add(s, stackTraceNewLine)
proc rawWriteStackTrace(s: var string) =
when compileOption("stacktrace") or compileOption("linetrace"):
when nimrodStackTrace:
if framePtr == nil:
add(s, "No stack traceback available")
add(s, stackTraceNewLine)
@@ -128,6 +181,10 @@ proc rawWriteStackTrace(s: var string) =
add(s, "Traceback (most recent call last)")
add(s, stackTraceNewLine)
auxWriteStackTrace(framePtr, s)
elif nativeStackTrace:
add(s, "Traceback from system (most recent call last)")
add(s, stackTraceNewLine)
auxWriteStackTraceWithBacktrace(s)
else:
add(s, "No stack traceback available")
add(s, stackTraceNewLine)
@@ -197,11 +254,6 @@ proc WriteStackTrace() =
rawWriteStackTrace(s)
writeToStdErr(s)
#proc stackTraceWrapper {.noconv.} =
# writeStackTrace()
#addQuitProc(stackTraceWrapper)
var
dbgAborting: bool # whether the debugger wants to abort

View File

@@ -77,14 +77,16 @@ var
# collection, not a lock for threads!
proc lock(gch: var TGcHeap) {.inline.} =
if isMultiThreaded:
Lock(gch.zctLock)
lock(gch.cycleRootsLock)
when hasThreadSupport:
if isMultiThreaded:
Lock(gch.zctLock)
lock(gch.cycleRootsLock)
proc unlock(gch: var TGcHeap) {.inline.} =
if isMultiThreaded:
unlock(gch.zctLock)
unlock(gch.cycleRootsLock)
when hasThreadSupport:
if isMultiThreaded:
unlock(gch.zctLock)
unlock(gch.cycleRootsLock)
proc addZCT(s: var TCellSeq, c: PCell) {.noinline.} =
if (c.refcount and rcZct) == 0:
@@ -202,15 +204,19 @@ proc prepareDealloc(cell: PCell) =
proc rtlAddCycleRoot(c: PCell) {.rtl, inl.} =
# we MUST access gch as a global here, because this crosses DLL boundaries!
if isMultiThreaded: Lock(gch.cycleRootsLock)
when hasThreadSupport:
if isMultiThreaded: Lock(gch.cycleRootsLock)
incl(gch.cycleRoots, c)
if isMultiThreaded: Unlock(gch.cycleRootsLock)
when hasThreadSupport:
if isMultiThreaded: Unlock(gch.cycleRootsLock)
proc rtlAddZCT(c: PCell) {.rtl, inl.} =
# we MUST access gch as a global here, because this crosses DLL boundaries!
if isMultiThreaded: Lock(gch.zctLock)
when hasThreadSupport:
if isMultiThreaded: Lock(gch.zctLock)
addZCT(gch.zct, c)
if isMultiThreaded: Unlock(gch.zctLock)
when hasThreadSupport:
if isMultiThreaded: Unlock(gch.zctLock)
proc decRef(c: PCell) {.inline.} =
when stressGC:
@@ -480,7 +486,7 @@ proc gcMark(p: pointer) {.inline.} =
add(gch.decStack, cell)
proc markThreadStacks(gch: var TGcHeap) =
when isMultiThreaded:
when hasThreadSupport:
nil
# ----------------- stack management --------------------------------------

View File

@@ -7,12 +7,17 @@
# distribution, for details about the copyright.
#
when defined(gcc) or defined(llvm_gcc):
const
hasThreadSupport = false # deactivate for now: thread stack walking
# is missing!
maxThreads = 256
when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport:
proc sync_add_and_fetch(p: var int, val: int): int {.
importc: "__sync_add_and_fetch", nodecl.}
proc sync_sub_and_fetch(p: var int, val: int): int {.
importc: "__sync_sub_and_fetch", nodecl.}
elif defined(vcc):
elif defined(vcc) and hasThreadSupport:
proc sync_add_and_fetch(p: var int, val: int): int {.
importc: "NimXadd", nodecl.}
else:
@@ -20,19 +25,18 @@ else:
inc(p, val)
result = p
const
isMultiThreaded* = true
maxThreads = 256
var
isMultiThreaded: bool # true when prog created at least 1 thread
proc atomicInc(memLoc: var int, x: int): int =
when isMultiThreaded:
when hasThreadSupport:
result = sync_add_and_fetch(memLoc, x)
else:
inc(memLoc, x)
result = memLoc
proc atomicDec(memLoc: var int, x: int): int =
when isMultiThreaded:
when hasThreadSupport:
when defined(sync_sub_and_fetch):
result = sync_sub_and_fetch(memLoc, x)
else:
@@ -85,11 +89,8 @@ type
TThreadFunc* = proc (closure: pointer) {.cdecl.}
proc createThread*(t: var TThread, fn: TThreadFunc) =
nil
proc destroyThread*(t: var TThread) =
nil

View File

@@ -12,9 +12,9 @@
# code!**
import
ast, astalgo, strutils, nhashes, trees, platform, magicsys, extccomp, options,
nversion, nimsets, msgs, crc, bitsets, idents, lists, types, os, times, ropes,
math, passes, ccgutils, wordrecg, rnimsyn, rodread
ast, astalgo, strutils, nhashes, trees, platform, magicsys, extccomp,
options, nversion, nimsets, msgs, crc, bitsets, idents, lists, types, os,
times, ropes, math, passes, ccgutils, wordrecg, rnimsyn, rodread
proc ecmasgenPass*(): TPass
# implementation
@@ -39,7 +39,8 @@ type
kind*: TEcmasTypeKind
com*: PRope # computation part
# address if this is a (address, index)-tuple
res*: PRope # result part; index if this is a (address, index)-tuple
res*: PRope # result part; index if this is an
# (address, index)-tuple
TBlock{.final.} = object
id*: int # the ID of the label; positive means that it
@@ -886,12 +887,11 @@ proc genDeref(p: var TProc, n: PNode, r: var TCompRes) =
if a.kind != etyBaseIndex: InternalError(n.info, "genDeref")
r.res = ropef("$1[$2]", [a.com, a.res])
proc genCall(p: var TProc, n: PNode, r: var TCompRes) =
var a: TCompRes
gen(p, n.sons[0], r)
proc genArgs(p: var TProc, n: PNode, r: var TCompRes) =
app(r.res, "(")
for i in countup(1, sonsLen(n) - 1):
if i > 1: app(r.res, ", ")
var a: TCompRes
gen(p, n.sons[i], a)
if a.kind == etyBaseIndex:
app(r.res, a.com)
@@ -901,6 +901,14 @@ proc genCall(p: var TProc, n: PNode, r: var TCompRes) =
app(r.res, mergeExpr(a))
app(r.res, ")")
proc genCall(p: var TProc, n: PNode, r: var TCompRes) =
gen(p, n.sons[0], r)
genArgs(p, n, r)
proc genEcho(p: var TProc, n: PNode, r: var TCompRes) =
app(r.res, "rawEcho")
genArgs(p, n, r)
proc putToSeq(s: string, indirect: bool): PRope =
result = toRope(s)
if indirect: result = ropef("[$1]", [result])
@@ -1124,6 +1132,8 @@ proc genMagic(p: var TProc, n: PNode, r: var TCompRes) =
of mInSet: binaryExpr(p, n, r, "", "($1[$2] != undefined)")
of mNLen..mNError:
liMessage(n.info, errCannotGenerateCodeForX, n.sons[0].sym.name.s)
of mNewSeq: binaryStmt(p, n, r, "", "$1 = new Array($2)")
of mEcho: genEcho(p, n, r)
else:
genCall(p, n, r)
#else internalError(e.info, 'genMagic: ' + magicToStr[op]);
@@ -1389,7 +1399,7 @@ proc newModule(module: PSym, filename: string): BModule =
proc genHeader(): PRope =
result = ropef("/* Generated by the Nimrod Compiler v$1 */$n" &
"/* (c) 2008 Andreas Rumpf */$n$n" & "$nvar Globals = this;$n" &
"/* (c) 2010 Andreas Rumpf */$n$n" & "$nvar Globals = this;$n" &
"var framePtr = null;$n" & "var excHandler = null;$n",
[toRope(versionAsString)])

View File

@@ -203,7 +203,7 @@ proc MainCommand(cmd, filename: string) =
gCmd = cmdCompileToCpp
wantFile(filename)
CommandCompileToC(filename)
of wCompileToEcmaScript:
of wCompileToEcmaScript, wJs:
gCmd = cmdCompileToEcmaScript
wantFile(filename)
CommandCompileToEcmaScript(filename)

View File

@@ -55,7 +55,7 @@ type
wCc, wGenscript, wCheckPoint, wCheckPoints, wNoMain, wSubsChar,
wAcyclic, wIndex,
wCompileToC, wCompileToCpp, wCompileToEcmaScript, wCompileToLLVM, wPretty,
wDoc, wGenDepend, wListDef, wCheck, wParse, wScan, wLazy,
wDoc, wGenDepend, wListDef, wCheck, wParse, wScan, wJs,
wRst2html, wRst2tex, wI,
wWrite, wPutEnv, wPrependEnv, wAppendEnv, wThreadVar
@@ -103,7 +103,7 @@ const
"nomain", "subschar", "acyclic", "index",
"compiletoc", "compiletocpp", "compiletoecmascript", "compiletollvm",
"pretty", "doc", "gendepend", "listdef", "check", "parse", "scan",
"lazy", "rst2html", "rst2tex", "i",
"js", "rst2html", "rst2tex", "i",
"write", "putenv", "prependenv", "appendenv", "threadvar"]
proc whichKeyword*(id: PIdent): TSpecialWord

View File

@@ -2,18 +2,18 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<!-- This has been written by hand. (c) 2008 Andreas Rumpf -->
<!-- This has been written by hand. (c) 2010 Andreas Rumpf -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Nimrod ECMAScript Generator Test</title>
<style type="text/css">
span.DecNumber {color: blue}
</style>
<script src="nimrcache/ecmas.js" type="text/javascript"></script>
<script src="nimcache/ecmas.js" type="text/javascript"></script>
</head>
<body onload="OnLoad()">
<form name="form1" action="ecmas.html">
<input type="text" name="input" size="3" />
<input type="text" name="input1" size="10" />
<input type="button" value="Calculate square" onclick="OnButtonClick()" />
</form>

View File

@@ -6,11 +6,14 @@ import
# We need to declare the used elements here. This is annoying but
# prevents any kind of typo:
var
inputElement {.importc: "document.form1.input", nodecl.}: ref TElement
inputElement {.importc: "document.form1.input1", nodecl.}: ref TElement
proc OnButtonClick() {.exportc.} =
var x: int = parseInt($inputElement.value)
echo($(x * x))
#var x = parseInt($inputElement.value)
#echo($(x * x))
var input = $inputElement.value
echo "Test"
echo "Hi, ", input
proc OnLoad() {.exportc.} =
echo("Welcome! Please take your time to fill in this formular!")
echo "Welcome! Please take your time to fill in this formular!"

View File

@@ -808,11 +808,11 @@ void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
if (!s1->error_func) {
/* default case: stderr */
fprintf(stderr, "%s\n", buf);
} else {
}
if (!is_warning || s1->warn_error) {
s1->error_func(s1->error_opaque, buf);
}
if (!is_warning || s1->warn_error)
s1->nb_errors++;
}
}
void tcc_set_error_func(TCCState *s, void *error_opaque,

View File

@@ -3,6 +3,8 @@ For version 0.8.10
- fix implicit generic routines
- bugfix: ccgexprs
- bugfix: make ``finally`` more robust
- bugfix: tiny C broken again!
High priority (version 0.9.0)

View File

@@ -7,17 +7,38 @@
# distribution, for details about the copyright.
#
import glib2, gtk2, gdk2, osproc, dialogs, strutils
import glib2, gtk2, gdk2, os, osproc, dialogs, strutils
when defined(tinyc):
const runCmd = "run"
else:
const runCmd = "c -r"
when not defined(findExe):
# candidate for the stdlib:
proc findExe(exe: string): string =
## returns exe if the exe cannot be found
result = addFileExt(exe, os.exeExt)
if ExistsFile(result): return
var path = os.getEnv("PATH")
for candidate in split(path, pathSep):
var x = candidate / result
if ExistsFile(x): return x
result = ""
var nimExe = findExe("nimrod")
if nimExe.len == 0: nimExe = "../bin" / addFileExt("nimrod", os.exeExt)
proc execCode(code: string): string =
var f: TFile
if open(f, "temp.nim", fmWrite):
f.write(code)
f.close()
result = osproc.execProcess(
"$# $# --verbosity:0 --hint[Conf]:off temp.nim" % [nimExe, runCmd],
{poStdErrToStdOut})
else:
raise newException(EIO, "Unable to open file")
result = osproc.execProcess(
"nimrod c -r --verbosity:0 --hint[Conf]:off temp.nim")
result = "cannot open file 'temp.nim'"
var shiftPressed = False
var w: gtk2.PWindow
@@ -29,33 +50,29 @@ proc destroy(widget: PWidget, data: pgpointer){.cdecl.} =
proc FileOpenClicked(menuitem: PMenuItem, userdata: pgpointer) {.cdecl.} =
var path = ChooseFileToOpen(w)
if path != "":
var file: string = readFile(path)
if file != nil:
set_text(InputTextBuffer, file, len(file))
else:
error(w, "Unable to read from file")
proc FileSaveClicked(menuitem: PMenuItem, userdata: pgpointer) {.cdecl.} =
var path = ChooseFileToSave(w)
if path != "":
var startIter: TTextIter
var endIter: TTextIter
get_start_iter(InputTextBuffer, addr(startIter))
get_end_iter(InputTextBuffer, addr(endIter))
var InputText = get_text(InputTextBuffer, addr(startIter),
addr(endIter), False)
var f: TFile
if open(f, path, fmWrite):
f.write(InputText)
f.close()
else:
error(w, "Unable to write to file")
if path == "": return
var startIter: TTextIter
var endIter: TTextIter
get_start_iter(InputTextBuffer, addr(startIter))
get_end_iter(InputTextBuffer, addr(endIter))
var InputText = get_text(InputTextBuffer, addr(startIter),
addr(endIter), False)
var f: TFile
if open(f, path, fmWrite):
f.write(InputText)
f.close()
else:
error(w, "Unable to write to file")
proc inputKeyPressed(widget: PWidget, event: PEventKey,
userdata: pgpointer): bool =
@@ -68,13 +85,13 @@ proc setError(msg: string) =
proc inputKeyReleased(widget: PWidget, event: PEventKey,
userdata: pgpointer): bool =
echo(keyval_name(event.keyval))
#echo(keyval_name(event.keyval))
if ($keyval_name(event.keyval)).tolower() == "shift_l":
# SHIFT is released
shiftPressed = False
if ($keyval_name(event.keyval)).tolower() == "return":
echo($keyval_name(event.keyval), "Shift_L")
#echo($keyval_name(event.keyval), "Shift_L")
# Enter pressed
if shiftPressed == False:
var startIter: TTextIter