summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2014-10-04 19:40:23 +0200
committerAraq <rumpf_a@web.de>2014-10-04 19:40:23 +0200
commitfc47c0edc76d1d8460fa0d1b384b97b7f2c92934 (patch)
tree395d3a61a2f5ee97491dd06e432ccf412f89fdb5
parent4616a1e006f0b909d204d8e8f1ad3cd43d8db556 (diff)
parentc17c8e9afa6ba6a1000fe82b1c8a7af10e3fc698 (diff)
downloadNim-fc47c0edc76d1d8460fa0d1b384b97b7f2c92934.tar.gz
Merge branch 'devel' of https://github.com/Araq/Nimrod into bigbreak
Conflicts:
	lib/impure/db_postgres.nim
	lib/pure/os.nim
	lib/wrappers/postgres.nim
-rw-r--r--compiler/ccgstmts.nim13
-rw-r--r--compiler/cgen.nim2
-rw-r--r--compiler/commands.nim4
-rw-r--r--compiler/condsyms.nim4
-rw-r--r--compiler/nversion.nim2
-rw-r--r--compiler/procfind.nim11
-rw-r--r--lib/impure/db_postgres.nim112
-rw-r--r--lib/pure/os.nim4
-rw-r--r--lib/system/ansi_c.nim21
-rw-r--r--lib/wrappers/postgres.nim6
10 files changed, 135 insertions, 44 deletions
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim
index 92af9b18e..1545da81b 100644
--- a/compiler/ccgstmts.nim
+++ b/compiler/ccgstmts.nim
@@ -170,6 +170,10 @@ proc genSingleVar(p: BProc, a: PNode) =
   if sfCompileTime in v.flags: return
   var targetProc = p
   if sfGlobal in v.flags:
+    if v.flags * {sfImportc, sfExportc} == {sfImportc} and
+        a.sons[2].kind == nkEmpty and
+        v.loc.flags * {lfHeader, lfNoDecl} != {}:
+      return
     if sfPure in v.flags:
       # v.owner.kind != skModule:
       targetProc = p.module.preInitProc
@@ -834,7 +838,14 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
     discard cgsym(p.module, "E_Base")
   linefmt(p, cpsLocals, "#TSafePoint $1;$n", safePoint)
   linefmt(p, cpsStmts, "#pushSafePoint(&$1);$n", safePoint)
-  linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", safePoint)
+  if isDefined("nimStdSetjmp"):
+    linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", safePoint)
+  elif isDefined("nimSigSetjmp"):
+    linefmt(p, cpsStmts, "$1.status = sigsetjmp($1.context, 0);$n", safePoint)
+  elif isDefined("nimRawSetjmp"):
+    linefmt(p, cpsStmts, "$1.status = _setjmp($1.context);$n", safePoint)
+  else:
+    linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", safePoint)
   startBlock(p, "if ($1.status == 0) {$n", [safePoint])
   var length = sonsLen(t)
   add(p.nestedTryStmts, t)
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index 44d4d18e1..afeac8c88 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -13,7 +13,7 @@ import
   ast, astalgo, strutils, hashes, trees, platform, magicsys, extccomp,
   options, intsets,
   nversion, nimsets, msgs, crc, bitsets, idents, lists, types, ccgutils, os,
-  times, ropes, math, passes, rodread, wordrecg, treetab, cgmeth,
+  times, ropes, math, passes, rodread, wordrecg, treetab, cgmeth, condsyms,
   rodutils, renderer, idgen, cgendata, ccgmerge, semfold, aliases, lowerings,
   semparallel
 
diff --git a/compiler/commands.nim b/compiler/commands.nim
index 596cdafba..f8f6a9a33 100644
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -80,9 +80,9 @@ proc writeVersionInfo(pass: TCmdLinePass) =
                                  platform.OS[platform.hostOS].name, 
                                  CPU[platform.hostCPU].name]))
 
