mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-18 21:40:32 +00:00
Merge branch 'devel' of github.com:nim-lang/Nim into devel
This commit is contained in:
@@ -104,6 +104,8 @@ This now needs to be written as:
|
||||
- [``poly``](https://github.com/lcrees/polynumeric)
|
||||
- [``pdcurses``](https://github.com/lcrees/pdcurses)
|
||||
- [``romans``](https://github.com/lcrees/romans)
|
||||
- [``libsvm``](https://github.com/nim-lang/libsvm_legacy)
|
||||
- [``joyent_http_parser``](https://github.com/nim-lang/joyent_http_parser)
|
||||
|
||||
- Added ``system.runnableExamples`` to make examples in Nim's documentation easier
|
||||
to write and test. The examples are tested as the last step of
|
||||
@@ -263,4 +265,4 @@ bar()
|
||||
|
||||
import std / [strutils, os, osproc]
|
||||
import someNimblePackage / [strutils, os]
|
||||
```
|
||||
```
|
||||
11
doc/lib.rst
11
doc/lib.rst
@@ -557,21 +557,10 @@ Database support
|
||||
Network Programming and Internet Protocols
|
||||
------------------------------------------
|
||||
|
||||
* `joyent_http_parser <joyent_http_parser.html>`_
|
||||
Wrapper for the joyent's high-performance HTTP parser.
|
||||
|
||||
* `openssl <openssl.html>`_
|
||||
Wrapper for OpenSSL.
|
||||
|
||||
|
||||
|
||||
Scientific computing
|
||||
--------------------
|
||||
|
||||
* `libsvm <libsvm.html>`_
|
||||
Low level wrapper for `lib svm <http://www.csie.ntu.edu.tw/~cjlin/libsvm/>`_.
|
||||
|
||||
|
||||
Nimble
|
||||
======
|
||||
|
||||
|
||||
@@ -50,22 +50,21 @@ when defined(windows) or defined(nimdoc):
|
||||
case mode
|
||||
of fmRead, fmReadWriteExisting:
|
||||
OPEN_EXISTING
|
||||
of fmAppend, fmReadWrite, fmWrite:
|
||||
if fileExists(filename):
|
||||
OPEN_EXISTING
|
||||
else:
|
||||
CREATE_NEW
|
||||
of fmReadWrite, fmWrite:
|
||||
CREATE_ALWAYS
|
||||
of fmAppend:
|
||||
OPEN_ALWAYS
|
||||
else:
|
||||
proc getPosixFlags(mode: FileMode): cint =
|
||||
case mode
|
||||
of fmRead:
|
||||
result = O_RDONLY
|
||||
of fmWrite:
|
||||
result = O_WRONLY or O_CREAT
|
||||
result = O_WRONLY or O_CREAT or O_TRUNC
|
||||
of fmAppend:
|
||||
result = O_WRONLY or O_CREAT or O_APPEND
|
||||
of fmReadWrite:
|
||||
result = O_RDWR or O_CREAT
|
||||
result = O_RDWR or O_CREAT or O_TRUNC
|
||||
of fmReadWriteExisting:
|
||||
result = O_RDWR
|
||||
result = result or O_NONBLOCK
|
||||
|
||||
@@ -150,6 +150,31 @@ proc code*(response: Response | AsyncResponse): HttpCode
|
||||
## corresponding ``HttpCode``.
|
||||
return response.status[0 .. 2].parseInt.HttpCode
|
||||
|
||||
proc contentType*(response: Response | AsyncResponse): string =
|
||||
## Retrieves the specified response's content type.
|
||||
##
|
||||
## This is effectively the value of the "Content-Type" header.
|
||||
response.headers.getOrDefault("content-type")
|
||||
|
||||
proc contentLength*(response: Response | AsyncResponse): int =
|
||||
## Retrieves the specified response's content length.
|
||||
##
|
||||
## This is effectively the value of the "Content-Length" header.
|
||||
##
|
||||
## A ``ValueError`` exception will be raised if the value is not an integer.
|
||||
var contentLengthHeader = response.headers.getOrDefault("Content-Length")
|
||||
return contentLengthHeader.parseInt()
|
||||
|
||||
proc lastModified*(response: Response | AsyncResponse): DateTime =
|
||||
## Retrieves the specified response's last modified time.
|
||||
##
|
||||
## This is effectively the value of the "Last-Modified" header.
|
||||
##
|
||||
## Raises a ``ValueError`` if the parsing fails or the value is not a correctly
|
||||
## formatted time.
|
||||
var lastModifiedHeader = response.headers.getOrDefault("last-modified")
|
||||
result = parse(lastModifiedHeader, "dd, dd MMM yyyy HH:mm:ss Z")
|
||||
|
||||
proc body*(response: Response): string =
|
||||
## Retrieves the specified response's body.
|
||||
##
|
||||
|
||||
@@ -64,6 +64,9 @@
|
||||
## socket.acceptAddr(client, address)
|
||||
## echo("Client connected from: ", address)
|
||||
##
|
||||
## **Note:** The ``client`` variable is initialised with ``new Socket`` **not**
|
||||
## ``newSocket()``. The difference is that the latter creates a new file
|
||||
## descriptor.
|
||||
|
||||
{.deadCodeElim: on.}
|
||||
import nativesockets, os, strutils, parseutils, times, sets, options
|
||||
@@ -753,6 +756,8 @@ proc acceptAddr*(server: Socket, client: var Socket, address: var string,
|
||||
## flag is specified then this error will not be raised and instead
|
||||
## accept will be called again.
|
||||
assert(client != nil)
|
||||
assert client.fd.int <= 0, "Client socket needs to be initialised with " &
|
||||
"`new`, not `newSocket`."
|
||||
let ret = accept(server.fd)
|
||||
let sock = ret[0]
|
||||
|
||||
|
||||
@@ -933,6 +933,14 @@ proc `$`*(time: Time): string {.tags: [], raises: [], benign.} =
|
||||
|
||||
proc parseToken(dt: var DateTime; token, value: string; j: var int) =
|
||||
## Helper of the parse proc to parse individual tokens.
|
||||
|
||||
# Overwrite system.`[]` to raise a ValueError on index out of bounds.
|
||||
proc `[]`[T, U](s: string, x: HSlice[T, U]): string =
|
||||
if x.a >= s.len or x.b >= s.len:
|
||||
raise newException(ValueError, "Value is missing required tokens, got: " &
|
||||
s)
|
||||
return system.`[]`(s, x)
|
||||
|
||||
var sv: int
|
||||
case token
|
||||
of "d":
|
||||
|
||||
@@ -666,6 +666,7 @@ const
|
||||
CREATE_ALWAYS* = 2'i32
|
||||
CREATE_NEW* = 1'i32
|
||||
OPEN_EXISTING* = 3'i32
|
||||
OPEN_ALWAYS* = 4'i32
|
||||
FILE_BEGIN* = 0'i32
|
||||
INVALID_SET_FILE_POINTER* = -1'i32
|
||||
NO_ERROR* = 0'i32
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
#
|
||||
#
|
||||
# Nim's Runtime Library
|
||||
# (c) Copyright 2015 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
type
|
||||
csize = int
|
||||
|
||||
HttpDataProc* = proc (a2: ptr HttpParser, at: cstring, length: csize): cint {.cdecl.}
|
||||
HttpProc* = proc (a2: ptr HttpParser): cint {.cdecl.}
|
||||
|
||||
HttpMethod* = enum
|
||||
HTTP_DELETE = 0, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_CONNECT,
|
||||
HTTP_OPTIONS, HTTP_TRACE, HTTP_COPY, HTTP_LOCK, HTTP_MKCOL, HTTP_MOVE,
|
||||
HTTP_PROPFIND, HTTP_PROPPATCH, HTTP_UNLOCK, HTTP_REPORT, HTTP_MKACTIVITY,
|
||||
HTTP_CHECKOUT, HTTP_MERGE, HTTP_MSEARCH, HTTP_NOTIFY, HTTP_SUBSCRIBE,
|
||||
HTTP_UNSUBSCRIBE, HTTP_PATCH
|
||||
|
||||
HttpParserType* = enum
|
||||
HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH
|
||||
|
||||
ParserFlag* = enum
|
||||
F_CHUNKED = 1 shl 0,
|
||||
F_CONNECTION_KEEP_ALIVE = 1 shl 1,
|
||||
F_CONNECTION_CLOSE = 1 shl 2,
|
||||
F_TRAILING = 1 shl 3,
|
||||
F_UPGRADE = 1 shl 4,
|
||||
F_SKIPBODY = 1 shl 5
|
||||
|
||||
HttpErrNo* = enum
|
||||
HPE_OK, HPE_CB_message_begin, HPE_CB_path, HPE_CB_query_string, HPE_CB_url,
|
||||
HPE_CB_fragment, HPE_CB_header_field, HPE_CB_header_value,
|
||||
HPE_CB_headers_complete, HPE_CB_body, HPE_CB_message_complete,
|
||||
HPE_INVALID_EOF_STATE, HPE_HEADER_OVERFLOW, HPE_CLOSED_CONNECTION,
|
||||
HPE_INVALID_VERSION, HPE_INVALID_STATUS, HPE_INVALID_METHOD,
|
||||
HPE_INVALID_URL, HPE_INVALID_HOST, HPE_INVALID_PORT, HPE_INVALID_PATH,
|
||||
HPE_INVALID_QUERY_STRING, HPE_INVALID_FRAGMENT, HPE_LF_EXPECTED,
|
||||
HPE_INVALID_HEADER_TOKEN, HPE_INVALID_CONTENT_LENGTH,
|
||||
HPE_INVALID_CHUNK_SIZE, HPE_INVALID_CONSTANT, HPE_INVALID_INTERNAL_STATE,
|
||||
HPE_STRICT, HPE_UNKNOWN
|
||||
|
||||
HttpParser*{.pure, final, importc: "http_parser", header: "http_parser.h".} = object
|
||||
typ {.importc: "type".}: char
|
||||
flags {.importc: "flags".}: char
|
||||
state*{.importc: "state".}: char
|
||||
header_state*{.importc: "header_state".}: char
|
||||
index*{.importc: "index".}: char
|
||||
nread*{.importc: "nread".}: cint
|
||||
content_length*{.importc: "content_length".}: int64
|
||||
http_major*{.importc: "http_major".}: cshort
|
||||
http_minor*{.importc: "http_minor".}: cshort
|
||||
status_code*{.importc: "status_code".}: cshort
|
||||
http_method*{.importc: "method".}: cshort
|
||||
http_errno_bits {.importc: "http_errno".}: char
|
||||
upgrade {.importc: "upgrade".}: bool
|
||||
data*{.importc: "data".}: pointer
|
||||
|
||||
HttpParserSettings*{.pure, final, importc: "http_parser_settings", header: "http_parser.h".} = object
|
||||
on_message_begin*{.importc: "on_message_begin".}: HttpProc
|
||||
on_url*{.importc: "on_url".}: HttpDataProc
|
||||
on_header_field*{.importc: "on_header_field".}: HttpDataProc
|
||||
on_header_value*{.importc: "on_header_value".}: HttpDataProc
|
||||
on_headers_complete*{.importc: "on_headers_complete".}: HttpProc
|
||||
on_body*{.importc: "on_body".}: HttpDataProc
|
||||
on_message_complete*{.importc: "on_message_complete".}: HttpProc
|
||||
{.deprecated: [THttpMethod: HttpMethod, THttpParserType: HttpParserType,
|
||||
TParserFlag: ParserFlag, THttpErrNo: HttpErrNo,
|
||||
THttpParser: HttpParser, THttpParserSettings: HttpParserSettings].}
|
||||
|
||||
proc http_parser_init*(parser: var HttpParser, typ: HttpParserType){.
|
||||
importc: "http_parser_init", header: "http_parser.h".}
|
||||
|
||||
proc http_parser_execute*(parser: var HttpParser,
|
||||
settings: var HttpParserSettings, data: cstring,
|
||||
len: csize): csize {.
|
||||
importc: "http_parser_execute", header: "http_parser.h".}
|
||||
|
||||
proc http_should_keep_alive*(parser: var HttpParser): cint{.
|
||||
importc: "http_should_keep_alive", header: "http_parser.h".}
|
||||
|
||||
proc http_method_str*(m: HttpMethod): cstring{.
|
||||
importc: "http_method_str", header: "http_parser.h".}
|
||||
|
||||
proc http_errno_name*(err: HttpErrNo): cstring{.
|
||||
importc: "http_errno_name", header: "http_parser.h".}
|
||||
|
||||
proc http_errno_description*(err: HttpErrNo): cstring{.
|
||||
importc: "http_errno_description", header: "http_parser.h".}
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
#
|
||||
#
|
||||
# Nim's Runtime Library
|
||||
# (c) Copyright 2012 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
## This module is a low level wrapper for `libsvm`:idx:.
|
||||
|
||||
{.deadCodeElim: on.}
|
||||
const
|
||||
LIBSVM_VERSION* = 312
|
||||
|
||||
when defined(windows):
|
||||
const svmdll* = "libsvm.dll"
|
||||
elif defined(macosx):
|
||||
const svmdll* = "libsvm.dylib"
|
||||
else:
|
||||
const svmdll* = "libsvm.so"
|
||||
|
||||
type
|
||||
Node*{.pure, final.} = object
|
||||
index*: cint
|
||||
value*: cdouble
|
||||
|
||||
Problem*{.pure, final.} = object
|
||||
L*: cint
|
||||
y*: ptr cdouble
|
||||
x*: ptr ptr Node
|
||||
|
||||
Type*{.size: sizeof(cint).} = enum
|
||||
C_SVC, NU_SVC, ONE_CLASS, EPSILON_SVR, NU_SVR
|
||||
|
||||
KernelType*{.size: sizeof(cint).} = enum
|
||||
LINEAR, POLY, RBF, SIGMOID, PRECOMPUTED
|
||||
|
||||
Parameter*{.pure, final.} = object
|
||||
typ*: Type
|
||||
kernelType*: KernelType
|
||||
degree*: cint # for poly
|
||||
gamma*: cdouble # for poly/rbf/sigmoid
|
||||
coef0*: cdouble # for poly/sigmoid
|
||||
# these are for training only
|
||||
cache_size*: cdouble # in MB
|
||||
eps*: cdouble # stopping criteria
|
||||
C*: cdouble # for C_SVC, EPSILON_SVR and NU_SVR
|
||||
nr_weight*: cint # for C_SVC
|
||||
weight_label*: ptr cint # for C_SVC
|
||||
weight*: ptr cdouble # for C_SVC
|
||||
nu*: cdouble # for NU_SVC, ONE_CLASS, and NU_SVR
|
||||
p*: cdouble # for EPSILON_SVR
|
||||
shrinking*: cint # use the shrinking heuristics
|
||||
probability*: cint # do probability estimates
|
||||
{.deprecated: [Tnode: Node, Tproblem: Problem, Ttype: Type,
|
||||
TKernelType: KernelType, Tparameter: Parameter].}
|
||||
|
||||
#
|
||||
# svm_model
|
||||
#
|
||||
|
||||
type
|
||||
Model*{.pure, final.} = object
|
||||
param*: Parameter # parameter
|
||||
nr_class*: cint # number of classes, = 2 in regression/one class svm
|
||||
L*: cint # total #SV
|
||||
SV*: ptr ptr Node # SVs (SV[l])
|
||||
sv_coef*: ptr ptr cdouble # coefficients for SVs in decision functions (sv_coef[k-1][l])
|
||||
rho*: ptr cdouble # constants in decision functions (rho[k*(k-1)/2])
|
||||
probA*: ptr cdouble # pariwise probability information
|
||||
probB*: ptr cdouble # for classification only
|
||||
label*: ptr cint # label of each class (label[k])
|
||||
nSV*: ptr cint # number of SVs for each class (nSV[k])
|
||||
# nSV[0] + nSV[1] + ... + nSV[k-1] = l
|
||||
# XXX
|
||||
free_sv*: cint # 1 if svm_model is created by svm_load_model
|
||||
# 0 if svm_model is created by svm_train
|
||||
{.deprecated: [TModel: Model].}
|
||||
|
||||
proc train*(prob: ptr Problem, param: ptr Parameter): ptr Model{.cdecl,
|
||||
importc: "svm_train", dynlib: svmdll.}
|
||||
proc cross_validation*(prob: ptr Problem, param: ptr Parameter, nr_fold: cint,
|
||||
target: ptr cdouble){.cdecl,
|
||||
importc: "svm_cross_validation", dynlib: svmdll.}
|
||||
proc save_model*(model_file_name: cstring, model: ptr Model): cint{.cdecl,
|
||||
importc: "svm_save_model", dynlib: svmdll.}
|
||||
proc load_model*(model_file_name: cstring): ptr Model{.cdecl,
|
||||
importc: "svm_load_model", dynlib: svmdll.}
|
||||
proc get_svm_type*(model: ptr Model): cint{.cdecl, importc: "svm_get_svm_type",
|
||||
dynlib: svmdll.}
|
||||
proc get_nr_class*(model: ptr Model): cint{.cdecl, importc: "svm_get_nr_class",
|
||||
dynlib: svmdll.}
|
||||
proc get_labels*(model: ptr Model, label: ptr cint){.cdecl,
|
||||
importc: "svm_get_labels", dynlib: svmdll.}
|
||||
proc get_svr_probability*(model: ptr Model): cdouble{.cdecl,
|
||||
importc: "svm_get_svr_probability", dynlib: svmdll.}
|
||||
proc predict_values*(model: ptr Model, x: ptr Node, dec_values: ptr cdouble): cdouble{.
|
||||
cdecl, importc: "svm_predict_values", dynlib: svmdll.}
|
||||
proc predict*(model: ptr Model, x: ptr Node): cdouble{.cdecl,
|
||||
importc: "svm_predict", dynlib: svmdll.}
|
||||
proc predict_probability*(model: ptr Model, x: ptr Node,
|
||||
prob_estimates: ptr cdouble): cdouble{.cdecl,
|
||||
importc: "svm_predict_probability", dynlib: svmdll.}
|
||||
proc free_model_content*(model_ptr: ptr Model){.cdecl,
|
||||
importc: "svm_free_model_content", dynlib: svmdll.}
|
||||
proc free_and_destroy_model*(model_ptr_ptr: ptr ptr Model){.cdecl,
|
||||
importc: "svm_free_and_destroy_model", dynlib: svmdll.}
|
||||
proc destroy_param*(param: ptr Parameter){.cdecl, importc: "svm_destroy_param",
|
||||
dynlib: svmdll.}
|
||||
proc check_parameter*(prob: ptr Problem, param: ptr Parameter): cstring{.
|
||||
cdecl, importc: "svm_check_parameter", dynlib: svmdll.}
|
||||
proc check_probability_model*(model: ptr Model): cint{.cdecl,
|
||||
importc: "svm_check_probability_model", dynlib: svmdll.}
|
||||
|
||||
proc set_print_string_function*(print_func: proc (arg: cstring) {.cdecl.}){.
|
||||
cdecl, importc: "svm_set_print_string_function", dynlib: svmdll.}
|
||||
@@ -41,11 +41,11 @@ proc main() {.async.} =
|
||||
await file.write("test2")
|
||||
file.close()
|
||||
file = openAsync(fn, fmWrite)
|
||||
await file.write("test3")
|
||||
await file.write("t3")
|
||||
file.close()
|
||||
file = openAsync(fn, fmRead)
|
||||
let data = await file.readAll()
|
||||
doAssert data == "test3"
|
||||
doAssert data == "t3"
|
||||
file.close()
|
||||
|
||||
|
||||
|
||||
@@ -131,6 +131,10 @@ template parseTest(s, f, sExpected: string, ydExpected: int) =
|
||||
echo parsed.yearday, " exp: ", ydExpected
|
||||
check(parsed.yearday == ydExpected)
|
||||
|
||||
template parseTestExcp(s, f: string) =
|
||||
expect ValueError:
|
||||
let parsed = s.parse(f)
|
||||
|
||||
template parseTestTimeOnly(s, f, sExpected: string) =
|
||||
check sExpected in $s.parse(f, utc())
|
||||
|
||||
@@ -281,6 +285,51 @@ suite "ttimes":
|
||||
test "parseTest":
|
||||
runTimezoneTests()
|
||||
|
||||
test "incorrect inputs: empty string":
|
||||
parseTestExcp("", "yyyy-MM-dd")
|
||||
|
||||
test "incorrect inputs: year":
|
||||
parseTestExcp("20-02-19", "yyyy-MM-dd")
|
||||
|
||||
test "incorrect inputs: month number":
|
||||
parseTestExcp("2018-2-19", "yyyy-MM-dd")
|
||||
|
||||
test "incorrect inputs: month name":
|
||||
parseTestExcp("2018-Fe", "yyyy-MMM-dd")
|
||||
|
||||
test "incorrect inputs: day":
|
||||
parseTestExcp("2018-02-1", "yyyy-MM-dd")
|
||||
|
||||
test "incorrect inputs: day of week":
|
||||
parseTestExcp("2018-Feb-Mo", "yyyy-MMM-ddd")
|
||||
|
||||
test "incorrect inputs: hour":
|
||||
parseTestExcp("2018-02-19 1:30", "yyyy-MM-dd hh:mm")
|
||||
|
||||
test "incorrect inputs: minute":
|
||||
parseTestExcp("2018-02-19 16:3", "yyyy-MM-dd hh:mm")
|
||||
|
||||
test "incorrect inputs: second":
|
||||
parseTestExcp("2018-02-19 16:30:0", "yyyy-MM-dd hh:mm:ss")
|
||||
|
||||
test "incorrect inputs: timezone (z)":
|
||||
parseTestExcp("2018-02-19 16:30:00 ", "yyyy-MM-dd hh:mm:ss z")
|
||||
|
||||
test "incorrect inputs: timezone (zz) 1":
|
||||
parseTestExcp("2018-02-19 16:30:00 ", "yyyy-MM-dd hh:mm:ss zz")
|
||||
|
||||
test "incorrect inputs: timezone (zz) 2":
|
||||
parseTestExcp("2018-02-19 16:30:00 +1", "yyyy-MM-dd hh:mm:ss zz")
|
||||
|
||||
test "incorrect inputs: timezone (zzz) 1":
|
||||
parseTestExcp("2018-02-19 16:30:00 ", "yyyy-MM-dd hh:mm:ss zzz")
|
||||
|
||||
test "incorrect inputs: timezone (zzz) 2":
|
||||
parseTestExcp("2018-02-19 16:30:00 +01:", "yyyy-MM-dd hh:mm:ss zzz")
|
||||
|
||||
test "incorrect inputs: timezone (zzz) 3":
|
||||
parseTestExcp("2018-02-19 16:30:00 +01:0", "yyyy-MM-dd hh:mm:ss zzz")
|
||||
|
||||
test "dynamic timezone":
|
||||
proc staticOffset(offset: int): Timezone =
|
||||
proc zoneInfoFromTz(adjTime: Time): ZonedTime =
|
||||
|
||||
@@ -77,7 +77,5 @@ webdoc: "wrappers/mysql;wrappers/iup"
|
||||
webdoc: "wrappers/sqlite3;wrappers/postgres;wrappers/tinyc;wrappers/odbcsql"
|
||||
webdoc: "wrappers/pcre"
|
||||
webdoc: "wrappers/openssl"
|
||||
webdoc: "wrappers/joyent_http_parser"
|
||||
|
||||
webdoc: "posix/posix;wrappers/odbcsql"
|
||||
webdoc: "wrappers/libsvm.nim"
|
||||
|
||||
Reference in New Issue
Block a user