SQLite wrapper

This commit is contained in:
Andreas Rumpf
2010-02-24 01:04:39 +01:00
parent 6da95ed9ca
commit f41bd71e61
43 changed files with 321 additions and 93 deletions

View File

@@ -16,7 +16,7 @@ cc = gcc
path="$lib/pure"
path="$lib/impure"
path="$lib/wrappers"
path="$lib/newwrap"
path="$lib/wrappers/cairo"
path="$lib/wrappers/gtk"
path="$lib/wrappers/lua"

View File

@@ -1,5 +1,6 @@
Mario Ray Mahardhika
Philippe Lhoste
Alexander R<>dseth
Jonathan Plona
Mario Ray Mahardhika
Dominik Picheta
Jonathan Plona
Alexander R<>dseth

View File

@@ -1,4 +1,4 @@
# Test the new CGI module
# Test/show CGI module
import strtabs, cgi

View File

@@ -4,7 +4,7 @@ import
var hCurl = curl_easy_init()
if hCurl != nil:
discard curl_easy_setopt(hCurl, CURLOPT_VERBOSE, True)
discard curl_easy_setopt(hCurl, CURLOPT_URL, "http://nimrod.ethexor.com")
discard curl_easy_setopt(hCurl, CURLOPT_URL, "http://force7.de/nimrod")
discard curl_easy_perform(hCurl)
curl_easy_cleanup(hCurl)

View File