-    const gitHash = gorge("git log -n 1 --format=%H")
+    discard """const gitHash = gorge("git log -n 1 --format=%H")
     if gitHash.strip.len == 40:
-      msgWriteln("git hash: " & gitHash)
+      msgWriteln("git hash: " & gitHash)"""
 
     msgWriteln("active boot switches:" & usedRelease & usedAvoidTimeMachine &
       usedTinyC & usedGnuReadline & usedNativeStacktrace & usedNoCaas &
diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim
index d87275063..137ec409f 100644
--- a/compiler/condsyms.nim
+++ b/compiler/condsyms.nim
@@ -137,3 +137,7 @@ proc initDefines*() =
   declareSymbol("emulatedthreadvars")
   if platform.OS[targetOS].props.contains(ospLacksThreadVars):
     defineSymbol("emulatedthreadvars")
+  case targetOS
+  of osSolaris, osNetbsd, osFreebsd, osOpenbsd, osMacosx:
+    defineSymbol("nimRawSetjmp")
+  else: discard
diff --git a/compiler/nversion.nim b/compiler/nversion.nim
index 7f0f93782..968feb081 100644
--- a/compiler/nversion.nim
+++ b/compiler/nversion.nim
@@ -14,7 +14,7 @@ const
   MaxSetElements* = 1 shl 16  # (2^16) to support unicode character sets?
   VersionMajor* = 0
   VersionMinor* = 9
-  VersionPatch* = 5
+  VersionPatch* = 6
   VersionAsString* = $VersionMajor & "." & $VersionMinor & "." & $VersionPatch
 
   RodFileVersion* = "1215"       # modify this if the rod-format changes!
diff --git a/compiler/procfind.nim b/compiler/procfind.nim
index e88524634..46d6c9929 100644
--- a/compiler/procfind.nim
+++ b/compiler/procfind.nim
@@ -70,8 +70,15 @@ proc searchForProcNew(c: PContext, scope: PScope, fn: PSym): PSym =
   var it: TIdentIter
   result = initIdentIter(it, scope.symbols, fn.name)
   while result != nil:
-    if result.kind in skProcKinds and
-       sameType(result.typ, fn.typ, flags): return
+    if result.kind in skProcKinds and sameType(result.typ, fn.typ, flags):
+      case equalParams(result.typ.n, fn.typ.n)
+      of paramsEqual:
+        return
+      of paramsIncompatible:
+        localError(fn.info, errNotOverloadable, fn.name.s)
+        return
+      of paramsNotEqual:
+        discard
 
     result = nextIdentIter(it, scope.symbols)
   
diff --git a/lib/impure/db_postgres.nim b/lib/impure/db_postgres.nim
index 6ea2bdbee..4080cd61f 100644
--- a/lib/impure/db_postgres.nim
+++ b/lib/impure/db_postgres.nim
@@ -1,7 +1,7 @@
 #
 #
 #            Nim's Runtime Library
-#        (c) Copyright 2012 Andreas Rumpf
+#        (c) Copyright 2014 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -19,6 +19,7 @@ type
   EDb* = object of IOError ## exception that is raised if a database error occurs
   
   TSqlQuery* = distinct string ## an SQL query string
+  TSqlPrepared* = distinct string ## a identifier for the prepared queries
 
   FDb* = object of IOEffect ## effect that denotes a database operation
   FReadDb* = object of FDb   ## effect that denotes a read operation
@@ -33,14 +34,14 @@ proc sql*(query: string): TSqlQuery {.noSideEffect, inline.} =
   ## on, later versions will check the string for valid syntax.
   result = TSqlQuery(query)
  
-proc dbError(db: TDbConn) {.noreturn.} = 
+proc dbError*(db: TDbConn) {.noreturn.} =
   ## raises an EDb exception.
   var e: ref EDb
   new(e)
   e.msg = $pqErrorMessage(db)
   raise e
 
-proc dbError*(msg: string) {.noreturn.} = 
+proc dbError*(msg: string) {.noreturn.} =
   ## raises an EDb exception with message `msg`.
   var e: ref EDb
   new(e)
@@ -61,41 +62,70 @@ proc dbFormat(formatstr: TSqlQuery, args: varargs[string]): string =
     if c == '?':
       add(result, dbQuote(args[a]))
       inc(a)
-    else: 
+    else:
       add(result, c)
   
-proc tryExec*(db: TDbConn, query: TSqlQuery, 
+proc tryExec*(db: TDbConn, query: TSqlQuery,
               args: varargs[string, `$`]): bool {.tags: [FReadDB, FWriteDb].} =
   ## tries to execute the query and returns true if successful, false otherwise.
-  var q = dbFormat(query, args)
-  var res = pqExec(db, q)
+  var arr = allocCStringArray(args)
+  var res = pqexecParams(db, query.string, int32(args.len), nil, arr,
+                        nil, nil, 0)
+  deallocCStringArray(arr)
   result = pqresultStatus(res) == PGRES_COMMAND_OK
   pqclear(res)
 
 proc exec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]) {.
   tags: [FReadDB, FWriteDb].} =
   ## executes the query and raises EDB if not successful.
