mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-07 05:23:20 +00:00
Merge /home/cb/pkg/nim/Nim into devel
pull from master
This commit is contained in:
@@ -460,7 +460,7 @@ type
|
||||
|
||||
TLineInfo*{.final.} = object # This is designed to be as small as possible,
|
||||
# because it is used
|
||||
# in syntax nodes. We safe space here by using
|
||||
# in syntax nodes. We save space here by using
|
||||
# two int16 and an int32.
|
||||
# On 64 bit and on 32 bit systems this is
|
||||
# only 8 bytes.
|
||||
|
||||
@@ -14,7 +14,7 @@ import
|
||||
options, idents, wordrecg, strtabs
|
||||
|
||||
# ---------------- configuration file parser -----------------------------
|
||||
# we use Nim's scanner here to safe space and work
|
||||
# we use Nim's scanner here to save space and work
|
||||
|
||||
proc ppGetTok(L: var TLexer, tok: var TToken) =
|
||||
# simple filter
|
||||
@@ -158,7 +158,7 @@ proc checkSymbol(L: TLexer, tok: TToken) =
|
||||
proc parseAssignment(L: var TLexer, tok: var TToken) =
|
||||
if tok.ident.id == getIdent("-").id or tok.ident.id == getIdent("--").id:
|
||||
confTok(L, tok) # skip unnecessary prefix
|
||||
var info = getLineInfo(L, tok) # safe for later in case of an error
|
||||
var info = getLineInfo(L, tok) # save for later in case of an error
|
||||
checkSymbol(L, tok)
|
||||
var s = tokToStr(tok)
|
||||
confTok(L, tok) # skip symbol
|
||||
@@ -252,6 +252,11 @@ proc loadConfigs*(cfg: string) =
|
||||
|
||||
if gProjectName.len != 0:
|
||||
# new project wide config file:
|
||||
let projectConfig = changeFileExt(gProjectFull, "nim.cfg")
|
||||
if fileExists(projectConfig): readConfigFile(projectConfig)
|
||||
else: readConfigFile(changeFileExt(gProjectFull, "nimrod.cfg"))
|
||||
var projectConfig = changeFileExt(gProjectFull, "nimcfg")
|
||||
if not fileExists(projectConfig):
|
||||
projectConfig = changeFileExt(gProjectFull, "nim.cfg")
|
||||
if not fileExists(projectConfig):
|
||||
projectConfig = changeFileExt(gProjectFull, "nimrod.cfg")
|
||||
if fileExists(projectConfig):
|
||||
rawMessage(warnDeprecated, projectConfig)
|
||||
readConfigFile(projectConfig)
|
||||
|
||||
@@ -31,9 +31,27 @@ when defined(Windows):
|
||||
stdout.write(prompt)
|
||||
result = readLine(stdin, line)
|
||||
|
||||
proc getch(): cint {.header: "<conio.h>", importc: "_getch".}
|
||||
|
||||
proc readPasswordFromStdin*(prompt: string, password: var TaintedString) =
|
||||
## Reads a `password` from stdin without printing it. `password` must not
|
||||
## be ``nil``!
|
||||
password.setLen(0)
|
||||
var c: char
|
||||
echo prompt
|
||||
while true:
|
||||
c = getch().char
|
||||
case c
|
||||
of '\r', chr(0xA):
|
||||
break
|
||||
of '\b':
|
||||
password.setLen(result.len - 1)
|
||||
else:
|
||||
password.add(c)
|
||||
|
||||
else:
|
||||
import readline, history
|
||||
|
||||
import readline, history, termios, unsigned
|
||||
|
||||
proc readLineFromStdin*(prompt: string): TaintedString {.
|
||||
tags: [ReadIOEffect, WriteIOEffect].} =
|
||||
var buffer = readline.readLine(prompt)
|
||||
@@ -55,8 +73,24 @@ else:
|
||||
result = true
|
||||
|
||||
# initialization:
|
||||
# disable auto-complete:
|
||||
# disable auto-complete:
|
||||
proc doNothing(a, b: cint): cint {.cdecl, procvar.} = discard
|
||||
|
||||
|
||||
discard readline.bind_key('\t'.ord, doNothing)
|
||||
|
||||
proc readPasswordFromStdin*(prompt: string, password: var TaintedString) =
|
||||
password.setLen(0)
|
||||
let fd = stdin.getFileHandle()
|
||||
var cur, old: Termios
|
||||
discard fd.tcgetattr(cur.addr)
|
||||
old = cur
|
||||
cur.lflag = cur.lflag and not Tcflag(ECHO)
|
||||
discard fd.tcsetattr(TCSADRAIN, cur.addr)
|
||||
stdout.write prompt
|
||||
discard stdin.readLine(password)
|
||||
discard fd.tcsetattr(TCSADRAIN, old.addr)
|
||||
|
||||
proc readPasswordFromStdin*(prompt: string): TaintedString =
|
||||
## Reads a password from stdin without printing it.
|
||||
result = TaintedString("")
|
||||
readPasswordFromStdin(prompt, result)
|
||||
|
||||
264
lib/posix/termios.nim
Normal file
264
lib/posix/termios.nim
Normal file
@@ -0,0 +1,264 @@
|
||||
#
|
||||
#
|
||||
# Nim's Runtime Library
|
||||
# (c) Copyright 2015 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
{.deadCodeElim: on.}
|
||||
import posix
|
||||
|
||||
type
|
||||
Speed* = cuint
|
||||
Tcflag* = cuint
|
||||
|
||||
const
|
||||
NCCS* = 32
|
||||
|
||||
type
|
||||
Termios* = object {.importc: "struct termios", header: "<termios.h>", final, pure.}
|
||||
iflag*: Tcflag # input mode flags
|
||||
oflag*: Tcflag # output mode flags
|
||||
cflag*: Tcflag # control mode flags
|
||||
lflag*: Tcflag # local mode flags
|
||||
line*: cuchar # line discipline
|
||||
cc*: array[NCCS, cuchar] # control characters
|
||||
ispeed*: Speed # input speed
|
||||
ospeed*: Speed # output speed
|
||||
|
||||
|
||||
# cc characters
|
||||
|
||||
const
|
||||
VINTR* = 0
|
||||
VQUIT* = 1
|
||||
VERASE* = 2
|
||||
VKILL* = 3
|
||||
VEOF* = 4
|
||||
VTIME* = 5
|
||||
VMIN* = 6
|
||||
VSWTC* = 7
|
||||
VSTART* = 8
|
||||
VSTOP* = 9
|
||||
VSUSP* = 10
|
||||
VEOL* = 11
|
||||
VREPRINT* = 12
|
||||
VDISCARD* = 13
|
||||
VWERASE* = 14
|
||||
VLNEXT* = 15
|
||||
VEOL2* = 16
|
||||
|
||||
# iflag bits
|
||||
|
||||
const
|
||||
IGNBRK* = 1
|
||||
BRKINT* = 2
|
||||
IGNPAR* = 4
|
||||
PARMRK* = 10
|
||||
INPCK* = 20
|
||||
ISTRIP* = 40
|
||||
INLCR* = 100
|
||||
IGNCR* = 200
|
||||
ICRNL* = 400
|
||||
IUCLC* = 1000
|
||||
IXON* = 2000
|
||||
IXANY* = 4000
|
||||
IXOFF* = 10000
|
||||
IMAXBEL* = 20000
|
||||
IUTF8* = 40000
|
||||
|
||||
# oflag bits
|
||||
|
||||
const
|
||||
OPOST* = 1
|
||||
OLCUC* = 2
|
||||
ONLCR* = 4
|
||||
OCRNL* = 10
|
||||
ONOCR* = 20
|
||||
ONLRET* = 40
|
||||
OFILL* = 100
|
||||
OFDEL* = 200
|
||||
NLDLY* = 400
|
||||
NL0* = 0
|
||||
NL1* = 400
|
||||
CRDLY* = 3000
|
||||
CR0* = 0
|
||||
CR1* = 1000
|
||||
CR2* = 2000
|
||||
CR3* = 3000
|
||||
TABDLY* = 14000
|
||||
TAB0* = 0
|
||||
TAB1* = 4000
|
||||
TAB2* = 10000
|
||||
TAB3* = 14000
|
||||
BSDLY* = 20000
|
||||
BS0* = 0
|
||||
BS1* = 20000
|
||||
FFDLY* = 0o000000100000
|
||||
FF0* = 0
|
||||
FF1* = 0o000000100000
|
||||
VTDLY* = 40000
|
||||
VT0* = 0
|
||||
VT1* = 40000
|
||||
XTABS* = 14000
|
||||
|
||||
# cflag bit meaning
|
||||
|
||||
const
|
||||
CBAUD* = 10017
|
||||
B0* = 0
|
||||
B50* = 1
|
||||
B75* = 2
|
||||
B110* = 3
|
||||
B134* = 4
|
||||
B150* = 5
|
||||
B200* = 6
|
||||
B300* = 7
|
||||
B600* = 10
|
||||
B1200* = 11
|
||||
B1800* = 12
|
||||
B2400* = 13
|
||||
B4800* = 14
|
||||
B9600* = 15
|
||||
B19200* = 16
|
||||
B38400* = 17
|
||||
EXTA* = B19200
|
||||
EXTB* = B38400
|
||||
CSIZE* = 60
|
||||
CS5* = 0
|
||||
CS6* = 20
|
||||
CS7* = 40
|
||||
CS8* = 60
|
||||
CSTOPB* = 100
|
||||
CREAD* = 200
|
||||
PARENB* = 400
|
||||
PARODD* = 1000
|
||||
HUPCL* = 2000
|
||||
CLOCAL* = 4000
|
||||
CBAUDEX* = 10000
|
||||
B57600* = 10001
|
||||
B115200* = 10002
|
||||
B230400* = 10003
|
||||
B460800* = 10004
|
||||
B500000* = 10005
|
||||
B576000* = 10006
|
||||
B921600* = 10007
|
||||
B1000000* = 10010
|
||||
B1152000* = 10011
|
||||
B1500000* = 10012
|
||||
B2000000* = 10013
|
||||
B2500000* = 10014
|
||||
B3000000* = 10015
|
||||
B3500000* = 10016
|
||||
B4000000* = 10017
|
||||
MAX_BAUD* = B4000000
|
||||
CIBAUD* = 2003600000
|
||||
CMSPAR* = 0o010000000000
|
||||
CRTSCTS* = 0o020000000000
|
||||
|
||||
# lflag bits
|
||||
|
||||
const
|
||||
ISIG* = 1
|
||||
ICANON* = 2
|
||||
XCASE* = 4
|
||||
ECHO* = 10
|
||||
ECHOE* = 20
|
||||
ECHOK* = 40
|
||||
ECHONL* = 100
|
||||
NOFLSH* = 200
|
||||
TOSTOP* = 400
|
||||
ECHOCTL* = 1000
|
||||
ECHOPRT* = 2000
|
||||
ECHOKE* = 4000
|
||||
FLUSHO* = 10000
|
||||
PENDIN* = 40000
|
||||
IEXTEN* = 0o000000100000
|
||||
EXTPROC* = 0o000000200000
|
||||
|
||||
# tcflow() and TCXONC use these
|
||||
|
||||
const
|
||||
TCOOFF* = 0
|
||||
TCOON* = 1
|
||||
TCIOFF* = 2
|
||||
TCION* = 3
|
||||
|
||||
# tcflush() and TCFLSH use these
|
||||
|
||||
const
|
||||
TCIFLUSH* = 0
|
||||
TCOFLUSH* = 1
|
||||
TCIOFLUSH* = 2
|
||||
|
||||
# tcsetattr uses these
|
||||
|
||||
const
|
||||
TCSANOW* = 0
|
||||
TCSADRAIN* = 1
|
||||
TCSAFLUSH* = 2
|
||||
|
||||
# Compare a character C to a value VAL from the `cc' array in a
|
||||
# `struct termios'. If VAL is _POSIX_VDISABLE, no character can match it.
|
||||
|
||||
template cceq*(val, c: expr): expr =
|
||||
c == val and val != POSIX_VDISABLE
|
||||
|
||||
# Return the output baud rate stored in *TERMIOS_P.
|
||||
|
||||
proc cfGetOspeed*(termios: ptr Termios): Speed {.importc: "cfgetospeed",
|
||||
header: "<termios.h>".}
|
||||
# Return the input baud rate stored in *TERMIOS_P.
|
||||
|
||||
proc cfGetIspeed*(termios: ptr Termios): Speed {.importc: "cfgetispeed",
|
||||
header: "<termios.h>".}
|
||||
# Set the output baud rate stored in *TERMIOS_P to SPEED.
|
||||
|
||||
proc cfSetOspeed*(termios: ptr Termios; speed: Speed): cint {.
|
||||
importc: "cfsetospeed", header: "<termios.h>".}
|
||||
# Set the input baud rate stored in *TERMIOS_P to SPEED.
|
||||
|
||||
proc cfSetIspeed*(termios: ptr Termios; speed: Speed): cint {.
|
||||
importc: "cfsetispeed", header: "<termios.h>".}
|
||||
# Set both the input and output baud rates in *TERMIOS_OP to SPEED.
|
||||
|
||||
proc cfSetSpeed*(termios: ptr Termios; speed: Speed): cint {.
|
||||
importc: "cfsetspeed", header: "<termios.h>".}
|
||||
# Put the state of FD into *TERMIOS_P.
|
||||
|
||||
proc tcGetAttr*(fd: cint; termios: ptr Termios): cint {.
|
||||
importc: "tcgetattr", header: "<termios.h>".}
|
||||
# Set the state of FD to *TERMIOS_P.
|
||||
# Values for OPTIONAL_ACTIONS (TCSA*) are in <bits/termios.h>.
|
||||
|
||||
proc tcSetAttr*(fd: cint; optional_actions: cint; termios: ptr Termios): cint {.
|
||||
importc: "tcsetattr", header: "<termios.h>".}
|
||||
# Set *TERMIOS_P to indicate raw mode.
|
||||
|
||||
proc cfMakeRaw*(termios: ptr Termios) {.importc: "cfmakeraw",
|
||||
header: "<termios.h>".}
|
||||
# Send zero bits on FD.
|
||||
|
||||
proc tcSendBreak*(fd: cint; duration: cint): cint {.importc: "tcsendbreak",
|
||||
header: "<termios.h>".}
|
||||
# Wait for pending output to be written on FD.
|
||||
#
|
||||
# This function is a cancellation point and therefore not marked with
|
||||
# .
|
||||
|
||||
proc tcDrain*(fd: cint): cint {.importc: "tcdrain", header: "<termios.h>".}
|
||||
# Flush pending data on FD.
|
||||
# Values for QUEUE_SELECTOR (TC{I,O,IO}FLUSH) are in <bits/termios.h>.
|
||||
|
||||
proc tcFlush*(fd: cint; queue_selector: cint): cint {.importc: "tcflush",
|
||||
header: "<termios.h>".}
|
||||
# Suspend or restart transmission on FD.
|
||||
# Values for ACTION (TC[IO]{OFF,ON}) are in <bits/termios.h>.
|
||||
|
||||
proc tcFlow*(fd: cint; action: cint): cint {.importc: "tcflow",
|
||||
header: "<termios.h>".}
|
||||
# Get process group ID for session leader for controlling terminal FD.
|
||||
|
||||
proc tcGetSid*(fd: cint): TPid {.importc: "tcgetsid", header: "<termios.h>".}
|
||||
@@ -30,9 +30,28 @@
|
||||
##
|
||||
## 1.3000000000000000e+00
|
||||
## true
|
||||
##
|
||||
## This module can also be used to comfortably create JSON using the `%*`
|
||||
## operator:
|
||||
##
|
||||
## .. code-block:: nim
|
||||
##
|
||||
## var hisName = "John"
|
||||
## let herAge = 31
|
||||
## var j = %*
|
||||
## [
|
||||
## {
|
||||
## "name": hisName,
|
||||
## "age": 30
|
||||
## },
|
||||
## {
|
||||
## "name": "Susan",
|
||||
## "age": herAge
|
||||
## }
|
||||
## ]
|
||||
|
||||
import
|
||||
hashes, strutils, lexbase, streams, unicode
|
||||
hashes, strutils, lexbase, streams, unicode, macros
|
||||
|
||||
type
|
||||
JsonEventKind* = enum ## enumeration of all events that may occur when parsing
|
||||
@@ -625,6 +644,29 @@ proc `%`*(elements: openArray[JsonNode]): JsonNode =
|
||||
newSeq(result.elems, elements.len)
|
||||
for i, p in pairs(elements): result.elems[i] = p
|
||||
|
||||
proc toJson(x: PNimrodNode): PNimrodNode {.compiletime.} =
|
||||
case x.kind
|
||||
of nnkBracket:
|
||||
result = newNimNode(nnkBracket)
|
||||
for i in 0 .. <x.len:
|
||||
result.add(toJson(x[i]))
|
||||
|
||||
of nnkTableConstr:
|
||||
result = newNimNode(nnkTableConstr)
|
||||
for i in 0 .. <x.len:
|
||||
assert x[i].kind == nnkExprColonExpr
|
||||
result.add(newNimNode(nnkExprColonExpr).add(x[i][0]).add(toJson(x[i][1])))
|
||||
|
||||
else:
|
||||
result = x
|
||||
|
||||
result = prefix(result, "%")
|
||||
|
||||
macro `%*`*(x: expr): expr =
|
||||
## Convert an expression to a JsonNode directly, without having to specify
|
||||
## `%` for every element.
|
||||
result = toJson(x)
|
||||
|
||||
proc `==`* (a,b: JsonNode): bool =
|
||||
## Check two nodes for equality
|
||||
if a.isNil:
|
||||
@@ -864,7 +906,7 @@ proc pretty*(node: JsonNode, indent = 2): string =
|
||||
proc `$`*(node: JsonNode): string =
|
||||
## Converts `node` to its JSON Representation on one line.
|
||||
result = ""
|
||||
toPretty(result, node, 1, false)
|
||||
toPretty(result, node, 0, false)
|
||||
|
||||
iterator items*(node: JsonNode): JsonNode =
|
||||
## Iterator for the items of `node`. `node` has to be a JArray.
|
||||
@@ -1101,6 +1143,37 @@ when isMainModule:
|
||||
except:
|
||||
assert(false, "EInvalidIndex thrown for valid index")
|
||||
|
||||
# Generator:
|
||||
var j = %* [{"name": "John", "age": 30}, {"name": "Susan", "age": 31}]
|
||||
assert j == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}]
|
||||
|
||||
var j2 = %*
|
||||
[
|
||||
{
|
||||
"name": "John",
|
||||
"age": 30
|
||||
},
|
||||
{
|
||||
"name": "Susan",
|
||||
"age": 31
|
||||
}
|
||||
]
|
||||
assert j2 == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}]
|
||||
|
||||
var name = "John"
|
||||
let herAge = 30
|
||||
const hisAge = 31
|
||||
|
||||
var j3 = %*
|
||||
[ { "name": "John"
|
||||
, "age": herAge
|
||||
}
|
||||
, { "name": "Susan"
|
||||
, "age": hisAge
|
||||
}
|
||||
]
|
||||
assert j3 == %[%{"name": %"John", "age": %30}, %{"name": %"Susan", "age": %31}]
|
||||
|
||||
discard """
|
||||
while true:
|
||||
var json = stdin.readLine()
|
||||
|
||||
@@ -343,10 +343,10 @@ type
|
||||
##
|
||||
## Each exception has to inherit from `Exception`. See the full `exception
|
||||
## hierarchy`_.
|
||||
parent: ref Exception ## parent exception (can be used as a stack)
|
||||
name: cstring ## The exception's name is its Nim identifier.
|
||||
## This field is filled automatically in the
|
||||
## ``raise`` statement.
|
||||
parent*: ref Exception ## parent exception (can be used as a stack)
|
||||
name: cstring ## The exception's name is its Nim identifier.
|
||||
## This field is filled automatically in the
|
||||
## ``raise`` statement.
|
||||
msg* {.exportc: "message".}: string ## the exception's message. Not
|
||||
## providing an exception message
|
||||
## is bad style.
|
||||
|
||||
Reference in New Issue
Block a user