mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-05-23 09:52:55 -06:00
the namespace iterator now takes a PgfExn parameter like in the old runtime
This commit is contained in:
@@ -239,13 +239,21 @@ size_t namespace_size(Namespace<V> map)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class V>
|
template <class V>
|
||||||
void namespace_iter(Namespace<V> map, PgfItor* itor)
|
void namespace_iter(Namespace<V> map, PgfItor* itor, PgfExn *err)
|
||||||
{
|
{
|
||||||
if (map == 0)
|
if (map == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
namespace_iter(map->left, itor);
|
namespace_iter(map->left, itor, err);
|
||||||
itor->fn(itor, &map->value->name, &(*map->value));
|
if (err->type != PGF_EXN_NONE)
|
||||||
namespace_iter(map->right, itor);
|
return;
|
||||||
|
|
||||||
|
itor->fn(itor, &map->value->name, &(*map->value), err);
|
||||||
|
if (err->type != PGF_EXN_NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
namespace_iter(map->right, itor, err);
|
||||||
|
if (err->type != PGF_EXN_NONE)
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -159,11 +159,12 @@ PgfText *pgf_abstract_name(PgfPGF* pgf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PGF_API
|
PGF_API
|
||||||
void pgf_iter_categories(PgfPGF *pgf, PgfItor *itor)
|
void pgf_iter_categories(PgfPGF *pgf, PgfItor *itor, PgfExn *err)
|
||||||
{
|
{
|
||||||
DB_scope scope(pgf, READER_SCOPE);
|
DB_scope scope(pgf, READER_SCOPE);
|
||||||
|
|
||||||
namespace_iter(pgf->get_root<PgfPGFRoot>()->abstract.cats, itor);
|
err->type = PGF_EXN_NONE;
|
||||||
|
namespace_iter(pgf->get_root<PgfPGFRoot>()->abstract.cats, itor, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
PGF_API
|
PGF_API
|
||||||
@@ -239,11 +240,12 @@ prob_t pgf_category_prob(PgfPGF *pgf, PgfText *catname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PGF_API
|
PGF_API
|
||||||
void pgf_iter_functions(PgfPGF *pgf, PgfItor *itor)
|
void pgf_iter_functions(PgfPGF *pgf, PgfItor *itor, PgfExn *err)
|
||||||
{
|
{
|
||||||
DB_scope scope(pgf, READER_SCOPE);
|
DB_scope scope(pgf, READER_SCOPE);
|
||||||
|
|
||||||
namespace_iter(pgf->get_root<PgfPGFRoot>()->abstract.funs, itor);
|
err->type = PGF_EXN_NONE;
|
||||||
|
namespace_iter(pgf->get_root<PgfPGFRoot>()->abstract.funs, itor, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PgfItorHelper : PgfItor
|
struct PgfItorHelper : PgfItor
|
||||||
@@ -253,16 +255,17 @@ struct PgfItorHelper : PgfItor
|
|||||||
};
|
};
|
||||||
|
|
||||||
static
|
static
|
||||||
void iter_by_cat_helper(PgfItor *itor, PgfText *key, void *value)
|
void iter_by_cat_helper(PgfItor *itor, PgfText *key, void *value,
|
||||||
|
PgfExn *err)
|
||||||
{
|
{
|
||||||
PgfItorHelper* helper = (PgfItorHelper*) itor;
|
PgfItorHelper* helper = (PgfItorHelper*) itor;
|
||||||
PgfAbsFun* absfun = (PgfAbsFun*) value;
|
PgfAbsFun* absfun = (PgfAbsFun*) value;
|
||||||
if (textcmp(helper->cat, &absfun->type->name) == 0)
|
if (textcmp(helper->cat, &absfun->type->name) == 0)
|
||||||
helper->itor->fn(helper->itor, key, value);
|
helper->itor->fn(helper->itor, key, value, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
PGF_API
|
PGF_API
|
||||||
void pgf_iter_functions_by_cat(PgfPGF *pgf, PgfText *cat, PgfItor *itor)
|
void pgf_iter_functions_by_cat(PgfPGF *pgf, PgfText *cat, PgfItor *itor, PgfExn *err)
|
||||||
{
|
{
|
||||||
DB_scope scope(pgf, READER_SCOPE);
|
DB_scope scope(pgf, READER_SCOPE);
|
||||||
|
|
||||||
@@ -270,7 +273,9 @@ void pgf_iter_functions_by_cat(PgfPGF *pgf, PgfText *cat, PgfItor *itor)
|
|||||||
helper.fn = iter_by_cat_helper;
|
helper.fn = iter_by_cat_helper;
|
||||||
helper.cat = cat;
|
helper.cat = cat;
|
||||||
helper.itor = itor;
|
helper.itor = itor;
|
||||||
namespace_iter(pgf->get_root<PgfPGFRoot>()->abstract.funs, &helper);
|
|
||||||
|
err->type = PGF_EXN_NONE;
|
||||||
|
namespace_iter(pgf->get_root<PgfPGFRoot>()->abstract.funs, &helper, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
PGF_API
|
PGF_API
|
||||||
|
|||||||
@@ -46,11 +46,41 @@ typedef struct {
|
|||||||
char text[];
|
char text[];
|
||||||
} PgfText;
|
} PgfText;
|
||||||
|
|
||||||
|
/* All functions that may fail take a reference to a PgfExn structure.
|
||||||
|
* It is used as follows:
|
||||||
|
*
|
||||||
|
* - If everything went fine, the field type will be equal to
|
||||||
|
* PGF_EXN_NONE and all other fields will be zeroed.
|
||||||
|
*
|
||||||
|
* - If the exception was caused by external factors such as an error
|
||||||
|
* from a system call, then type will be PGF_EXN_SYSTEM_ERROR and
|
||||||
|
* the field code will contain the value of errno from the C runtime.
|
||||||
|
*
|
||||||
|
* - If the exception was caused by factors related to the GF runtime
|
||||||
|
* itself, then the error type is PGF_EXN_PGF_ERROR, and the field
|
||||||
|
* msg will contain a newly allocated string which must be freed from
|
||||||
|
* the caller.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PGF_EXN_NONE,
|
||||||
|
PGF_EXN_SYSTEM_ERROR,
|
||||||
|
PGF_EXN_PGF_ERROR,
|
||||||
|
PGF_EXN_OTHER_ERROR
|
||||||
|
} PgfExnType;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PgfExnType type;
|
||||||
|
int code;
|
||||||
|
const char *msg;
|
||||||
|
} PgfExn;
|
||||||
|
|
||||||
/* A generic structure to pass a callback for iteration over a collection */
|
/* A generic structure to pass a callback for iteration over a collection */
|
||||||
typedef struct PgfItor PgfItor;
|
typedef struct PgfItor PgfItor;
|
||||||
|
|
||||||
struct PgfItor {
|
struct PgfItor {
|
||||||
void (*fn)(PgfItor* self, PgfText* key, void *value);
|
void (*fn)(PgfItor* self, PgfText* key, void *value,
|
||||||
|
PgfExn *err);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef uintptr_t object;
|
typedef uintptr_t object;
|
||||||
@@ -179,34 +209,6 @@ typedef float prob_t;
|
|||||||
|
|
||||||
typedef struct PgfPGF PgfPGF;
|
typedef struct PgfPGF PgfPGF;
|
||||||
|
|
||||||
/* All functions that may fail take a reference to a PgfExn structure.
|
|
||||||
* It is used as follows:
|
|
||||||
*
|
|
||||||
* - If everything went fine, the field type will be equal to
|
|
||||||
* PGF_EXN_NONE and all other fields will be zeroed.
|
|
||||||
*
|
|
||||||
* - If the exception was caused by external factors such as an error
|
|
||||||
* from a system call, then type will be PGF_EXN_SYSTEM_ERROR and
|
|
||||||
* the field code will contain the value of errno from the C runtime.
|
|
||||||
*
|
|
||||||
* - If the exception was caused by factors related to the GF runtime
|
|
||||||
* itself, then the error type is PGF_EXN_PGF_ERROR, and the field
|
|
||||||
* msg will contain a newly allocated string which must be freed from
|
|
||||||
* the caller.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
PGF_EXN_NONE,
|
|
||||||
PGF_EXN_SYSTEM_ERROR,
|
|
||||||
PGF_EXN_PGF_ERROR
|
|
||||||
} PgfExnType;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PgfExnType type;
|
|
||||||
int code;
|
|
||||||
const char *msg;
|
|
||||||
} PgfExn;
|
|
||||||
|
|
||||||
/* Reads a PGF file and keeps it in memory. */
|
/* Reads a PGF file and keeps it in memory. */
|
||||||
PGF_API_DECL
|
PGF_API_DECL
|
||||||
PgfPGF *pgf_read_pgf(const char* fpath,
|
PgfPGF *pgf_read_pgf(const char* fpath,
|
||||||
@@ -236,7 +238,7 @@ PGF_API_DECL
|
|||||||
PgfText *pgf_abstract_name(PgfPGF *pgf);
|
PgfText *pgf_abstract_name(PgfPGF *pgf);
|
||||||
|
|
||||||
PGF_API_DECL
|
PGF_API_DECL
|
||||||
void pgf_iter_categories(PgfPGF *pgf, PgfItor *itor);
|
void pgf_iter_categories(PgfPGF *pgf, PgfItor *itor, PgfExn *err);
|
||||||
|
|
||||||
PGF_API_DECL
|
PGF_API_DECL
|
||||||
PgfType pgf_start_cat(PgfPGF *pgf, PgfUnmarshaller *u);
|
PgfType pgf_start_cat(PgfPGF *pgf, PgfUnmarshaller *u);
|
||||||
@@ -248,10 +250,10 @@ PGF_API_DECL
|
|||||||
prob_t pgf_category_prob(PgfPGF* pgf, PgfText *catname);
|
prob_t pgf_category_prob(PgfPGF* pgf, PgfText *catname);
|
||||||
|
|
||||||
PGF_API_DECL
|
PGF_API_DECL
|
||||||
void pgf_iter_functions(PgfPGF *pgf, PgfItor *itor);
|
void pgf_iter_functions(PgfPGF *pgf, PgfItor *itor, PgfExn *err);
|
||||||
|
|
||||||
PGF_API_DECL
|
PGF_API_DECL
|
||||||
void pgf_iter_functions_by_cat(PgfPGF *pgf, PgfText *cat, PgfItor *itor);
|
void pgf_iter_functions_by_cat(PgfPGF *pgf, PgfText *cat, PgfItor *itor, PgfExn *err);
|
||||||
|
|
||||||
PGF_API_DECL
|
PGF_API_DECL
|
||||||
PgfType pgf_function_type(PgfPGF *pgf, PgfText *funname, PgfUnmarshaller *u);
|
PgfType pgf_function_type(PgfPGF *pgf, PgfText *funname, PgfUnmarshaller *u);
|
||||||
|
|||||||
@@ -187,15 +187,16 @@ categories p =
|
|||||||
unsafePerformIO $ do
|
unsafePerformIO $ do
|
||||||
ref <- newIORef []
|
ref <- newIORef []
|
||||||
(allocaBytes (#size PgfItor) $ \itor ->
|
(allocaBytes (#size PgfItor) $ \itor ->
|
||||||
|
allocaBytes (#size PgfExn) $ \c_exn ->
|
||||||
bracket (wrapItorCallback (getCategories ref)) freeHaskellFunPtr $ \fptr ->
|
bracket (wrapItorCallback (getCategories ref)) freeHaskellFunPtr $ \fptr ->
|
||||||
withForeignPtr (a_pgf p) $ \p_pgf -> do
|
withForeignPtr (a_pgf p) $ \p_pgf -> do
|
||||||
(#poke PgfItor, fn) itor fptr
|
(#poke PgfItor, fn) itor fptr
|
||||||
pgf_iter_categories p_pgf itor
|
pgf_iter_categories p_pgf itor c_exn
|
||||||
cs <- readIORef ref
|
cs <- readIORef ref
|
||||||
return (reverse cs))
|
return (reverse cs))
|
||||||
where
|
where
|
||||||
getCategories :: IORef [String] -> ItorCallback
|
getCategories :: IORef [String] -> ItorCallback
|
||||||
getCategories ref itor key = do
|
getCategories ref itor key exn = do
|
||||||
names <- readIORef ref
|
names <- readIORef ref
|
||||||
name <- peekText key
|
name <- peekText key
|
||||||
writeIORef ref $ (name : names)
|
writeIORef ref $ (name : names)
|
||||||
@@ -243,15 +244,16 @@ functions p =
|
|||||||
unsafePerformIO $ do
|
unsafePerformIO $ do
|
||||||
ref <- newIORef []
|
ref <- newIORef []
|
||||||
(allocaBytes (#size PgfItor) $ \itor ->
|
(allocaBytes (#size PgfItor) $ \itor ->
|
||||||
|
allocaBytes (#size PgfExn) $ \c_exn ->
|
||||||
bracket (wrapItorCallback (getFunctions ref)) freeHaskellFunPtr $ \fptr ->
|
bracket (wrapItorCallback (getFunctions ref)) freeHaskellFunPtr $ \fptr ->
|
||||||
withForeignPtr (a_pgf p) $ \p_pgf -> do
|
withForeignPtr (a_pgf p) $ \p_pgf -> do
|
||||||
(#poke PgfItor, fn) itor fptr
|
(#poke PgfItor, fn) itor fptr
|
||||||
pgf_iter_functions p_pgf itor
|
pgf_iter_functions p_pgf itor c_exn
|
||||||
fs <- readIORef ref
|
fs <- readIORef ref
|
||||||
return (reverse fs))
|
return (reverse fs))
|
||||||
where
|
where
|
||||||
getFunctions :: IORef [String] -> ItorCallback
|
getFunctions :: IORef [String] -> ItorCallback
|
||||||
getFunctions ref itor key = do
|
getFunctions ref itor key exn = do
|
||||||
names <- readIORef ref
|
names <- readIORef ref
|
||||||
name <- peekText key
|
name <- peekText key
|
||||||
writeIORef ref $ (name : names)
|
writeIORef ref $ (name : names)
|
||||||
@@ -263,15 +265,16 @@ functionsByCat p cat =
|
|||||||
ref <- newIORef []
|
ref <- newIORef []
|
||||||
(withText cat $ \c_cat ->
|
(withText cat $ \c_cat ->
|
||||||
allocaBytes (#size PgfItor) $ \itor ->
|
allocaBytes (#size PgfItor) $ \itor ->
|
||||||
|
allocaBytes (#size PgfExn) $ \c_exn ->
|
||||||
bracket (wrapItorCallback (getFunctions ref)) freeHaskellFunPtr $ \fptr ->
|
bracket (wrapItorCallback (getFunctions ref)) freeHaskellFunPtr $ \fptr ->
|
||||||
withForeignPtr (a_pgf p) $ \p_pgf -> do
|
withForeignPtr (a_pgf p) $ \p_pgf -> do
|
||||||
(#poke PgfItor, fn) itor fptr
|
(#poke PgfItor, fn) itor fptr
|
||||||
pgf_iter_functions_by_cat p_pgf c_cat itor
|
pgf_iter_functions_by_cat p_pgf c_cat itor c_exn
|
||||||
fs <- readIORef ref
|
fs <- readIORef ref
|
||||||
return (reverse fs))
|
return (reverse fs))
|
||||||
where
|
where
|
||||||
getFunctions :: IORef [String] -> ItorCallback
|
getFunctions :: IORef [String] -> ItorCallback
|
||||||
getFunctions ref itor key = do
|
getFunctions ref itor key exn = do
|
||||||
names <- readIORef ref
|
names <- readIORef ref
|
||||||
name <- peekText key
|
name <- peekText key
|
||||||
writeIORef ref $ (name : names)
|
writeIORef ref $ (name : names)
|
||||||
|
|||||||
@@ -68,13 +68,13 @@ foreign import ccall "pgf_print_type"
|
|||||||
foreign import ccall "pgf_read_type"
|
foreign import ccall "pgf_read_type"
|
||||||
pgf_read_type :: Ptr PgfText -> Ptr PgfUnmarshaller -> IO (StablePtr Type)
|
pgf_read_type :: Ptr PgfText -> Ptr PgfUnmarshaller -> IO (StablePtr Type)
|
||||||
|
|
||||||
type ItorCallback = Ptr PgfItor -> Ptr PgfText -> IO ()
|
type ItorCallback = Ptr PgfItor -> Ptr PgfText -> Ptr PgfExn -> IO ()
|
||||||
|
|
||||||
foreign import ccall "wrapper"
|
foreign import ccall "wrapper"
|
||||||
wrapItorCallback :: ItorCallback -> IO (FunPtr ItorCallback)
|
wrapItorCallback :: ItorCallback -> IO (FunPtr ItorCallback)
|
||||||
|
|
||||||
foreign import ccall "pgf_iter_categories"
|
foreign import ccall "pgf_iter_categories"
|
||||||
pgf_iter_categories :: Ptr PgfPGF -> Ptr PgfItor -> IO ()
|
pgf_iter_categories :: Ptr PgfPGF -> Ptr PgfItor -> Ptr PgfExn -> IO ()
|
||||||
|
|
||||||
foreign import ccall "pgf_start_cat"
|
foreign import ccall "pgf_start_cat"
|
||||||
pgf_start_cat :: Ptr PgfPGF -> Ptr PgfUnmarshaller -> IO (StablePtr Type)
|
pgf_start_cat :: Ptr PgfPGF -> Ptr PgfUnmarshaller -> IO (StablePtr Type)
|
||||||
@@ -86,10 +86,10 @@ foreign import ccall "pgf/pgf.h pgf_category_prob"
|
|||||||
pgf_category_prob :: Ptr PgfPGF -> Ptr PgfText -> IO (#type prob_t)
|
pgf_category_prob :: Ptr PgfPGF -> Ptr PgfText -> IO (#type prob_t)
|
||||||
|
|
||||||
foreign import ccall "pgf_iter_functions"
|
foreign import ccall "pgf_iter_functions"
|
||||||
pgf_iter_functions :: Ptr PgfPGF -> Ptr PgfItor -> IO ()
|
pgf_iter_functions :: Ptr PgfPGF -> Ptr PgfItor -> Ptr PgfExn -> IO ()
|
||||||
|
|
||||||
foreign import ccall "pgf_iter_functions_by_cat"
|
foreign import ccall "pgf_iter_functions_by_cat"
|
||||||
pgf_iter_functions_by_cat :: Ptr PgfPGF -> Ptr PgfText -> Ptr PgfItor -> IO ()
|
pgf_iter_functions_by_cat :: Ptr PgfPGF -> Ptr PgfText -> Ptr PgfItor -> Ptr PgfExn -> IO ()
|
||||||
|
|
||||||
foreign import ccall "pgf/pgf.h pgf_function_type"
|
foreign import ccall "pgf/pgf.h pgf_function_type"
|
||||||
pgf_function_type :: Ptr PgfPGF -> Ptr PgfText -> Ptr PgfUnmarshaller -> IO (StablePtr Type)
|
pgf_function_type :: Ptr PgfPGF -> Ptr PgfText -> Ptr PgfUnmarshaller -> IO (StablePtr Type)
|
||||||
|
|||||||
@@ -2958,7 +2958,7 @@ PGF_getAbstractName(PGFObject *self, void *closure)
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pgf_collect_cats(PgfItor* fn, PgfText* key, void* value)
|
pgf_collect_cats(PgfItor* fn, PgfText* key, void* value, PgfExn *err)
|
||||||
{
|
{
|
||||||
PgfText* name = key;
|
PgfText* name = key;
|
||||||
PyPGFClosure* clo = (PyPGFClosure*) fn;
|
PyPGFClosure* clo = (PyPGFClosure*) fn;
|
||||||
@@ -2987,13 +2987,9 @@ PGF_getCategories(PGFObject *self, void *closure)
|
|||||||
if (categories == NULL)
|
if (categories == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// GuPool* tmp_pool = gu_local_pool();
|
PgfExn err;
|
||||||
//
|
|
||||||
// Create an exception frame that catches all errors.
|
|
||||||
// GuExn* err = gu_new_exn(tmp_pool);
|
|
||||||
|
|
||||||
PyPGFClosure clo = { { pgf_collect_cats }, self, categories };
|
PyPGFClosure clo = { { pgf_collect_cats }, self, categories };
|
||||||
pgf_iter_categories(self->pgf, &clo.fn);
|
pgf_iter_categories(self->pgf, &clo.fn, &err);
|
||||||
|
|
||||||
// if (!gu_ok(err)) {
|
// if (!gu_ok(err)) {
|
||||||
// Py_DECREF(categories);
|
// Py_DECREF(categories);
|
||||||
@@ -3026,7 +3022,7 @@ PGF_getCategories(PGFObject *self, void *closure)
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pgf_collect_funs(PgfItor* fn, PgfText* key, void* value)
|
pgf_collect_funs(PgfItor* fn, PgfText* key, void* value, PgfExn *err)
|
||||||
{
|
{
|
||||||
PgfText* name = key;
|
PgfText* name = key;
|
||||||
PyPGFClosure* clo = (PyPGFClosure*) fn;
|
PyPGFClosure* clo = (PyPGFClosure*) fn;
|
||||||
@@ -3055,13 +3051,9 @@ PGF_getFunctions(PGFObject *self, void *closure)
|
|||||||
if (functions == NULL)
|
if (functions == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// GuPool* tmp_pool = gu_local_pool();
|
PgfExn err;
|
||||||
|
|
||||||
// Create an exception frame that catches all errors.
|
|
||||||
// GuExn* err = gu_new_exn(tmp_pool);
|
|
||||||
|
|
||||||
PyPGFClosure clo = { { pgf_collect_funs }, self, functions };
|
PyPGFClosure clo = { { pgf_collect_funs }, self, functions };
|
||||||
pgf_iter_functions(self->pgf, &clo.fn);
|
pgf_iter_functions(self->pgf, &clo.fn, &err);
|
||||||
// if (!gu_ok(err)) {
|
// if (!gu_ok(err)) {
|
||||||
// Py_DECREF(functions);
|
// Py_DECREF(functions);
|
||||||
// gu_pool_free(tmp_pool);
|
// gu_pool_free(tmp_pool);
|
||||||
@@ -3090,13 +3082,9 @@ PGF_functionsByCat(PGFObject* self, PyObject *args)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// GuPool *tmp_pool = gu_local_pool();
|
PgfExn err;
|
||||||
|
|
||||||
// Create an exception frame that catches all errors.
|
|
||||||
// GuExn* err = gu_new_exn(tmp_pool);
|
|
||||||
|
|
||||||
PyPGFClosure clo = { { pgf_collect_funs }, self, functions };
|
PyPGFClosure clo = { { pgf_collect_funs }, self, functions };
|
||||||
pgf_iter_functions_by_cat(self->pgf, catname, &clo.fn);
|
pgf_iter_functions_by_cat(self->pgf, catname, &clo.fn, &err);
|
||||||
// if (!gu_ok(err)) {
|
// if (!gu_ok(err)) {
|
||||||
// Py_DECREF(functions);
|
// Py_DECREF(functions);
|
||||||
// gu_pool_free(tmp_pool);
|
// gu_pool_free(tmp_pool);
|
||||||
|
|||||||
Reference in New Issue
Block a user