-  var q = dbFormat(query, args)
-  var res = pqExec(db, q)
+  var arr = allocCStringArray(args)
+  var res = pqexecParams(db, query.string, int32(args.len), nil, arr,
+                        nil, nil, 0)
+  deallocCStringArray(arr)
   if pqresultStatus(res) != PGRES_COMMAND_OK: dbError(db)
   pqclear(res)
-  
+
+proc exec*(db: TDbConn, stmtName: TSqlPrepared,
+          args: varargs[string]) {.tags: [FReadDB, FWriteDb].} =
+  var arr = allocCStringArray(args)
+  var res = pqexecPrepared(db, stmtName.string, int32(args.len), arr,
+                           nil, nil, 0)
+  deallocCStringArray(arr)
+  if pqResultStatus(res) != PGRES_COMMAND_OK: dbError(db)
+  pqclear(res)
+
 proc newRow(L: int): TRow =
   newSeq(result, L)
   for i in 0..L-1: result[i] = ""
   
-proc setupQuery(db: TDbConn, query: TSqlQuery, 
-                args: varargs[string]): PPGresult = 
-  var q = dbFormat(query, args)
-  result = pqExec(db, q)
-  if pqresultStatus(result) != PGRES_TUPLES_OK: dbError(db)
-  
+proc setupQuery(db: TDbConn, query: TSqlQuery,
+                args: varargs[string]): PPGresult =
+  var arr = allocCStringArray(args)
+  result = pqexecParams(db, query.string, int32(args.len), nil, arr,
+                        nil, nil, 0)
+  deallocCStringArray(arr)
+  if pqResultStatus(result) != PGRES_TUPLES_OK: dbError(db)
+
+proc setupQuery(db: TDbConn, stmtName: TSqlPrepared,
+                 args: varargs[string]): PPGresult =
+  var arr = allocCStringArray(args)
+  result = pqexecPrepared(db, stmtName.string, int32(args.len), arr,
+                          nil, nil, 0)
+  deallocCStringArray(arr)
+  if pqResultStatus(result) != PGRES_TUPLES_OK: dbError(db)
+
+proc prepare*(db: TDbConn; stmtName: string, query: TSqlQuery;
+              nParams: int): TSqlPrepared =
+  var res = pqprepare(db, stmtName, query.string, int32(nParams), nil)
+  if pqResultStatus(res) != PGRES_COMMAND_OK: dbError(db)
+  return TSqlPrepared(stmtName)
+   
 proc setRow(res: PPGresult, r: var TRow, line, cols: int32) =
   for col in 0..cols-1:
     setLen(r[col], 0)
     var x = pqgetvalue(res, line, col)
     add(r[col], x)
-  
+
 iterator fastRows*(db: TDbConn, query: TSqlQuery,
                    args: varargs[string, `$`]): TRow {.tags: [FReadDB].} =
   ## executes the query and iterates over the result dataset. This is very 
