diff options
-rwxr-xr-x | lib/impure/re.nim | 2 | ||||
-rwxr-xr-x | lib/pure/httpserver.nim | 53 | ||||
-rwxr-xr-x | lib/pure/strutils.nim | 112 | ||||
-rwxr-xr-x | rod/semtypes.nim | 3 | ||||
-rwxr-xr-x | todo.txt | 2 |
5 files changed, 94 insertions, 78 deletions
diff --git a/lib/impure/re.nim b/lib/impure/re.nim index a3fb86332..bce786087 100755 --- a/lib/impure/re.nim +++ b/lib/impure/re.nim @@ -55,7 +55,7 @@ proc rawCompile(pattern: string, flags: cint): PPcre = return com proc finalizeRegEx(x: TRegEx) = - # XXX This is a hack, but PCRE does not export it's "free" function properly. + # XXX This is a hack, but PCRE does not export its "free" function properly. # Sigh. The hack relies on PCRE's implementation (see ``pcre_get.c``). # Fortunately the implementation is unlikely to change. pcre.free_substring(cast[cstring](x.h)) diff --git a/lib/pure/httpserver.nim b/lib/pure/httpserver.nim index bb7f42a7a..0f18f7569 100755 --- a/lib/pure/httpserver.nim +++ b/lib/pure/httpserver.nim @@ -23,7 +23,7 @@ ## run(handleRequest, TPort(80)) ## -import strutils, os, osproc, strtabs, streams, sockets +import parseutils, strutils, os, osproc, strtabs, streams, sockets const wwwNL* = "\r\L" @@ -76,9 +76,9 @@ proc unimplemented(client: TSocket) = proc discardHeaders(client: TSocket) = skip(client) -proc serveFile(client: TSocket, filename: string) = - discardHeaders(client) - +proc serveFile*(client: TSocket, filename: string) = + ## serves a file to the client. + when false: discardHeaders(client) var f: TFile if open(f, filename): headers(client, filename) @@ -231,19 +231,33 @@ proc next*(s: var TServer) = ## proceed to the first/next request. s.client = accept(s.socket) headers(s.client, "") - var buf = "" - discard recvLine(s.client, buf) - var data = buf.split() - if cmpIgnoreCase(data[0], "GET") == 0 or cmpIgnoreCase(data[0], "POST") == 0: - var q = find(data[1], '?') - if q >= 0: - s.query = data[1].copy(q+1) - s.path = data[1].copy(0, q-1) - else: - s.query = "" - s.path = data[1] - else: + var data = recv(s.client) + #discard recvLine(s.client, data) + + var i = 0 + if skipIgnoreCase(data, "GET") > 0: i = 3 + elif skipIgnoreCase(data, "POST") > 0: i = 4 + elif data.len == 0: + # Google Chrome sends an empty line first? the web is ugly ... + nil + else: unimplemented(s.client) + return + + var L = skipWhitespace(data, i) + inc(i, L) + # XXX we ignore "HTTP/1.1" etc. for now here + var query = 0 + var last = i + while last < data.len and data[last] notin whitespace: + if data[last] == '?' and query == 0: query = last + inc(last) + if query > 0: + s.query = data.copy(query+1, last-1) + s.path = data.copy(i, query-1) + else: + s.query = "" + s.path = data.copy(i, last-1) proc close*(s: TServer) = ## closes the server (and the socket the server uses). @@ -254,7 +268,7 @@ proc run*(handleRequest: proc (client: TSocket, path, query: string): bool, ## encapsulates the server object and main loop var s: TServer open(s, port) - #echo("httpserver running on port ", s.port) + echo("httpserver running on port ", s.port) while true: next(s) if handleRequest(s.client, s.path, s.query): break @@ -265,8 +279,9 @@ when isMainModule: var counter = 0 proc handleRequest(client: TSocket, path, query: string): bool {.procvar.} = inc(counter) - client.send("Hello, Andreas, for the $#th time." % $counter & wwwNL) + client.send("Hello, Andreas, for the $#th time. $# ? $#" % [ + $counter, path, query] & wwwNL) return false # do not stop processing - run(handleRequest, TPort(80)) + run(handleRequest, TPort(0)) diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index c794b5a74..76ea068df 100755 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -935,60 +935,60 @@ proc editDistance*(a, b: string): int {.noSideEffect, row[p] = x result = row[e] #dealloc(row) - - -# floating point formating: - -proc c_sprintf(buf, frmt: CString) {.nodecl, importc: "sprintf", varargs, - noSideEffect.} - -type - TFloatFormat* = enum - ffDefault, ## use the shorter floating point notation - ffDecimal, ## use decimal floating point notation - ffScientific ## use scientific notation (using ``e``) character - -proc formatBiggestFloat*(f: BiggestFloat, format: TFloatFormat = ffDefault, + + +# floating point formating: + +proc c_sprintf(buf, frmt: CString) {.nodecl, importc: "sprintf", varargs, + noSideEffect.} + +type + TFloatFormat* = enum + ffDefault, ## use the shorter floating point notation + ffDecimal, ## use decimal floating point notation + ffScientific ## use scientific notation (using ``e``) character + +proc formatBiggestFloat*(f: BiggestFloat, format: TFloatFormat = ffDefault, precision = 16): string {.noSideEffect, - rtl, extern: "nsu$1".} = - ## converts a floating point value `f` to a string. - ## - ## If ``format == ffDecimal`` then precision is the number of digits to - ## be printed after the decimal point. - ## If ``format == ffScientific`` then precision is the maximum number - ## of significant digits to be printed. - ## `precision`'s default value is the maximum number of meaningful digits - ## after the decimal point for Nimrod's ``biggestFloat`` type. - const floatFormatToChar: array[TFloatFormat, char] = ['g', 'f', 'e'] - var - frmtstr: array[0..5, char] - buf: array[0..80, char] - frmtstr[0] = '%' - frmtstr[1] = '#' - if precision > 0: - frmtstr[2] = '.' - frmtstr[3] = '*' - frmtstr[4] = floatFormatToChar[format] - frmtstr[5] = '\0' - c_sprintf(buf, frmtstr, precision, f) - else: - frmtstr[2] = floatFormatToChar[format] - frmtstr[3] = '\0' - c_sprintf(buf, frmtstr, f) - result = $buf - -proc formatFloat*(f: float, format: TFloatFormat = ffDefault, + rtl, extern: "nsu$1".} = + ## converts a floating point value `f` to a string. + ## + ## If ``format == ffDecimal`` then precision is the number of digits to + ## be printed after the decimal point. + ## If ``format == ffScientific`` then precision is the maximum number + ## of significant digits to be printed. + ## `precision`'s default value is the maximum number of meaningful digits + ## after the decimal point for Nimrod's ``biggestFloat`` type. + const floatFormatToChar: array[TFloatFormat, char] = ['g', 'f', 'e'] + var + frmtstr: array[0..5, char] + buf: array[0..80, char] + frmtstr[0] = '%' + frmtstr[1] = '#' + if precision > 0: + frmtstr[2] = '.' + frmtstr[3] = '*' + frmtstr[4] = floatFormatToChar[format] + frmtstr[5] = '\0' + c_sprintf(buf, frmtstr, precision, f) + else: + frmtstr[2] = floatFormatToChar[format] + frmtstr[3] = '\0' + c_sprintf(buf, frmtstr, f) + result = $buf + +proc formatFloat*(f: float, format: TFloatFormat = ffDefault, precision = 16): string {.noSideEffect, - rtl, extern: "nsu$1".} = - ## converts a floating point value `f` to a string. - ## - ## If ``format == ffDecimal`` then precision is the number of digits to - ## be printed after the decimal point. - ## If ``format == ffScientific`` then precision is the maximum number - ## of significant digits to be printed. - ## `precision`'s default value is the maximum number of meaningful digits - ## after the decimal point for Nimrod's ``float`` type. - result = formatBiggestFloat(f, format, precision) + rtl, extern: "nsu$1".} = + ## converts a floating point value `f` to a string. + ## + ## If ``format == ffDecimal`` then precision is the number of digits to + ## be printed after the decimal point. + ## If ``format == ffScientific`` then precision is the maximum number + ## of significant digits to be printed. + ## `precision`'s default value is the maximum number of meaningful digits + ## after the decimal point for Nimrod's ``float`` type. + result = formatBiggestFloat(f, format, precision) {.pop.} @@ -998,7 +998,7 @@ when isMainModule: assert align("1232", 6) == " 1232" echo wordWrap(""" this is a long text -- muchlongerthan10chars and here it goes""", 10, false) - assert formatBiggestFloat(0.00000000001, ffDecimal, 11) == "0.00000000001" - assert formatBiggestFloat(0.00000000001, ffScientific, 1) == "1.0e-11" - - + assert formatBiggestFloat(0.00000000001, ffDecimal, 11) == "0.00000000001" + assert formatBiggestFloat(0.00000000001, ffScientific, 1) == "1.0e-11" + + diff --git a/rod/semtypes.nim b/rod/semtypes.nim index ccba76a21..52766f174 100755 --- a/rod/semtypes.nim +++ b/rod/semtypes.nim @@ -627,7 +627,8 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = of nkBlockType: result = semBlockType(c, n, prev) else: - liMessage(n.info, errTypeExpected) #internalError(n.info, 'semTypeNode(' +{&} nodeKindToStr[n.kind] +{&} ')'); + liMessage(n.info, errTypeExpected) + #internalError(n.info, 'semTypeNode(' +{&} nodeKindToStr[n.kind] +{&} ')'); proc setMagicType(m: PSym, kind: TTypeKind, size: int) = m.typ.kind = kind diff --git a/todo.txt b/todo.txt index cf50f4144..d7cc384fb 100755 --- a/todo.txt +++ b/todo.txt @@ -26,7 +26,6 @@ To implement * sort routine * hash tables and sets -* the two other parsers * distinct types for array/seq indexes * constant sequences @@ -98,6 +97,7 @@ Version 2 type PWindow = ref TWindow not nil +- the two other parsers Low priority |