@@ -60,12 +60,12 @@ proc dbFormat(formatstr: TSqlQuery, args: openarray[string]): string =
else:
add(result, c)
proc TryQuery*(db: TDbConn, query: TSqlQuery, args: openarray[string]): bool =
proc TryExec*(db: TDbConn, query: TSqlQuery, args: openarray[string]): bool =
## tries to execute the query and returns true if successful, false otherwise.
var q = dbFormat(query, args)
return mysqlRealQuery(db, q, q.len) == 0'i32
proc Query*(db: TDbConn, query: TSqlQuery, args: openarray[string]) =
proc Exec*(db: TDbConn, query: TSqlQuery, args: openarray[string]) =
## executes the query and raises EDB if not successful.
var q = dbFormat(query, args)
if mysqlRealQuery(db, q, q.len) != 0'i32: dbError(db)
@@ -84,7 +84,7 @@ iterator FastRows*(db: TDbConn, query: TSqlQuery,
## executes the query and iterates over the result dataset. This is very
## fast, but potenially dangerous: If the for-loop-body executes another
## query, the results can be undefined. For Postgres it is safe though.
Query(db, query, args)
Exec(db, query, args)
var sqlres = mysqlUseResult(db)
if sqlres != nil:
var L = int(mysql_num_fields(sqlres))
@@ -103,7 +103,7 @@ proc GetAllRows*(db: TDbConn, query: TSqlQuery,
args: openarray[string]): seq[TRow] =
## executes the query and returns the whole result dataset.
result = @[]
Query(db, query, args)
Exec(db, query, args)
var sqlres = mysqlUseResult(db)
if sqlres != nil:
var L = int(mysql_num_fields(sqlres))
@@ -149,11 +149,11 @@ proc InsertID*(db: TDbConn, query: TSqlQuery, args: openArray[string]): int64 =
result = TryInsertID(db, query, args)
if result < 0: dbError(db)
proc QueryAffectedRows*(db: TDbConn, query: TSqlQuery,
args: openArray[string]): int64 =
proc ExecAffectedRows*(db: TDbConn, query: TSqlQuery,
args: openArray[string]): int64 =
## runs the query (typically "UPDATE") and returns the
## number of affected rows
Query(db, query, args)
Exec(db, query, args)
result = mysql_affected_rows(db)
proc Close*(db: TDbConn) =

View File

@@ -59,15 +59,15 @@ proc dbFormat(formatstr: TSqlQuery, args: openarray[string]): string =
else:
add(result, c)
proc TryQuery*(db: TDbConn, query: TSqlQuery,
args: openarray[string]): bool =
proc TryExec*(db: TDbConn, query: TSqlQuery,
args: openarray[string]): bool =
## tries to execute the query and returns true if successful, false otherwise.
var q = dbFormat(query, args)
var res = PQExec(db, q)
result = PQresultStatus(res) == PGRES_COMMAND_OK
PQclear(res)
proc Query*(db: TDbConn, query: TSqlQuery, args: openarray[string]) =
proc Exec*(db: TDbConn, query: TSqlQuery, args: openarray[string]) =
## executes the query and raises EDB if not successful.
var q = dbFormat(query, args)
var res = PQExec(db, q)
@@ -143,8 +143,8 @@ proc InsertID*(db: TDbConn, query: TSqlQuery,
result = TryInsertID(db, query, args)
if result < 0: dbError(db)
proc QueryAffectedRows*(db: TDbConn, query: TSqlQuery,
args: openArray[string]): int64 =
proc ExecAffectedRows*(db: TDbConn, query: TSqlQuery,
args: openArray[string]): int64 =
## executes the query (typically "UPDATE") and returns the
## number of affected rows.
var q = dbFormat(query, args)

178
lib/impure/db_sqlite.nim Normal file
View File

@@ -0,0 +1,178 @@
#
#
# Nimrod's Runtime Library
# (c) Copyright 2010 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## A higher level `PostgreSQL`:idx: database wrapper. This interface
## is implemented for other databases too.
import strutils, sqlite3
type
TDbConn* = PSqlite3 ## encapsulates a database connection
TRow* = seq[string] ## a row of a dataset
EDb* = object of EIO ## exception that is raised if a database error occurs
TSqlQuery* = distinct string ## an SQL query string
proc sql*(query: string): TSqlQuery {.noSideEffect, inline.} =
## constructs a TSqlQuery from the string `query`. This is supposed to be
## used as a raw-string-literal modifier:
## ``sql"update user set counter = counter + 1"``
##
## If assertions are turned off, it does nothing. If assertions are turned
## on, later versions will check the string for valid syntax.
result = TSqlQuery(query)
proc dbError(db: TDbConn) {.noreturn.} =
## raises an EDb exception.
var e: ref EDb
new(e)
e.msg = $sqlite3.errmsg(db)
raise e
proc dbError*(msg: string) {.noreturn.} =
## raises an EDb exception with message `msg`.
var e: ref EDb
new(e)
e.msg = msg
raise e
proc dbQuote(s: string): string =
result = "'"
for c in items(s):
if c == '\'': add(result, "''")
else: add(result, c)
add(result, '\'')
proc dbFormat(formatstr: TSqlQuery, args: openarray[string]): string =
result = ""
var a = 0
for c in items(string(formatstr)):
if c == '?':
add(result, dbQuote(args[a]))
inc(a)
else:
add(result, c)
proc TryExec*(db: TDbConn, query: TSqlQuery,
args: openarray[string]): bool =
## tries to execute the query and returns true if successful, false otherwise.
var q = dbFormat(query, args)
var stmt: sqlite3.PStmt
if prepare_v2(db, q, q.len, stmt, nil) == SQLITE_OK:
if step(stmt) == SQLITE_DONE:
result = finalize(stmt) == SQLITE_OK
proc Exec*(db: TDbConn, query: TSqlQuery, args: openarray[string]) =
## executes the query and raises EDB if not successful.
if not TryExec(db, query, args): dbError(db)
proc newRow(L: int): TRow =
newSeq(result, L)
for i in 0..L-1: result[i] = ""
proc setupQuery(db: TDbConn, query: TSqlQuery,
args: openarray[string]): PStmt =
var q = dbFormat(query, args)
if prepare_v2(db, q, q.len, result, nil) != SQLITE_OK: dbError(db)
proc setRow(stmt: PStmt, r: var TRow, cols: int) =
for col in 0..cols-1:
setLen(r[col], column_bytes(stmt, col)) # set capacity
setLen(r[col], 0)
add(r[col], column_text(stmt, col))
iterator FastRows*(db: TDbConn, query: TSqlQuery,
args: openarray[string]): TRow =
## executes the query and iterates over the result dataset. This is very
## fast, but potenially dangerous: If the for-loop-body executes another
## query, the results can be undefined. For Sqlite it is safe though.
var stmt = setupQuery(db, query, args)
var L = int(columnCount(stmt))
var result = newRow(L)
while step(stmt) == SQLITE_ROW:
setRow(stmt, result, L)
yield result
if finalize(stmt) != SQLITE_OK: dbError(db)
proc GetAllRows*(db: TDbConn, query: TSqlQuery,
args: openarray[string]): seq[TRow] =
## 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,
args: openarray[string]): TRow =
## same as `FastRows`, but slower and safe.
for r in FastRows(db, query, args): yield r
proc GetValue*(db: TDbConn, query: TSqlQuery,
args: openarray[string]): string =
## executes the query and returns the result dataset's the first column
## of the first row. Returns "" if the dataset contains no rows.
var stmt = setupQuery(db, query, args)
if step(stmt) == SQLITE_ROW:
result = newString(column_bytes(stmt, 0))
setLen(result, 0)
add(result, column_text(stmt, 0))
if finalize(stmt) != SQLITE_OK: dbError(db)
else:
result = ""
proc TryInsertID*(db: TDbConn, query: TSqlQuery,
args: openarray[string]): int64 =
## executes the query (typically "INSERT") and returns the
## generated ID for the row or -1 in case of an error.
if tryExec(db, query, args):
result = last_insert_rowid(db)
else:
result = -1
proc InsertID*(db: TDbConn, query: TSqlQuery,
args: openArray[string]): int64 =
## executes the query (typically "INSERT") and returns the
## generated ID for the row. For Postgre this adds
## ``RETURNING id`` to the query, so it only works if your primary key is
## named ``id``.
result = TryInsertID(db, query, args)
if result < 0: dbError(db)
proc ExecAffectedRows*(db: TDbConn, query: TSqlQuery,
args: openArray[string]): int64 =
## executes the query (typically "UPDATE") and returns the
## number of affected rows.
Exec(db, query, args)
result = changes(db)
proc Close*(db: TDbConn) =
## closes the database connection.
if sqlite3.close(db) != SQLITE_OK:
dbError(db)
proc Open*(connection, user, password, database: string): TDbConn =
## opens a database connection. Raises `EDb` if the connection could not
## be established. Only the ``connection`` parameter is used for ``sqlite``.
var db: TDbConn
if sqlite3.open(connection, db) == SQLITE_OK:
return db
else:
dbError(db)
when isMainModule:
var db = open("db.sql", "", "", "")
Exec(db, sql"create table tbl1(one varchar(10), two smallint)", [])
exec(db, sql"insert into tbl1 values('hello!',10)", [])
exec(db, sql"insert into tbl1 values('goodbye', 20)", [])
#db.query("create table tbl1(one varchar(10), two smallint)")
#db.query("insert into tbl1 values('hello!',10)")
#db.query("insert into tbl1 values('goodbye', 20)")
for r in db.rows(sql"select * from tbl1", []):
echo(r[0], r[1])
db_sqlite.close(db)

View File

@@ -17,7 +17,7 @@
## Currently only requesting URLs is implemented. The implementation depends
## on the libcurl library!
##
## **Deprecated since version 0.8.6:** Use the httpclient module instead.
## **Deprecated since version 0.8.6:** Use the ``httpclient`` module instead.
##
{.deprecated.}

View File

@@ -96,30 +96,24 @@ const
SQLITE_TRANSIENT* = cast[pointer](- 1)
type
sqlite_int64* = int64
PPPChar* = ptr ptr cstring
TSqlite3 {.pure, final.} = object
PSqlite3* = ptr TSqlite3
PPSqlite3* = ptr PSqlite3
TSqlLite3Context{.pure, final.} = object
Pcontext* = ptr TSqlLite3Context
TContext{.pure, final.} = object
Pcontext* = ptr TContext
Tstmt{.pure, final.} = object
Pstmt* = ptr Tstmt
PPsqlite3_stmt* = ptr Pstmt
Tvalue{.pure, final.} = object
Pvalue* = ptr Tvalue
PPsqlite3_value* = ptr Pvalue #Callback function types
#Notice that most functions
#were named using as prefix the
#function name that uses them,
#rather than describing their functions
Tcallback* = proc (para1: pointer, para2: int32, para3: var cstring,
para4: var cstring): int32{.cdecl.}
PPValue* = ptr Pvalue
Tcallback* = proc (para1: pointer, para2: int32, para3,
para4: cstringArray): int32{.cdecl.}
Tbind_destructor_func* = proc (para1: pointer){.cdecl.}
Tcreate_function_step_func* = proc (para1: Pcontext, para2: int32,
para3: PPsqlite3_value){.cdecl.}
para3: PPValue){.cdecl.}
Tcreate_function_func_func* = proc (para1: Pcontext, para2: int32,
para3: PPsqlite3_value){.cdecl.}
para3: PPValue){.cdecl.}
Tcreate_function_final_func* = proc (para1: Pcontext){.cdecl.}
Tresult_func* = proc (para1: pointer){.cdecl.}
Tcreate_collation_func* = proc (para1: pointer, para2: int32, para3: pointer,
@@ -131,7 +125,7 @@ proc close*(para1: PSqlite3): int32{.cdecl, dynlib: Lib, importc: "sqlite3_close
proc exec*(para1: PSqlite3, sql: cstring, para3: Tcallback, para4: pointer,
errmsg: var cstring): int32{.cdecl, dynlib: Lib,
importc: "sqlite3_exec".}
proc last_insert_rowid*(para1: PSqlite3): sqlite_int64{.cdecl, dynlib: Lib,
proc last_insert_rowid*(para1: PSqlite3): int64{.cdecl, dynlib: Lib,
importc: "sqlite3_last_insert_rowid".}
proc changes*(para1: PSqlite3): int32{.cdecl, dynlib: Lib, importc: "sqlite3_changes".}
proc total_changes*(para1: PSqlite3): int32{.cdecl, dynlib: Lib,
@@ -183,10 +177,15 @@ proc errcode*(db: PSqlite3): int32{.cdecl, dynlib: Lib, importc: "sqlite3_errcod
proc errmsg*(para1: PSqlite3): cstring{.cdecl, dynlib: Lib, importc: "sqlite3_errmsg".}
proc errmsg16*(para1: PSqlite3): pointer{.cdecl, dynlib: Lib,
importc: "sqlite3_errmsg16".}
proc prepare*(db: PSqlite3, zSql: cstring, nBytes: int32, ppStmt: PPsqlite3_stmt,
proc prepare*(db: PSqlite3, zSql: cstring, nBytes: int32, ppStmt: var PStmt,
pzTail: ptr cstring): int32{.cdecl, dynlib: Lib,
importc: "sqlite3_prepare".}
proc prepare16*(db: PSqlite3, zSql: pointer, nBytes: int32, ppStmt: PPsqlite3_stmt,
proc prepare_v2*(db: PSqlite3, zSql: cstring, nByte: cint, ppStmt: var PStmt,
pzTail: ptr cstring): cint {.
importc: "sqlite3_prepare_v2", cdecl, dynlib: Lib.}
proc prepare16*(db: PSqlite3, zSql: pointer, nBytes: int32, ppStmt: var PStmt,
pzTail: var pointer): int32{.cdecl, dynlib: Lib,
importc: "sqlite3_prepare16".}
proc bind_blob*(para1: Pstmt, para2: int32, para3: pointer, n: int32,
@@ -196,7 +195,7 @@ proc bind_double*(para1: Pstmt, para2: int32, para3: float64): int32{.cdecl,
dynlib: Lib, importc: "sqlite3_bind_double".}
proc bind_int*(para1: Pstmt, para2: int32, para3: int32): int32{.cdecl,
dynlib: Lib, importc: "sqlite3_bind_int".}
proc bind_int64*(para1: Pstmt, para2: int32, para3: sqlite_int64): int32{.cdecl,
proc bind_int64*(para1: Pstmt, para2: int32, para3: int64): int32{.cdecl,
dynlib: Lib, importc: "sqlite3_bind_int64".}
proc bind_null*(para1: Pstmt, para2: int32): int32{.cdecl, dynlib: Lib,
importc: "sqlite3_bind_null".}
@@ -248,7 +247,7 @@ proc column_double*(para1: Pstmt, iCol: int32): float64{.cdecl, dynlib: Lib,
importc: "sqlite3_column_double".}
proc column_int*(para1: Pstmt, iCol: int32): int32{.cdecl, dynlib: Lib,
importc: "sqlite3_column_int".}
proc column_int64*(para1: Pstmt, iCol: int32): sqlite_int64{.cdecl, dynlib: Lib,
proc column_int64*(para1: Pstmt, iCol: int32): int64{.cdecl, dynlib: Lib,
importc: "sqlite3_column_int64".}
proc column_text*(para1: Pstmt, iCol: int32): cstring{.cdecl, dynlib: Lib,
importc: "sqlite3_column_text".}
@@ -283,7 +282,7 @@ proc value_double*(para1: Pvalue): float64{.cdecl, dynlib: Lib,
importc: "sqlite3_value_double".}
proc value_int*(para1: Pvalue): int32{.cdecl, dynlib: Lib,
importc: "sqlite3_value_int".}
proc value_int64*(para1: Pvalue): sqlite_int64{.cdecl, dynlib: Lib,
proc value_int64*(para1: Pvalue): int64{.cdecl, dynlib: Lib,
importc: "sqlite3_value_int64".}
proc value_text*(para1: Pvalue): cstring{.cdecl, dynlib: Lib,
importc: "sqlite3_value_text".}
@@ -315,7 +314,7 @@ proc result_error16*(para1: Pcontext, para2: pointer, para3: int32){.cdecl,
dynlib: Lib, importc: "sqlite3_result_error16".}
proc result_int*(para1: Pcontext, para2: int32){.cdecl, dynlib: Lib,
importc: "sqlite3_result_int".}
proc result_int64*(para1: Pcontext, para2: sqlite_int64){.cdecl, dynlib: Lib,
proc result_int64*(para1: Pcontext, para2: int64){.cdecl, dynlib: Lib,
importc: "sqlite3_result_int64".}
proc result_null*(para1: Pcontext){.cdecl, dynlib: Lib,
importc: "sqlite3_result_null".}

View File

@@ -1,7 +1,7 @@
#
#
# Nimrod's Runtime Library
# (c) Copyright 2009 Andreas Rumpf
# (c) Copyright 2010 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
@@ -35,41 +35,41 @@ type
iterator objectFields*[T](x: T, skipInherited: bool): tuple[
key: string, val: TVariant] {.magic: "ObjectFields"}
proc `<>`*(x: ordinal): TVariant =
proc `?`*(x: ordinal): TVariant =
result.kind = vtEnum
result.vint = x
proc `<>`*(x: biggestInt): TVariant =
proc `?`*(x: biggestInt): TVariant =
result.kind = vtInt
result.vint = x
proc `<>`*(x: char): TVariant =
proc `?`*(x: char): TVariant =
result.kind = vtChar
result.vint = ord(x)
proc `<>`*(x: bool): TVariant =
proc `?`*(x: bool): TVariant =
result.kind = vtBool
result.vint = ord(x)
proc `<>`*(x: biggestFloat): TVariant =
proc `?`*(x: biggestFloat): TVariant =
result.kind = vtFloat
result.vfloat = x
proc `<>`*(x: string): TVariant =
proc `?`*(x: string): TVariant =
result.kind = vtString
result.vstring = x
proc `<>`*[T](x: openArray[T]): TVariant =
proc `?`*[T](x: openArray[T]): TVariant =
result.kind = vtSeq
newSeq(result.q, x.len)
for i in 0..x.len-1: result.q[i] = <>x[i]
proc `<>`*[T](x: set[T]): TVariant =
proc `?`*[T](x: set[T]): TVariant =
result.kind = vtSet
result.q = @[]
for a in items(x): result.q.add(<>a)
proc `<>`* [T: object](x: T): TVariant {.magic: "ToVariant".}
proc `?`* [T: object](x: T): TVariant {.magic: "ToVariant".}
## this converts a value to a variant ("boxing")
proc `><`*[T](v: TVariant, typ: T): T {.magic: "FromVariant".}
@@ -140,10 +140,10 @@ proc `[]=`* (a, b, c: TVariant) =
variantError()
else: variantError()
proc `[]`* (a: TVariant, b: int): TVariant {.inline} = return a[<>b]
proc `[]`* (a: TVariant, b: string): TVariant {.inline} = return a[<>b]
proc `[]=`* (a: TVariant, b: int, c: TVariant) {.inline} = a[<>b] = c
proc `[]=`* (a: TVariant, b: string, c: TVariant) {.inline} = a[<>b] = c
proc `[]`* (a: TVariant, b: int): TVariant {.inline} = return a[?b]
proc `[]`* (a: TVariant, b: string): TVariant {.inline} = return a[?b]
proc `[]=`* (a: TVariant, b: int, c: TVariant) {.inline} = a[?b] = c
proc `[]=`* (a: TVariant, b: string, c: TVariant) {.inline} = a[?b] = c
proc `+`* (x, y: TVariant): TVariant =
case x.vtype

View File

@@ -133,6 +133,22 @@ proc skip(my: var TYamlLexer) =
var buf = my.buf
while true:
case buf[pos]
of '#':
# skip line comment:
inc(pos)
while true:
case buf[pos]
of '\0': break
of '\c':
pos = lexbase.HandleCR(my, pos)
buf = my.buf
break
of '\L':
pos = lexbase.HandleLF(my, pos)
buf = my.buf
break
else:
inc(pos)
of '/':
if buf[pos+1] == '/':
# skip line comment:
@@ -186,6 +202,26 @@ proc skip(my: var TYamlLexer) =
break
my.bufpos = pos
proc parseDirective(my: var TYamlLexer) =
var pos = my.bufpos
var buf = my.buf
inc(pos)
while buf[pos] in {'\t', ' '}: inc(pos)
while true:
case buf[pos]
of '\0': break
of '\c':
pos = lexbase.HandleCR(my, pos)
buf = my.buf
break
of '\L':
pos = lexbase.HandleLF(my, pos)
buf = my.buf
break
else:
add(my.a, buf[pos])
inc(pos)
proc parseNumber(my: var TYamlLexer) =
var pos = my.bufpos
var buf = my.buf
@@ -230,11 +266,16 @@ proc getTok(my: var TYamlLexer): TTokKind =
setLen(my.a, 0)
skip(my) # skip whitespace, comments
case my.buf[my.bufpos]
of '-':
inc(my.bufpos)
result = tkHyphen
of '-', '.', '0'..'9':
parseNumber(my)
result = tkNumber
of '"':
result = parseString(my)
of '\'':
result = parseSingleQuote(my)
of '[':
inc(my.bufpos)
result = tkBracketLe
@@ -253,8 +294,30 @@ proc getTok(my: var TYamlLexer): TTokKind =
of ':':
inc(my.bufpos)
result = tkColon
of '\0':
result = tkEof
of '?':
inc(my.bufpos)
result = tkQust
of '!':
inc(my.bufpos)
result = tkExcl
of '&':
inc(my.bufpos)
result = tkAmp
of '*':
inc(my.bufpos)
result = tkStar
of '|':
parseLiteralBlockScalar(my)
result = tkLiteralBlockScalar
of '>':
parseFoldedBlockScalar(my)
result = tkFoldedBlockScalar
of '%':
parseDirective(my)
result = tkDirective
of '@', '`':
inc(my.bufpos)
result = tkReserved
of 'a'..'z', 'A'..'Z', '_':
parseName(my)
case my.a
@@ -262,6 +325,8 @@ proc getTok(my: var TYamlLexer): TTokKind =
of "true": result = tkTrue
of "false": result = tkFalse
else: result = tkError
of '\0':
result = tkEof
else:
inc(my.bufpos)
result = tkError

View File

@@ -1,7 +1,7 @@
#
#
# Nimrod's Runtime Library
# (c) Copyright 2009 Andreas Rumpf
# (c) Copyright 2010 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
@@ -112,8 +112,8 @@ type
#were named using as prefix the
#function name that uses them,
#rather than describing their functions
Tsqlite3_callback* = proc (para1: pointer, para2: int32, para3: var cstring,
para4: var cstring): int32{.cdecl.}
Tsqlite3_callback* = proc (para1: pointer, para2: int32, para3,
para4: cstringArray): int32{.cdecl.}
Tbind_destructor_func* = proc (para1: pointer){.cdecl.}
Tcreate_function_step_func* = proc (para1: Psqlite3_context, para2: int32,
para3: PPsqlite3_value){.cdecl.}

View File

@@ -1,34 +0,0 @@
# Hallo world program
echo("Hi! What's your name?")
var name = readLine(stdin)
if name == "Andreas":
echo("What a nice name!")
elif name == "":
echo("Don't you have a name?")
else:
echo("Your name is not Andreas...")
for i in 0..name.len-1:
if name[i] == 'm':
echo("hey, there is an *m* in your name!")
echo("Please give your password: (12345)")
var pw = readLine(stdin)
while pw != "12345":
echo("Wrong password! Next try: ")
pw = readLine(stdin)
echo("""Login complete!
What do you want to do?
delete-everything
restart-computer
go-for-a-walk""")
case readline(stdin)
of "delete-everything", "restart-computer":
echo("permission denied")
of "go-for-a-walk": echo("please yourself")
else: echo("unknown command")

5
tests/reject/tatomic.nim Normal file
View File

@@ -0,0 +1,5 @@
var
atomic: int
echo atomic

14
tests/testdata/doc1.xml vendored Normal file
View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<root>
<tag>
<test arg="blah" arg2="test"/>
<test2>
bla ah absy hsh
hsh
sjj
</test2>
<test><teh>bla</teh></test>
</tag>
</root>