@@ -109,6 +139,17 @@ iterator fastRows*(db: TDbConn, query: TSqlQuery,
     yield result
   pqclear(res)
 
+iterator fastRows*(db: TDbConn, stmtName: TSqlPrepared,
+                   args: varargs[string, `$`]): TRow {.tags: [FReadDB].} =
+  ## executes the prepared query and iterates over the result dataset.
+  var res = setupQuery(db, stmtName, args)
+  var L = PQnfields(res)
+  var result = newRow(L)
+  for i in 0..PQntuples(res)-1:
+    setRow(res, result, i, L)
+    yield result
+  PQclear(res)
+
 proc getRow*(db: TDbConn, query: TSqlQuery,
              args: varargs[string, `$`]): TRow {.tags: [FReadDB].} =
   ## retrieves a single row. If the query doesn't return any rows, this proc
@@ -119,27 +160,42 @@ proc getRow*(db: TDbConn, query: TSqlQuery,
   setRow(res, result, 0, L)
   pqclear(res)
 
-proc getAllRows*(db: TDbConn, query: TSqlQuery, 
+proc getRow*(db: TDbConn, stmtName: TSqlPrepared,
+             args: varargs[string, `$`]): TRow {.tags: [FReadDB].} =
+  var res = setupQuery(db, stmtName, args)
+  var L = PQnfields(res)
+  result = newRow(L)
+  setRow(res, result, 0, L)
+  PQclear(res)
+
+proc getAllRows*(db: TDbConn, query: TSqlQuery,
                  args: varargs[string, `$`]): seq[TRow] {.tags: [FReadDB].} =
   ## executes the query and returns the whole result dataset.
   result = @[]
   for r in fastRows(db, query, args):
     result.add(r)
 
-iterator rows*(db: TDbConn, query: TSqlQuery, 
+proc getAllRows*(db: TDbConn, stmtName: TSqlPrepared,
+                 args: varargs[string, `$`]): seq[TRow] {.tags: [FReadDB].} =
+  ## executes the prepared query and returns the whole result dataset.
+  result = @[]
+  for r in FastRows(db, stmtName, args):
+    result.add(r)
+
+iterator rows*(db: TDbConn, query: TSqlQuery,
                args: varargs[string, `$`]): TRow {.tags: [FReadDB].} =
   ## same as `fastRows`, but slower and safe.
   for r in items(getAllRows(db, query, args)): yield r
 
-proc getValue*(db: TDbConn, query: TSqlQuery, 
-               args: varargs[string, `$`]): string {.tags: [FReadDB].} = 
+proc getValue*(db: TDbConn, query: TSqlQuery,
+               args: varargs[string, `$`]): string {.tags: [FReadDB].} =
   ## executes the query and returns the first column of the first row of the
   ## result dataset. Returns "" if the dataset contains no rows or the database
   ## value is NULL.
   var x = pqgetvalue(setupQuery(db, query, args), 0, 0)
   result = if isNil(x): "" else: $x
   
-proc tryInsertID*(db: TDbConn, query: TSqlQuery, 
+proc tryInsertID*(db: TDbConn, query: TSqlQuery,
                   args: varargs[string, `$`]): int64  {.tags: [FWriteDb].}=
   ## executes the query (typically "INSERT") and returns the 
   ## generated ID for the row or -1 in case of an error. For Postgre this adds
@@ -152,7 +208,7 @@ proc tryInsertID*(db: TDbConn, query: TSqlQuery,
   else:
     result = -1
 
-proc insertID*(db: TDbConn, query: TSqlQuery, 
+proc insertID*(db: TDbConn, query: TSqlQuery,
                args: varargs[string, `$`]): int64 {.tags: [FWriteDb].} =
   ## executes the query (typically "INSERT") and returns the 
   ## generated ID for the row. For Postgre this adds
@@ -161,9 +217,9 @@ proc insertID*(db: TDbConn, query: TSqlQuery,
   result = tryInsertID(db, query, args)
   if result < 0: dbError(db)
   
-proc execAffectedRows*(db: TDbConn, query: TSqlQuery, 
+proc execAffectedRows*(db: TDbConn, query: TSqlQuery,
                        args: varargs[string, `$`]): int64 {.tags: [
-                       FReadDB, FWriteDb].} = 
+                       FReadDB, FWriteDb].} =
   ## executes the query (typically "UPDATE") and returns the
   ## number of affected rows.
   var q = dbFormat(query, args)
@@ -172,7 +228,7 @@ proc execAffectedRows*(db: TDbConn, query: TSqlQuery,
   result = parseBiggestInt($pqcmdTuples(res))
   pqclear(res)
 
-proc close*(db: TDbConn) {.tags: [FDb].} = 
+proc close*(db: TDbConn) {.tags: [FDb].} =
   ## closes the database connection.
   if db != nil: pqfinish(db)
 
@@ -188,7 +244,7 @@ proc open*(connection, user, password, database: string): TDbConn {.
   ##
   ## .. code-block:: nim
   ##
-  ##      con = Open("", "", "", "host=localhost port=5432 dbname=mydb")
+  ##      con = open("", "", "", "host=localhost port=5432 dbname=mydb")
   ##
   ## See http://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING
   ## for more information.
@@ -197,5 +253,3 @@ proc open*(connection, user, password, database: string): TDbConn {.
   ## the nim db api.
   result = pqsetdbLogin(nil, nil, nil, nil, database, user, password)
   if pqStatus(result) != CONNECTION_OK: dbError(result) # result = nil
-
-
diff --git a/lib/pure/os.nim b/lib/pure/os.nim
index c08297b7c..3a6930654 100644
--- a/lib/pure/os.nim
+++ b/lib/pure/os.nim
@@ -1341,10 +1341,10 @@ proc removeDir*(dir: string) {.rtl, extern: "nos$1", tags: [
 
 proc rawCreateDir(dir: string) =
   when defined(solaris):
-    if mkdir(dir, 0o711) != 0'i32 and errno != EEXIST and errno != ENOSYS:
+    if mkdir(dir, 0o777) != 0'i32 and errno != EEXIST and errno != ENOSYS:
       raiseOSError(osLastError())
   elif defined(unix):
-    if mkdir(dir, 0o711) != 0'i32 and errno != EEXIST:
+    if mkdir(dir, 0o777) != 0'i32 and errno != EEXIST:
       raiseOSError(osLastError())
   else:
     when useWinUnicode:
diff --git a/lib/system/ansi_c.nim b/lib/system/ansi_c.nim
index 121cd207d..6bc44719f 100644
--- a/lib/system/ansi_c.nim
+++ b/lib/system/ansi_c.nim
@@ -78,10 +78,23 @@ when defined(macosx):
 else:
   template SIGBUS: expr = SIGSEGV
 
-proc c_longjmp(jmpb: C_JmpBuf, retval: cint) {.
-  header: "<setjmp.h>", importc: "longjmp".}
-proc c_setjmp(jmpb: C_JmpBuf): cint {.
-  header: "<setjmp.h>", importc: "setjmp".}
+when defined(nimSigSetjmp) and not defined(nimStdSetjmp):
+  proc c_longjmp(jmpb: C_JmpBuf, retval: cint) {.
+    header: "<setjmp.h>", importc: "siglongjmp".}
+  template c_setjmp(jmpb: C_JmpBuf): cint =
+    proc c_sigsetjmp(jmpb: C_JmpBuf, savemask: cint): cint {.
+      header: "<setjmp.h>", importc: "sigsetjmp".}
+    c_sigsetjmp(jmpb, 0)
+elif defined(nimRawSetjmp) and not defined(nimStdSetjmp):
+  proc c_longjmp(jmpb: C_JmpBuf, retval: cint) {.
+    header: "<setjmp.h>", importc: "_longjmp".}
+  proc c_setjmp(jmpb: C_JmpBuf): cint {.
+    header: "<setjmp.h>", importc: "_setjmp".}
+else:
+  proc c_longjmp(jmpb: C_JmpBuf, retval: cint) {.
+    header: "<setjmp.h>", importc: "longjmp".}
+  proc c_setjmp(jmpb: C_JmpBuf): cint {.
+    header: "<setjmp.h>", importc: "setjmp".}
 
 proc c_signal(sig: cint, handler: proc (a: cint) {.noconv.}) {.
   importc: "signal", header: "<signal.h>".}
diff --git a/lib/wrappers/postgres.nim b/lib/wrappers/postgres.nim
index 6c857de40..cb39c41bb 100644
--- a/lib/wrappers/postgres.nim
+++ b/lib/wrappers/postgres.nim
@@ -213,8 +213,10 @@ proc pqexecParams*(conn: PPGconn, command: cstring, nParams: int32,
                    paramTypes: POid, paramValues: cstringArray, 
                    paramLengths, paramFormats: ptr int32, resultFormat: int32): PPGresult{.
     cdecl, dynlib: dllName, importc: "PQexecParams".}
-proc pqexecPrepared*(conn: PPGconn, stmtName: cstring, nParams: int32, 
-                     paramValues: cstringArray, 
+proc pqprepare*(conn: PPGconn, stmtName, query: cstring, nParams: int32,
+    paramTypes: POid): PPGresult{.cdecl, dynlib: dllName, importc: "PQprepare".}
+proc pqexecPrepared*(conn: PPGconn, stmtName: cstring, nParams: int32,
+                     paramValues: cstringArray,
                      paramLengths, paramFormats: ptr int32, resultFormat: int32): PPGresult{.
     cdecl, dynlib: dllName, importc: "PQexecPrepared".}
 proc pqsendQuery*(conn: PPGconn, query: cstring): int32{.cdecl, dynlib: dllName,