fixed the file inclusion error in the go wrappers
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
20ddd12c89
commit
3953a8e404
36
go/cb.go
36
go/cb.go
@ -10,6 +10,7 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"sync"
|
"sync"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
@ -103,13 +104,13 @@ func hcl_go_cci_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.in
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ioarg.includer == nil || ioarg.includer.name == nil {
|
if ioarg.includer == nil || ioarg.includer.name == nil {
|
||||||
includer_name = ""
|
includer_name = g.io.cci_main
|
||||||
} else {
|
} else {
|
||||||
var k []rune = ucstr_to_rune_slice(ioarg.includer.name)
|
var k []rune = ucstr_to_rune_slice(ioarg.includer.name)
|
||||||
includer_name = string(k)
|
includer_name = string(k)
|
||||||
}
|
}
|
||||||
|
|
||||||
fd, err = g.io.r.Open(g, name, includer_name)
|
fd, err = g.io.cci.Open(g, name, includer_name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
g.set_errmsg(C.HCL_EIOERR, err.Error())
|
g.set_errmsg(C.HCL_EIOERR, err.Error())
|
||||||
return -1
|
return -1
|
||||||
@ -120,7 +121,7 @@ func hcl_go_cci_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.in
|
|||||||
|
|
||||||
case C.HCL_IO_CLOSE:
|
case C.HCL_IO_CLOSE:
|
||||||
var ioarg *C.hcl_io_cciarg_t = (*C.hcl_io_cciarg_t)(arg)
|
var ioarg *C.hcl_io_cciarg_t = (*C.hcl_io_cciarg_t)(arg)
|
||||||
g.io.r.Close(int(uintptr(ioarg.handle)))
|
g.io.cci.Close(int(uintptr(ioarg.handle)))
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
case C.HCL_IO_READ:
|
case C.HCL_IO_READ:
|
||||||
@ -133,7 +134,7 @@ func hcl_go_cci_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.in
|
|||||||
ioarg = (*C.hcl_io_cciarg_t)(arg)
|
ioarg = (*C.hcl_io_cciarg_t)(arg)
|
||||||
|
|
||||||
buf = make([]rune, 1024) // TODO: different size...
|
buf = make([]rune, 1024) // TODO: different size...
|
||||||
n, err = g.io.r.Read(int(uintptr(ioarg.handle)), buf)
|
n, err = g.io.cci.Read(int(uintptr(ioarg.handle)), buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
g.set_errmsg(C.HCL_EIOERR, err.Error())
|
g.set_errmsg(C.HCL_EIOERR, err.Error())
|
||||||
return -1
|
return -1
|
||||||
@ -161,7 +162,7 @@ func hcl_go_udi_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.in
|
|||||||
|
|
||||||
switch cmd {
|
switch cmd {
|
||||||
case C.HCL_IO_OPEN:
|
case C.HCL_IO_OPEN:
|
||||||
err = g.io.s.Open(g)
|
err = g.io.udi.Open(g)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
g.set_errmsg(C.HCL_EIOERR, err.Error())
|
g.set_errmsg(C.HCL_EIOERR, err.Error())
|
||||||
return -1
|
return -1
|
||||||
@ -172,7 +173,7 @@ func hcl_go_udi_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.in
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
case C.HCL_IO_CLOSE:
|
case C.HCL_IO_CLOSE:
|
||||||
g.io.s.Close()
|
g.io.udi.Close()
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
case C.HCL_IO_READ:
|
case C.HCL_IO_READ:
|
||||||
@ -185,7 +186,7 @@ func hcl_go_udi_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.in
|
|||||||
ioarg = (*C.hcl_io_udiarg_t)(arg)
|
ioarg = (*C.hcl_io_udiarg_t)(arg)
|
||||||
|
|
||||||
buf = make([]rune, 1024) // TODO: different size...
|
buf = make([]rune, 1024) // TODO: different size...
|
||||||
n, err = g.io.s.Read(buf)
|
n, err = g.io.udi.Read(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
g.set_errmsg(C.HCL_EIOERR, err.Error())
|
g.set_errmsg(C.HCL_EIOERR, err.Error())
|
||||||
return -1
|
return -1
|
||||||
@ -209,7 +210,7 @@ func hcl_go_udo_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.in
|
|||||||
|
|
||||||
switch cmd {
|
switch cmd {
|
||||||
case C.HCL_IO_OPEN:
|
case C.HCL_IO_OPEN:
|
||||||
err = g.io.p.Open(g)
|
err = g.io.udo.Open(g)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
g.set_errmsg(C.HCL_EIOERR, err.Error())
|
g.set_errmsg(C.HCL_EIOERR, err.Error())
|
||||||
return -1
|
return -1
|
||||||
@ -220,7 +221,7 @@ func hcl_go_udo_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.in
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
case C.HCL_IO_CLOSE:
|
case C.HCL_IO_CLOSE:
|
||||||
g.io.p.Close()
|
g.io.udo.Close()
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
case C.HCL_IO_WRITE:
|
case C.HCL_IO_WRITE:
|
||||||
@ -231,7 +232,7 @@ func hcl_go_udo_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.in
|
|||||||
)
|
)
|
||||||
ioarg = (*C.hcl_io_udoarg_t)(arg)
|
ioarg = (*C.hcl_io_udoarg_t)(arg)
|
||||||
data = uchars_to_rune_slice((*C.hcl_uch_t)(ioarg.ptr), uintptr(ioarg.len))
|
data = uchars_to_rune_slice((*C.hcl_uch_t)(ioarg.ptr), uintptr(ioarg.len))
|
||||||
err = g.io.p.Write(data)
|
err = g.io.udo.Write(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
g.set_errmsg(C.HCL_EIOERR, err.Error())
|
g.set_errmsg(C.HCL_EIOERR, err.Error())
|
||||||
return -1
|
return -1
|
||||||
@ -247,7 +248,7 @@ func hcl_go_udo_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.in
|
|||||||
)
|
)
|
||||||
ioarg = (*C.hcl_io_udoarg_t)(arg)
|
ioarg = (*C.hcl_io_udoarg_t)(arg)
|
||||||
data = unsafe.Slice((*byte)(ioarg.ptr), ioarg.len)
|
data = unsafe.Slice((*byte)(ioarg.ptr), ioarg.len)
|
||||||
err = g.io.p.WriteBytes(data)
|
err = g.io.udo.WriteBytes(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
g.set_errmsg(C.HCL_EIOERR, err.Error())
|
g.set_errmsg(C.HCL_EIOERR, err.Error())
|
||||||
return -1
|
return -1
|
||||||
@ -256,7 +257,7 @@ func hcl_go_udo_handler(c *C.hcl_t, cmd C.hcl_io_cmd_t, arg unsafe.Pointer) C.in
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
case C.HCL_IO_FLUSH:
|
case C.HCL_IO_FLUSH:
|
||||||
var err error = g.io.p.Flush()
|
var err error = g.io.udo.Flush()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
g.set_errmsg(C.HCL_EIOERR, err.Error())
|
g.set_errmsg(C.HCL_EIOERR, err.Error())
|
||||||
return -1
|
return -1
|
||||||
@ -284,7 +285,14 @@ func (p *CciFileHandler) Open(g *HCL, name string, includer_name string) (int, e
|
|||||||
if name == "" {
|
if name == "" {
|
||||||
f = os.Stdin
|
f = os.Stdin
|
||||||
} else {
|
} else {
|
||||||
f, err = os.Open(name)
|
var dir string
|
||||||
|
|
||||||
|
dir = path.Dir(includer_name)
|
||||||
|
if dir != "/" && dir != "" {
|
||||||
|
dir = dir + "/"
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err = os.Open(dir + name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
@ -377,7 +385,7 @@ func (p *UdiFileHandler) Read(buf []rune) (int, error) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// flush all pending print out before reading
|
// flush all pending print out before reading
|
||||||
p.g.io.p.Flush()
|
p.g.io.udo.Flush()
|
||||||
|
|
||||||
for i = 0; i < len(buf); i++ {
|
for i = 0; i < len(buf); i++ {
|
||||||
c, _, err = p.r.ReadRune()
|
c, _, err = p.r.ReadRune()
|
||||||
|
69
go/hcl.go
69
go/hcl.go
@ -3,7 +3,7 @@ package hcl
|
|||||||
/*
|
/*
|
||||||
#include <hcl.h>
|
#include <hcl.h>
|
||||||
#include <hcl-utl.h>
|
#include <hcl-utl.h>
|
||||||
#include <stdlib.h> // for C.freem
|
#include <stdlib.h> // for C.free
|
||||||
|
|
||||||
extern int hcl_go_cci_handler (hcl_t hcl, hcl_io_cmd_t cmd, void* arg);
|
extern int hcl_go_cci_handler (hcl_t hcl, hcl_io_cmd_t cmd, void* arg);
|
||||||
extern int hcl_go_udi_handler (hcl_t hcl, hcl_io_cmd_t cmd, void* arg);
|
extern int hcl_go_udi_handler (hcl_t hcl, hcl_io_cmd_t cmd, void* arg);
|
||||||
@ -30,19 +30,19 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
type IOReadImpl interface {
|
type CciImpl interface {
|
||||||
Open(g *HCL, name string, includer_name string) (int, error)
|
Open(g *HCL, name string, includer_name string) (int, error)
|
||||||
Close(fd int)
|
Close(fd int)
|
||||||
Read(fd int, buf []rune) (int, error)
|
Read(fd int, buf []rune) (int, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type IOScanImpl interface {
|
type UdiImpl interface {
|
||||||
Open(g *HCL) error
|
Open(g *HCL) error
|
||||||
Close()
|
Close()
|
||||||
Read(buf []rune) (int, error)
|
Read(buf []rune) (int, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type IOPrintImpl interface {
|
type UdoImpl interface {
|
||||||
Open(g *HCL) error
|
Open(g *HCL) error
|
||||||
Close()
|
Close()
|
||||||
Write(data []rune) error
|
Write(data []rune) error
|
||||||
@ -50,16 +50,15 @@ type IOPrintImpl interface {
|
|||||||
Flush() error
|
Flush() error
|
||||||
}
|
}
|
||||||
|
|
||||||
type IOImplSet struct {
|
|
||||||
r IOReadImpl
|
|
||||||
s IOScanImpl
|
|
||||||
p IOPrintImpl
|
|
||||||
}
|
|
||||||
|
|
||||||
type HCL struct {
|
type HCL struct {
|
||||||
c *C.hcl_t
|
c *C.hcl_t
|
||||||
inst_no int
|
inst_no int
|
||||||
io IOImplSet
|
io struct {
|
||||||
|
cci CciImpl
|
||||||
|
cci_main string
|
||||||
|
udi UdiImpl
|
||||||
|
udo UdoImpl
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Ext struct {
|
type Ext struct {
|
||||||
@ -126,7 +125,7 @@ func (hcl *HCL) GetLogMask () BitMask {
|
|||||||
func (hcl *HCL) SetLogMask(log_mask BitMask) {
|
func (hcl *HCL) SetLogMask(log_mask BitMask) {
|
||||||
var x C.int
|
var x C.int
|
||||||
|
|
||||||
x = C.hcl_setoption(hcl.c, C.HCL_LOG_MASK, unsafe.Pointer(&log_mask));
|
x = C.hcl_setoption(hcl.c, C.HCL_LOG_MASK, unsafe.Pointer(&log_mask))
|
||||||
if x <= -1 {
|
if x <= -1 {
|
||||||
// this must not happen
|
// this must not happen
|
||||||
panic(fmt.Errorf("unable to set log mask - %s", hcl.get_errmsg()))
|
panic(fmt.Errorf("unable to set log mask - %s", hcl.get_errmsg()))
|
||||||
@ -137,7 +136,7 @@ func (hcl *HCL) GetLogTarget () string {
|
|||||||
var x C.int
|
var x C.int
|
||||||
var tgt *C.char
|
var tgt *C.char
|
||||||
|
|
||||||
x = C.hcl_getoption(hcl.c, C.HCL_LOG_TARGET_BCSTR, unsafe.Pointer(&tgt));
|
x = C.hcl_getoption(hcl.c, C.HCL_LOG_TARGET_BCSTR, unsafe.Pointer(&tgt))
|
||||||
if x <= -1 {
|
if x <= -1 {
|
||||||
// this must not happen
|
// this must not happen
|
||||||
panic(fmt.Errorf("unable to set log target - %s", hcl.get_errmsg()))
|
panic(fmt.Errorf("unable to set log target - %s", hcl.get_errmsg()))
|
||||||
@ -153,7 +152,7 @@ func (hcl *HCL) SetLogTarget (target string) {
|
|||||||
tgt = C.CString(target)
|
tgt = C.CString(target)
|
||||||
defer C.free(unsafe.Pointer(tgt))
|
defer C.free(unsafe.Pointer(tgt))
|
||||||
|
|
||||||
x = C.hcl_setoption(hcl.c, C.HCL_LOG_TARGET_BCSTR, unsafe.Pointer(tgt));
|
x = C.hcl_setoption(hcl.c, C.HCL_LOG_TARGET_BCSTR, unsafe.Pointer(tgt))
|
||||||
if x <= -1 {
|
if x <= -1 {
|
||||||
// thist must not happen
|
// thist must not happen
|
||||||
panic(fmt.Errorf("unable to set log target - %s", hcl.get_errmsg()))
|
panic(fmt.Errorf("unable to set log target - %s", hcl.get_errmsg()))
|
||||||
@ -181,41 +180,49 @@ func (hcl *HCL) AddBuiltinPrims() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hcl *HCL) AttachCCIO(r IOReadImpl) error {
|
// the name of the main cci stream is required because:
|
||||||
|
// - the main stream is not handled by this IO handler
|
||||||
|
// - the feeder must read the main stream and pass data.
|
||||||
|
// - the inclusion of another file from the main stream requires the path information of the main strea.
|
||||||
|
func (hcl *HCL) AttachCCIO(cci CciImpl, main_cci_name string) error {
|
||||||
var x C.int
|
var x C.int
|
||||||
var or IOReadImpl
|
var old_cci CciImpl
|
||||||
|
var old_cci_name string
|
||||||
|
|
||||||
or = hcl.io.r
|
old_cci = hcl.io.cci
|
||||||
|
old_cci_name = hcl.io.cci_main
|
||||||
|
|
||||||
hcl.io.r = r
|
hcl.io.cci = cci
|
||||||
|
hcl.io.cci_main = main_cci_name
|
||||||
|
|
||||||
x = C.hcl_attachccio(hcl.c, C.hcl_io_impl_t(C.hcl_cci_Handler_for_go))
|
x = C.hcl_attachccio(hcl.c, C.hcl_io_impl_t(C.hcl_cci_Handler_for_go))
|
||||||
if x <= -1 {
|
if x <= -1 {
|
||||||
// restore the io handler set due to attachment failure
|
// restore the io handler set due to attachment failure
|
||||||
hcl.io.r = or
|
hcl.io.cci_main = old_cci_name
|
||||||
|
hcl.io.cci = old_cci
|
||||||
return fmt.Errorf("unable to attach source input stream handler - %s", hcl.get_errmsg())
|
return fmt.Errorf("unable to attach source input stream handler - %s", hcl.get_errmsg())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hcl *HCL) AttachUDIO(s IOScanImpl, p IOPrintImpl) error {
|
func (hcl *HCL) AttachUDIO(udi UdiImpl, udo UdoImpl) error {
|
||||||
var x C.int
|
var x C.int
|
||||||
var os IOScanImpl
|
var os UdiImpl
|
||||||
var op IOPrintImpl
|
var op UdoImpl
|
||||||
|
|
||||||
os = hcl.io.s
|
os = hcl.io.udi
|
||||||
op = hcl.io.p
|
op = hcl.io.udo
|
||||||
|
|
||||||
hcl.io.s = s
|
hcl.io.udi = udi
|
||||||
hcl.io.p = p
|
hcl.io.udo = udo
|
||||||
|
|
||||||
x = C.hcl_attachudio(hcl.c,
|
x = C.hcl_attachudio(hcl.c,
|
||||||
C.hcl_io_impl_t(C.hcl_udi_handler_for_go),
|
C.hcl_io_impl_t(C.hcl_udi_handler_for_go),
|
||||||
C.hcl_io_impl_t(C.hcl_udo_handler_for_go))
|
C.hcl_io_impl_t(C.hcl_udo_handler_for_go))
|
||||||
if x <= -1 {
|
if x <= -1 {
|
||||||
//restore the io handlers set due to attachment failure
|
//restore the io handlers set due to attachment failure
|
||||||
hcl.io.s = os
|
hcl.io.udi = os
|
||||||
hcl.io.p = op
|
hcl.io.udo = op
|
||||||
return fmt.Errorf("unable to attach user data stream handlers - %s", hcl.get_errmsg())
|
return fmt.Errorf("unable to attach user data stream handlers - %s", hcl.get_errmsg())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -281,7 +288,7 @@ func (hcl *HCL) FeedFromReader(rdr io.Reader) error {
|
|||||||
return fmt.Errorf("unable to read bytes - %s", err.Error())
|
return fmt.Errorf("unable to read bytes - %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
x = C.hcl_feedbchars(hcl.c, (*C.hcl_bch_t)(unsafe.Pointer(&buf[0])), C.hcl_oow_t(n));
|
x = C.hcl_feedbchars(hcl.c, (*C.hcl_bch_t)(unsafe.Pointer(&buf[0])), C.hcl_oow_t(n))
|
||||||
if x <= -1 {
|
if x <= -1 {
|
||||||
return fmt.Errorf("unable to feed bytes - %s", hcl.get_errmsg())
|
return fmt.Errorf("unable to feed bytes - %s", hcl.get_errmsg())
|
||||||
}
|
}
|
||||||
@ -294,7 +301,7 @@ func (hcl *HCL) FeedFromFile (file string) error {
|
|||||||
var f *os.File
|
var f *os.File
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
f, err = os.Open(file);
|
f, err = os.Open(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to open %s - %s", file, err.Error())
|
return fmt.Errorf("unable to open %s - %s", file, err.Error())
|
||||||
}
|
}
|
||||||
@ -363,7 +370,7 @@ func string_to_uchars (str string) []C.hcl_uch_t {
|
|||||||
var i int
|
var i int
|
||||||
|
|
||||||
// TODO: proper encoding
|
// TODO: proper encoding
|
||||||
r = []rune(str);
|
r = []rune(str)
|
||||||
c = make([]C.hcl_uch_t, len(r), len(r))
|
c = make([]C.hcl_uch_t, len(r), len(r))
|
||||||
for i = 0; i < len(r); i++ {
|
for i = 0; i < len(r); i++ {
|
||||||
c[i] = C.hcl_uch_t(r[i])
|
c[i] = C.hcl_uch_t(r[i])
|
||||||
|
8
main.go
8
main.go
@ -31,7 +31,7 @@ func handle_arguments(param *Param) error {
|
|||||||
for i = 1; i < nargs; i++ {
|
for i = 1; i < nargs; i++ {
|
||||||
if strings.HasPrefix(os.Args[i], "--log=") {
|
if strings.HasPrefix(os.Args[i], "--log=") {
|
||||||
param.log_file = os.Args[i][6:]
|
param.log_file = os.Args[i][6:]
|
||||||
} else if (os.Args[i] == "--log") {
|
} else if os.Args[i] == "--log" {
|
||||||
i++
|
i++
|
||||||
param.log_file = os.Args[i]
|
param.log_file = os.Args[i]
|
||||||
} else if strings.HasPrefix(os.Args[i], "--") || strings.HasPrefix(os.Args[i], "-") {
|
} else if strings.HasPrefix(os.Args[i], "--") || strings.HasPrefix(os.Args[i], "-") {
|
||||||
@ -59,7 +59,7 @@ func main() {
|
|||||||
var sfh hcl.UdiFileHandler
|
var sfh hcl.UdiFileHandler
|
||||||
var pfh hcl.UdoFileHandler
|
var pfh hcl.UdoFileHandler
|
||||||
|
|
||||||
err = handle_arguments(¶m);
|
err = handle_arguments(¶m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error: %s\n", err.Error())
|
fmt.Printf("Error: %s\n", err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@ -87,7 +87,7 @@ func main() {
|
|||||||
goto oops
|
goto oops
|
||||||
}
|
}
|
||||||
|
|
||||||
err = x.AttachCCIO(&rfh)
|
err = x.AttachCCIO(&rfh, param.input_file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error: %s\n", err.Error())
|
fmt.Printf("Error: %s\n", err.Error())
|
||||||
goto oops
|
goto oops
|
||||||
@ -99,7 +99,7 @@ func main() {
|
|||||||
goto oops
|
goto oops
|
||||||
}
|
}
|
||||||
|
|
||||||
err = x.BeginFeed();
|
err = x.BeginFeed()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error: %s\n", err.Error())
|
fmt.Printf("Error: %s\n", err.Error())
|
||||||
goto oops
|
goto oops
|
||||||
|
Loading…
Reference in New Issue
Block a user