mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-10 05:38:10 +00:00
enable style:usages for stdlib tests [backport: 1.6] (#19715)
* enable style:usages for stdlib tests * freeAddrInfo * more tests * importc * bufSize * fix more * => parseSql and renderSql
This commit is contained in:
@@ -150,17 +150,17 @@ proc tryExec*(db: DbConn, query: SqlQuery, args: varargs[string, `$`]): bool {.
|
||||
tags: [ReadDbEffect, WriteDbEffect].} =
|
||||
## tries to execute the query and returns true if successful, false otherwise.
|
||||
var q = dbFormat(query, args)
|
||||
return mysql.realQuery(PMySQL db, q, q.len) == 0'i32
|
||||
return mysql.real_query(PMySQL db, q, q.len) == 0'i32
|
||||
|
||||
proc rawExec(db: DbConn, query: SqlQuery, args: varargs[string, `$`]) =
|
||||
var q = dbFormat(query, args)
|
||||
if mysql.realQuery(PMySQL db, q, q.len) != 0'i32: dbError(db)
|
||||
if mysql.real_query(PMySQL db, q, q.len) != 0'i32: dbError(db)
|
||||
|
||||
proc exec*(db: DbConn, query: SqlQuery, args: varargs[string, `$`]) {.
|
||||
tags: [ReadDbEffect, WriteDbEffect].} =
|
||||
## executes the query and raises EDB if not successful.
|
||||
var q = dbFormat(query, args)
|
||||
if mysql.realQuery(PMySQL db, q, q.len) != 0'i32: dbError(db)
|
||||
if mysql.real_query(PMySQL db, q, q.len) != 0'i32: dbError(db)
|
||||
|
||||
proc newRow(L: int): Row =
|
||||
newSeq(result, L)
|
||||
@@ -168,7 +168,7 @@ proc newRow(L: int): Row =
|
||||
|
||||
proc properFreeResult(sqlres: mysql.PRES, row: cstringArray) =
|
||||
if row != nil:
|
||||
while mysql.fetchRow(sqlres) != nil: discard
|
||||
while mysql.fetch_row(sqlres) != nil: discard
|
||||
mysql.freeResult(sqlres)
|
||||
|
||||
iterator fastRows*(db: DbConn, query: SqlQuery,
|
||||
@@ -190,7 +190,7 @@ iterator fastRows*(db: DbConn, query: SqlQuery,
|
||||
backup: Row
|
||||
newSeq(result, L)
|
||||
while true:
|
||||
row = mysql.fetchRow(sqlres)
|
||||
row = mysql.fetch_row(sqlres)
|
||||
if row == nil: break
|
||||
for i in 0..L-1:
|
||||
setLen(result[i], 0)
|
||||
@@ -209,7 +209,7 @@ iterator instantRows*(db: DbConn, query: SqlQuery,
|
||||
let L = int(mysql.numFields(sqlres))
|
||||
var row: cstringArray
|
||||
while true:
|
||||
row = mysql.fetchRow(sqlres)
|
||||
row = mysql.fetch_row(sqlres)
|
||||
if row == nil: break
|
||||
yield InstantRow(row: row, len: L)
|
||||
properFreeResult(sqlres, row)
|
||||
@@ -290,7 +290,7 @@ iterator instantRows*(db: DbConn; columns: var DbColumns; query: SqlQuery;
|
||||
setColumnInfo(columns, sqlres, L)
|
||||
var row: cstringArray
|
||||
while true:
|
||||
row = mysql.fetchRow(sqlres)
|
||||
row = mysql.fetch_row(sqlres)
|
||||
if row == nil: break
|
||||
yield InstantRow(row: row, len: L)
|
||||
properFreeResult(sqlres, row)
|
||||
@@ -317,7 +317,7 @@ proc getRow*(db: DbConn, query: SqlQuery,
|
||||
if sqlres != nil:
|
||||
var L = int(mysql.numFields(sqlres))
|
||||
result = newRow(L)
|
||||
var row = mysql.fetchRow(sqlres)
|
||||
var row = mysql.fetch_row(sqlres)
|
||||
if row != nil:
|
||||
for i in 0..L-1:
|
||||
setLen(result[i], 0)
|
||||
@@ -335,7 +335,7 @@ proc getAllRows*(db: DbConn, query: SqlQuery,
|
||||
var row: cstringArray
|
||||
var j = 0
|
||||
while true:
|
||||
row = mysql.fetchRow(sqlres)
|
||||
row = mysql.fetch_row(sqlres)
|
||||
if row == nil: break
|
||||
setLen(result, j+1)
|
||||
newSeq(result[j], L)
|
||||
@@ -361,7 +361,7 @@ proc tryInsertId*(db: DbConn, query: SqlQuery,
|
||||
## executes the query (typically "INSERT") and returns the
|
||||
## generated ID for the row or -1 in case of an error.
|
||||
var q = dbFormat(query, args)
|
||||
if mysql.realQuery(PMySQL db, q, q.len) != 0'i32:
|
||||
if mysql.real_query(PMySQL db, q, q.len) != 0'i32:
|
||||
result = -1'i64
|
||||
else:
|
||||
result = mysql.insertId(PMySQL db)
|
||||
|
||||
@@ -1016,7 +1016,7 @@ proc endhostent*() {.importc, header: "<netdb.h>".}
|
||||
proc endnetent*() {.importc, header: "<netdb.h>".}
|
||||
proc endprotoent*() {.importc, header: "<netdb.h>".}
|
||||
proc endservent*() {.importc, header: "<netdb.h>".}
|
||||
proc freeaddrinfo*(a1: ptr AddrInfo) {.importc, header: "<netdb.h>".}
|
||||
proc freeAddrInfo*(a1: ptr AddrInfo) {.importc: "freeaddrinfo", header: "<netdb.h>".}
|
||||
|
||||
proc gai_strerror*(a1: cint): cstring {.importc:"(char *)$1", header: "<netdb.h>".}
|
||||
|
||||
|
||||
@@ -1791,7 +1791,7 @@ template asyncAddrInfoLoop(addrInfo: ptr AddrInfo, fd: untyped,
|
||||
curAddrInfo = curAddrInfo.ai_next
|
||||
|
||||
if curAddrInfo == nil:
|
||||
freeaddrinfo(addrInfo)
|
||||
freeAddrInfo(addrInfo)
|
||||
when shouldCreateFd:
|
||||
closeUnusedFds()
|
||||
if lastException != nil:
|
||||
@@ -1807,7 +1807,7 @@ template asyncAddrInfoLoop(addrInfo: ptr AddrInfo, fd: untyped,
|
||||
try:
|
||||
curFd = createAsyncNativeSocket(domain, sockType, protocol)
|
||||
except:
|
||||
freeaddrinfo(addrInfo)
|
||||
freeAddrInfo(addrInfo)
|
||||
closeUnusedFds()
|
||||
raise getCurrentException()
|
||||
when defined(windows):
|
||||
@@ -1817,7 +1817,7 @@ template asyncAddrInfoLoop(addrInfo: ptr AddrInfo, fd: untyped,
|
||||
doConnect(curFd, curAddrInfo).callback = tryNextAddrInfo
|
||||
curAddrInfo = curAddrInfo.ai_next
|
||||
else:
|
||||
freeaddrinfo(addrInfo)
|
||||
freeAddrInfo(addrInfo)
|
||||
when shouldCreateFd:
|
||||
closeUnusedFds(ord(domain))
|
||||
retFuture.complete(curFd)
|
||||
|
||||
@@ -648,9 +648,9 @@ proc bindAddr*(socket: AsyncSocket, port = Port(0), address = "") {.
|
||||
|
||||
var aiList = getAddrInfo(realaddr, port, socket.domain)
|
||||
if bindAddr(socket.fd, aiList.ai_addr, aiList.ai_addrlen.SockLen) < 0'i32:
|
||||
freeaddrinfo(aiList)
|
||||
freeAddrInfo(aiList)
|
||||
raiseOSError(osLastError())
|
||||
freeaddrinfo(aiList)
|
||||
freeAddrInfo(aiList)
|
||||
|
||||
proc hasDataBuffered*(s: AsyncSocket): bool {.since: (1, 5).} =
|
||||
## Determines whether an AsyncSocket has data buffered.
|
||||
@@ -859,7 +859,7 @@ proc sendTo*(socket: AsyncSocket, address: string, port: Port, data: string,
|
||||
|
||||
it = it.ai_next
|
||||
|
||||
freeaddrinfo(aiList)
|
||||
freeAddrInfo(aiList)
|
||||
|
||||
if not success:
|
||||
if lastException != nil:
|
||||
|
||||
@@ -75,4 +75,4 @@ proc setCookie*(key, value: string, expires: DateTime|Time,
|
||||
## `Set-Cookie: key=value; Domain=...; ...`
|
||||
result = setCookie(key, value, domain, path,
|
||||
format(expires.utc, "ddd',' dd MMM yyyy HH:mm:ss 'GMT'"),
|
||||
noname, secure, httpOnly, maxAge, sameSite)
|
||||
noName, secure, httpOnly, maxAge, sameSite)
|
||||
|
||||
@@ -526,4 +526,4 @@ template withData*[T](s: Selector[T], fd: SocketHandle|int, value, body1,
|
||||
body2
|
||||
|
||||
proc getFd*[T](s: Selector[T]): int =
|
||||
return s.epollFd.int
|
||||
return s.epollFD.int
|
||||
|
||||
@@ -26,27 +26,27 @@ else:
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>"""
|
||||
type
|
||||
Fdset {.importc: "fd_set", header: platformHeaders, pure, final.} = object
|
||||
FdSet {.importc: "fd_set", header: platformHeaders, pure, final.} = object
|
||||
var
|
||||
FD_SETSIZE {.importc: "FD_SETSIZE", header: platformHeaders.}: cint
|
||||
|
||||
proc IOFD_SET(fd: SocketHandle, fdset: ptr Fdset)
|
||||
proc IOFD_SET(fd: SocketHandle, fdset: ptr FdSet)
|
||||
{.cdecl, importc: "FD_SET", header: platformHeaders, inline.}
|
||||
proc IOFD_CLR(fd: SocketHandle, fdset: ptr Fdset)
|
||||
proc IOFD_CLR(fd: SocketHandle, fdset: ptr FdSet)
|
||||
{.cdecl, importc: "FD_CLR", header: platformHeaders, inline.}
|
||||
proc IOFD_ZERO(fdset: ptr Fdset)
|
||||
proc IOFD_ZERO(fdset: ptr FdSet)
|
||||
{.cdecl, importc: "FD_ZERO", header: platformHeaders, inline.}
|
||||
|
||||
when defined(windows):
|
||||
proc IOFD_ISSET(fd: SocketHandle, fdset: ptr Fdset): cint
|
||||
proc IOFD_ISSET(fd: SocketHandle, fdset: ptr FdSet): cint
|
||||
{.stdcall, importc: "FD_ISSET", header: platformHeaders, inline.}
|
||||
proc ioselect(nfds: cint, readFds, writeFds, exceptFds: ptr Fdset,
|
||||
proc ioselect(nfds: cint, readFds, writeFds, exceptFds: ptr FdSet,
|
||||
timeout: ptr Timeval): cint
|
||||
{.stdcall, importc: "select", header: platformHeaders.}
|
||||
else:
|
||||
proc IOFD_ISSET(fd: SocketHandle, fdset: ptr Fdset): cint
|
||||
proc IOFD_ISSET(fd: SocketHandle, fdset: ptr FdSet): cint
|
||||
{.cdecl, importc: "FD_ISSET", header: platformHeaders, inline.}
|
||||
proc ioselect(nfds: cint, readFds, writeFds, exceptFds: ptr Fdset,
|
||||
proc ioselect(nfds: cint, readFds, writeFds, exceptFds: ptr FdSet,
|
||||
timeout: ptr Timeval): cint
|
||||
{.cdecl, importc: "select", header: platformHeaders.}
|
||||
|
||||
|
||||
@@ -958,12 +958,12 @@ proc parseJson*(s: Stream, filename: string = ""; rawIntegers = false, rawFloats
|
||||
|
||||
when defined(js):
|
||||
from math import `mod`
|
||||
from std/jsffi import JSObject, `[]`, to
|
||||
from std/jsffi import JsObject, `[]`, to
|
||||
from std/private/jsutils import getProtoName, isInteger, isSafeInteger
|
||||
|
||||
proc parseNativeJson(x: cstring): JSObject {.importjs: "JSON.parse(#)".}
|
||||
proc parseNativeJson(x: cstring): JsObject {.importjs: "JSON.parse(#)".}
|
||||
|
||||
proc getVarType(x: JSObject, isRawNumber: var bool): JsonNodeKind =
|
||||
proc getVarType(x: JsObject, isRawNumber: var bool): JsonNodeKind =
|
||||
result = JNull
|
||||
case $getProtoName(x) # TODO: Implicit returns fail here.
|
||||
of "[object Array]": return JArray
|
||||
@@ -982,12 +982,12 @@ when defined(js):
|
||||
of "[object String]": return JString
|
||||
else: assert false
|
||||
|
||||
proc len(x: JSObject): int =
|
||||
proc len(x: JsObject): int =
|
||||
asm """
|
||||
`result` = `x`.length;
|
||||
"""
|
||||
|
||||
proc convertObject(x: JSObject): JsonNode =
|
||||
proc convertObject(x: JsObject): JsonNode =
|
||||
var isRawNumber = false
|
||||
case getVarType(x, isRawNumber)
|
||||
of JArray:
|
||||
@@ -1000,7 +1000,7 @@ when defined(js):
|
||||
if (`x`.hasOwnProperty(property)) {
|
||||
"""
|
||||
var nimProperty: cstring
|
||||
var nimValue: JSObject
|
||||
var nimValue: JsObject
|
||||
asm "`nimProperty` = property; `nimValue` = `x`[property];"
|
||||
result[$nimProperty] = nimValue.convertObject()
|
||||
asm "}}"
|
||||
|
||||
@@ -633,8 +633,8 @@ when useNimNetLite:
|
||||
INET_ADDRSTRLEN = 16
|
||||
INET6_ADDRSTRLEN = 46 # it's actually 46 in both cases
|
||||
|
||||
proc sockAddrToStr(sa: ptr Sockaddr): string {.noinit.} =
|
||||
let af_family = sa.sa_family
|
||||
proc sockAddrToStr(sa: ptr SockAddr): string {.noinit.} =
|
||||
let af_family = sa.sa_family
|
||||
var nl, v4Slice: cint
|
||||
var si_addr: ptr InAddr
|
||||
|
||||
|
||||
@@ -984,11 +984,11 @@ proc bindAddr*(socket: Socket, port = Port(0), address = "") {.
|
||||
|
||||
var aiList = getAddrInfo(realaddr, port, socket.domain)
|
||||
if bindAddr(socket.fd, aiList.ai_addr, aiList.ai_addrlen.SockLen) < 0'i32:
|
||||
freeaddrinfo(aiList)
|
||||
freeAddrInfo(aiList)
|
||||
var address2: string
|
||||
address2.addQuoted address
|
||||
raiseOSError(osLastError(), "address: $# port: $#" % [address2, $port])
|
||||
freeaddrinfo(aiList)
|
||||
freeAddrInfo(aiList)
|
||||
|
||||
proc acceptAddr*(server: Socket, client: var owned(Socket), address: var string,
|
||||
flags = {SocketFlag.SafeDisconn},
|
||||
@@ -1745,7 +1745,7 @@ proc sendTo*(socket: Socket, address: string, port: Port, data: pointer,
|
||||
it = it.ai_next
|
||||
|
||||
let osError = osLastError()
|
||||
freeaddrinfo(aiList)
|
||||
freeAddrInfo(aiList)
|
||||
|
||||
if not success:
|
||||
raiseOSError(osError)
|
||||
@@ -1960,7 +1960,7 @@ proc dial*(address: string, port: Port,
|
||||
# network system problem (e.g. not enough FDs), and not an unreachable
|
||||
# address.
|
||||
let err = osLastError()
|
||||
freeaddrinfo(aiList)
|
||||
freeAddrInfo(aiList)
|
||||
closeUnusedFds()
|
||||
raiseOSError(err)
|
||||
fdPerDomain[ord(domain)] = lastFd
|
||||
@@ -1969,7 +1969,7 @@ proc dial*(address: string, port: Port,
|
||||
break
|
||||
lastError = osLastError()
|
||||
it = it.ai_next
|
||||
freeaddrinfo(aiList)
|
||||
freeAddrInfo(aiList)
|
||||
closeUnusedFds(ord(domain))
|
||||
|
||||
if success:
|
||||
@@ -1999,7 +1999,7 @@ proc connect*(socket: Socket, address: string,
|
||||
else: lastError = osLastError()
|
||||
it = it.ai_next
|
||||
|
||||
freeaddrinfo(aiList)
|
||||
freeAddrInfo(aiList)
|
||||
if not success: raiseOSError(lastError)
|
||||
|
||||
when defineSsl:
|
||||
@@ -2051,7 +2051,7 @@ proc connectAsync(socket: Socket, name: string, port = Port(0),
|
||||
|
||||
it = it.ai_next
|
||||
|
||||
freeaddrinfo(aiList)
|
||||
freeAddrInfo(aiList)
|
||||
if not success: raiseOSError(lastError)
|
||||
|
||||
proc connect*(socket: Socket, address: string, port = Port(0),
|
||||
|
||||
@@ -1451,7 +1451,7 @@ proc ra(n: SqlNode, s: var SqlWriter) =
|
||||
s.addKeyw("enum")
|
||||
rs(n, s)
|
||||
|
||||
proc renderSQL*(n: SqlNode, upperCase = false): string =
|
||||
proc renderSql*(n: SqlNode, upperCase = false): string =
|
||||
## Converts an SQL abstract syntax tree to its string representation.
|
||||
var s: SqlWriter
|
||||
s.buffer = ""
|
||||
@@ -1460,8 +1460,8 @@ proc renderSQL*(n: SqlNode, upperCase = false): string =
|
||||
return s.buffer
|
||||
|
||||
proc `$`*(n: SqlNode): string =
|
||||
## an alias for `renderSQL`.
|
||||
renderSQL(n)
|
||||
## an alias for `renderSql`.
|
||||
renderSql(n)
|
||||
|
||||
proc treeReprAux(s: SqlNode, level: int, result: var string) =
|
||||
result.add('\n')
|
||||
@@ -1493,7 +1493,7 @@ proc open(p: var SqlParser, input: Stream, filename: string) =
|
||||
p.tok.literal = ""
|
||||
getTok(p)
|
||||
|
||||
proc parseSQL*(input: Stream, filename: string): SqlNode =
|
||||
proc parseSql*(input: Stream, filename: string): SqlNode =
|
||||
## parses the SQL from `input` into an AST and returns the AST.
|
||||
## `filename` is only used for error messages.
|
||||
## Syntax errors raise an `SqlParseError` exception.
|
||||
@@ -1504,8 +1504,8 @@ proc parseSQL*(input: Stream, filename: string): SqlNode =
|
||||
finally:
|
||||
close(p)
|
||||
|
||||
proc parseSQL*(input: string, filename = ""): SqlNode =
|
||||
proc parseSql*(input: string, filename = ""): SqlNode =
|
||||
## parses the SQL from `input` into an AST and returns the AST.
|
||||
## `filename` is only used for error messages.
|
||||
## Syntax errors raise an `SqlParseError` exception.
|
||||
parseSQL(newStringStream(input), "")
|
||||
parseSql(newStringStream(input), "")
|
||||
|
||||
@@ -1023,7 +1023,7 @@ template eventParser*(pegAst, handlers: untyped): (proc(s: string): int) =
|
||||
## Symbols declared in an *enter* handler can be made visible in the
|
||||
## corresponding *leave* handler by annotating them with an *inject* pragma.
|
||||
proc rawParse(s: string, p: Peg, start: int, c: var Captures): int
|
||||
{.genSym.} =
|
||||
{.gensym.} =
|
||||
|
||||
# binding from *macros*
|
||||
bind strVal
|
||||
@@ -1058,7 +1058,7 @@ template eventParser*(pegAst, handlers: untyped): (proc(s: string): int) =
|
||||
matchOrParse(parseIt)
|
||||
parseIt(s, p, start, c)
|
||||
|
||||
proc parser(s: string): int {.genSym.} =
|
||||
proc parser(s: string): int {.gensym.} =
|
||||
# the proc to be returned
|
||||
var
|
||||
ms: array[MaxSubpatterns, (int, int)]
|
||||
|
||||
@@ -30,7 +30,7 @@ when defined(windows):
|
||||
|
||||
const
|
||||
EXCEPTION_ACCESS_VIOLATION = DWORD(0xc0000005'i32)
|
||||
EXCEPTION_CONTINUE_SEARCH = Long(0)
|
||||
EXCEPTION_CONTINUE_SEARCH = LONG(0)
|
||||
|
||||
type
|
||||
PEXCEPTION_RECORD = ptr object
|
||||
|
||||
@@ -46,7 +46,7 @@ func setSlice*(s: var string, slice: Slice[int]) =
|
||||
import std/sugar
|
||||
|
||||
var a = "Hello, Nim!"
|
||||
doassert a.dup(setSlice(7 .. 9)) == "Nim"
|
||||
doAssert a.dup(setSlice(7 .. 9)) == "Nim"
|
||||
doAssert a.dup(setSlice(0 .. 0)) == "H"
|
||||
doAssert a.dup(setSlice(0 .. 1)) == "He"
|
||||
doAssert a.dup(setSlice(0 .. 10)) == a
|
||||
|
||||
@@ -85,7 +85,7 @@ template checkIsolate(scratchAssignList: seq[NimNode], procParam, scratchDotExpr
|
||||
# var isoTempB = isolate(literal)
|
||||
# scratch.b = extract(isolateB)
|
||||
let isolatedTemp = genSym(nskTemp, "isoTemp")
|
||||
scratchAssignList.add newVarStmt(isolatedTemp, newCall(newidentNode("isolate"), procParam))
|
||||
scratchAssignList.add newVarStmt(isolatedTemp, newCall(newIdentNode("isolate"), procParam))
|
||||
scratchAssignList.add newAssignment(scratchDotExpr,
|
||||
newCall(newIdentNode("extract"), isolatedTemp))
|
||||
|
||||
|
||||
@@ -46,26 +46,26 @@ template call(f) =
|
||||
proc getUnicodeValue*(path, key: string; handle: HKEY): string =
|
||||
let hh = newWideCString path
|
||||
let kk = newWideCString key
|
||||
var bufsize: int32
|
||||
var bufSize: int32
|
||||
# try a couple of different flag settings:
|
||||
var flags: int32 = RRF_RT_ANY
|
||||
let err = regGetValue(handle, hh, kk, flags, nil, nil, addr bufsize)
|
||||
let err = regGetValue(handle, hh, kk, flags, nil, nil, addr bufSize)
|
||||
if err != 0:
|
||||
var newHandle: HKEY
|
||||
call regOpenKeyEx(handle, hh, 0, KEY_READ or KEY_WOW64_64KEY, newHandle)
|
||||
call regGetValue(newHandle, nil, kk, flags, nil, nil, addr bufsize)
|
||||
call regGetValue(newHandle, nil, kk, flags, nil, nil, addr bufSize)
|
||||
if bufSize > 0:
|
||||
var res = newWideCString(bufsize)
|
||||
var res = newWideCString(bufSize)
|
||||
call regGetValue(newHandle, nil, kk, flags, nil, addr res[0],
|
||||
addr bufsize)
|
||||
result = res $ bufsize
|
||||
addr bufSize)
|
||||
result = res $ bufSize
|
||||
call regCloseKey(newHandle)
|
||||
else:
|
||||
if bufSize > 0:
|
||||
var res = newWideCString(bufsize)
|
||||
var res = newWideCString(bufSize)
|
||||
call regGetValue(handle, hh, kk, flags, nil, addr res[0],
|
||||
addr bufsize)
|
||||
result = res $ bufsize
|
||||
addr bufSize)
|
||||
result = res $ bufSize
|
||||
|
||||
proc regSetValue(key: HKEY, lpSubKey, lpValueName: WideCString,
|
||||
dwType: int32; lpData: WideCString; cbData: int32): int32 {.
|
||||
|
||||
@@ -670,7 +670,7 @@ proc getaddrinfo*(nodename, servname: cstring, hints: ptr AddrInfo,
|
||||
res: var ptr AddrInfo): cint {.
|
||||
stdcall, importc: "getaddrinfo", dynlib: ws2dll.}
|
||||
|
||||
proc freeaddrinfo*(ai: ptr AddrInfo) {.
|
||||
proc freeAddrInfo*(ai: ptr AddrInfo) {.
|
||||
stdcall, importc: "freeaddrinfo", dynlib: ws2dll.}
|
||||
|
||||
proc inet_ntoa*(i: InAddr): cstring {.
|
||||
|
||||
Reference in New Issue
Block a user