*** empty log message ***
This commit is contained in:
parent
c569bd886b
commit
9a78805acc
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: awk.c,v 1.77 2006-09-22 14:04:25 bacon Exp $
|
* $Id: awk.c,v 1.78 2006-10-02 14:53:44 bacon Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xp/awk/awk_i.h>
|
#include <xp/awk/awk_i.h>
|
||||||
@ -10,10 +10,25 @@ xp_awk_t* xp_awk_open (xp_awk_syscas_t* syscas)
|
|||||||
{
|
{
|
||||||
xp_awk_t* awk;
|
xp_awk_t* awk;
|
||||||
|
|
||||||
if (syscas == XP_NULL ||
|
if (syscas == XP_NULL) return XP_NULL;
|
||||||
syscas->malloc == XP_NULL ||
|
|
||||||
|
if (syscas->malloc == XP_NULL ||
|
||||||
syscas->free == XP_NULL) return XP_NULL;
|
syscas->free == XP_NULL) return XP_NULL;
|
||||||
|
|
||||||
|
if (syscas->is_upper == XP_NULL ||
|
||||||
|
syscas->is_lower == XP_NULL ||
|
||||||
|
syscas->is_alpha == XP_NULL ||
|
||||||
|
syscas->is_digit == XP_NULL ||
|
||||||
|
syscas->is_xdigit == XP_NULL ||
|
||||||
|
syscas->is_alnum == XP_NULL ||
|
||||||
|
syscas->is_space == XP_NULL ||
|
||||||
|
syscas->is_print == XP_NULL ||
|
||||||
|
syscas->is_graph == XP_NULL ||
|
||||||
|
syscas->is_cntrl == XP_NULL ||
|
||||||
|
syscas->is_punct == XP_NULL ||
|
||||||
|
syscas->to_upper == XP_NULL ||
|
||||||
|
syscas->to_lower == XP_NULL) return XP_NULL;
|
||||||
|
|
||||||
#if defined(_WIN32) && defined(_DEBUG)
|
#if defined(_WIN32) && defined(_DEBUG)
|
||||||
awk = (xp_awk_t*) malloc (xp_sizeof(xp_awk_t));
|
awk = (xp_awk_t*) malloc (xp_sizeof(xp_awk_t));
|
||||||
#else
|
#else
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: awk.h,v 1.118 2006-09-25 06:17:18 bacon Exp $
|
* $Id: awk.h,v 1.119 2006-10-02 14:53:44 bacon Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _XP_AWK_AWK_H_
|
#ifndef _XP_AWK_AWK_H_
|
||||||
@ -350,7 +350,11 @@ xp_awk_val_t* xp_awk_getglobal (void* run, xp_size_t idx);
|
|||||||
int xp_awk_setglobal (void* run, xp_size_t idx, xp_awk_val_t* val);
|
int xp_awk_setglobal (void* run, xp_size_t idx, xp_awk_val_t* val);
|
||||||
void xp_awk_seterrnum (void* run, int errnum);
|
void xp_awk_seterrnum (void* run, int errnum);
|
||||||
void xp_awk_setretval (void* run, xp_awk_val_t* val);
|
void xp_awk_setretval (void* run, xp_awk_val_t* val);
|
||||||
int xp_awk_setrecord (void* run, const xp_char_t* str, xp_size_t len);
|
|
||||||
|
int xp_awk_setrecord (
|
||||||
|
void* run, const xp_char_t* str, xp_size_t len);
|
||||||
|
int xp_awk_setfield (
|
||||||
|
void* run, xp_size_t idx, const xp_char_t* str, xp_size_t len);
|
||||||
|
|
||||||
/* utility functions exported by awk.h */
|
/* utility functions exported by awk.h */
|
||||||
xp_long_t xp_awk_strtolong (
|
xp_long_t xp_awk_strtolong (
|
||||||
|
106
ase/awk/func.c
106
ase/awk/func.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: func.c,v 1.54 2006-09-30 17:02:35 bacon Exp $
|
* $Id: func.c,v 1.55 2006-10-02 14:53:44 bacon Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xp/awk/awk_i.h>
|
#include <xp/awk/awk_i.h>
|
||||||
@ -521,6 +521,7 @@ static int __bfn_split (xp_awk_t* awk, void* run)
|
|||||||
|
|
||||||
xp_assert (a1->type == XP_AWK_VAL_REF);
|
xp_assert (a1->type == XP_AWK_VAL_REF);
|
||||||
|
|
||||||
|
/* TODO: XP_AWK_VAL_REF_POS */
|
||||||
if (((xp_awk_val_ref_t*)a1)->id >= XP_AWK_VAL_REF_NAMEDIDX &&
|
if (((xp_awk_val_ref_t*)a1)->id >= XP_AWK_VAL_REF_NAMEDIDX &&
|
||||||
((xp_awk_val_ref_t*)a1)->id <= XP_AWK_VAL_REF_ARGIDX)
|
((xp_awk_val_ref_t*)a1)->id <= XP_AWK_VAL_REF_ARGIDX)
|
||||||
{
|
{
|
||||||
@ -809,6 +810,7 @@ static int __bfn_sub (xp_awk_t* awk, void* run)
|
|||||||
|
|
||||||
static int __substitute (xp_awk_t* awk, void* run, xp_long_t max_count)
|
static int __substitute (xp_awk_t* awk, void* run, xp_long_t max_count)
|
||||||
{
|
{
|
||||||
|
xp_awk_run_t* r = run;
|
||||||
xp_size_t nargs;
|
xp_size_t nargs;
|
||||||
xp_awk_val_t* a0, * a1, * a2, ** a2_ref, * v;
|
xp_awk_val_t* a0, * a1, * a2, ** a2_ref, * v;
|
||||||
xp_char_t* a0_ptr, * a1_ptr, * a2_ptr;
|
xp_char_t* a0_ptr, * a1_ptr, * a2_ptr;
|
||||||
@ -882,21 +884,34 @@ static int __substitute (xp_awk_t* awk, void* run, xp_long_t max_count)
|
|||||||
if (a2 == XP_NULL)
|
if (a2 == XP_NULL)
|
||||||
{
|
{
|
||||||
/* is this correct? any needs to use inrec.d0? */
|
/* is this correct? any needs to use inrec.d0? */
|
||||||
a2_ptr = XP_AWK_STR_BUF(&((xp_awk_run_t*)run)->inrec.line);
|
a2_ptr = XP_AWK_STR_BUF(&r->inrec.line);
|
||||||
a2_len = XP_AWK_STR_LEN(&((xp_awk_run_t*)run)->inrec.line);
|
a2_len = XP_AWK_STR_LEN(&r->inrec.line);
|
||||||
|
}
|
||||||
|
else if (((xp_awk_val_ref_t*)a2)->id == XP_AWK_VAL_REF_POS)
|
||||||
|
{
|
||||||
|
xp_size_t idx;
|
||||||
|
|
||||||
|
idx = (xp_size_t)((xp_awk_val_ref_t*)a2)->adr;
|
||||||
|
if (idx == 0)
|
||||||
|
{
|
||||||
|
a2_ptr = XP_AWK_STR_BUF(&r->inrec.line);
|
||||||
|
a2_len = XP_AWK_STR_LEN(&r->inrec.line);
|
||||||
|
}
|
||||||
|
else if (idx <= r->inrec.nflds)
|
||||||
|
{
|
||||||
|
a2_ptr = r->inrec.flds[idx-1].ptr;
|
||||||
|
a2_len = r->inrec.flds[idx-1].len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
a2_ptr = XP_T("");
|
||||||
|
a2_len = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* operation is on a2 */
|
|
||||||
if (((xp_awk_val_ref_t*)a2)->id == XP_AWK_VAL_REF_POS)
|
|
||||||
{
|
|
||||||
FREE_A_PTRS (awk);
|
|
||||||
/* a map is not allowed as the third parameter */
|
|
||||||
xp_awk_seterrnum (run, XP_AWK_EMAPNOTALLOWED);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
a2_ref = (xp_awk_val_t**)((xp_awk_val_ref_t*)a2)->adr;
|
a2_ref = (xp_awk_val_t**)((xp_awk_val_ref_t*)a2)->adr;
|
||||||
|
|
||||||
if ((*a2_ref)->type == XP_AWK_VAL_MAP)
|
if ((*a2_ref)->type == XP_AWK_VAL_MAP)
|
||||||
{
|
{
|
||||||
FREE_A_PTRS (awk);
|
FREE_A_PTRS (awk);
|
||||||
@ -913,7 +928,7 @@ return -1;
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
a2_ptr = xp_awk_valtostr (
|
a2_ptr = xp_awk_valtostr (
|
||||||
run, *a2_ref, xp_true, XP_NULL, &a2_len);
|
r, *a2_ref, xp_true, XP_NULL, &a2_len);
|
||||||
if (a2_ptr == XP_NULL)
|
if (a2_ptr == XP_NULL)
|
||||||
{
|
{
|
||||||
FREE_A_PTRS (awk);
|
FREE_A_PTRS (awk);
|
||||||
@ -1023,30 +1038,57 @@ return -1;
|
|||||||
|
|
||||||
FREE_A0_REX (awk, rex);
|
FREE_A0_REX (awk, rex);
|
||||||
|
|
||||||
if (a2 == XP_NULL)
|
if (sub_count > 0)
|
||||||
{
|
{
|
||||||
if (xp_awk_setrecord (run,
|
if (a2 == XP_NULL)
|
||||||
XP_AWK_STR_BUF(&new), XP_AWK_STR_LEN(&new)) == -1)
|
|
||||||
{
|
{
|
||||||
xp_awk_str_close (&new);
|
if (xp_awk_setrecord (run,
|
||||||
FREE_A_PTRS (awk);
|
XP_AWK_STR_BUF(&new), XP_AWK_STR_LEN(&new)) == -1)
|
||||||
return -1;
|
{
|
||||||
|
xp_awk_str_close (&new);
|
||||||
|
FREE_A_PTRS (awk);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
else if (((xp_awk_val_ref_t*)a2)->id == XP_AWK_VAL_REF_POS)
|
||||||
else
|
|
||||||
{
|
|
||||||
v = xp_awk_makestrval (run,
|
|
||||||
XP_AWK_STR_BUF(&new), XP_AWK_STR_LEN(&new));
|
|
||||||
if (v == XP_NULL)
|
|
||||||
{
|
{
|
||||||
xp_awk_str_close (&new);
|
int n;
|
||||||
FREE_A_PTRS (awk);
|
xp_size_t idx;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
xp_awk_refdownval (run, *a2_ref);
|
idx = (xp_size_t)((xp_awk_val_ref_t*)a2)->adr;
|
||||||
*a2_ref = v;
|
if (idx == 0)
|
||||||
xp_awk_refupval (*a2_ref);
|
{
|
||||||
|
n = xp_awk_setrecord (run,
|
||||||
|
XP_AWK_STR_BUF(&new), XP_AWK_STR_LEN(&new));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
n = xp_awk_setfield (run, idx,
|
||||||
|
XP_AWK_STR_BUF(&new), XP_AWK_STR_LEN(&new));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n == -1)
|
||||||
|
{
|
||||||
|
xp_awk_str_close (&new);
|
||||||
|
FREE_A_PTRS (awk);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
v = xp_awk_makestrval (run,
|
||||||
|
XP_AWK_STR_BUF(&new), XP_AWK_STR_LEN(&new));
|
||||||
|
if (v == XP_NULL)
|
||||||
|
{
|
||||||
|
xp_awk_str_close (&new);
|
||||||
|
FREE_A_PTRS (awk);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
xp_awk_refdownval (run, *a2_ref);
|
||||||
|
*a2_ref = v;
|
||||||
|
xp_awk_refupval (*a2_ref);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xp_awk_str_close (&new);
|
xp_awk_str_close (&new);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: run.c,v 1.215 2006-10-01 14:48:48 bacon Exp $
|
* $Id: run.c,v 1.216 2006-10-02 14:53:44 bacon Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xp/awk/awk_i.h>
|
#include <xp/awk/awk_i.h>
|
||||||
@ -199,7 +199,8 @@ static int __set_record (
|
|||||||
static int __split_record (xp_awk_run_t* run);
|
static int __split_record (xp_awk_run_t* run);
|
||||||
static int __clear_record (xp_awk_run_t* run, xp_bool_t noline);
|
static int __clear_record (xp_awk_run_t* run, xp_bool_t noline);
|
||||||
static int __recomp_record_fields (
|
static int __recomp_record_fields (
|
||||||
xp_awk_run_t* run, xp_size_t lv, xp_char_t* str, xp_size_t len);
|
xp_awk_run_t* run, xp_size_t lv,
|
||||||
|
const xp_char_t* str, xp_size_t len);
|
||||||
static int __shorten_record (xp_awk_run_t* run, xp_size_t nflds);
|
static int __shorten_record (xp_awk_run_t* run, xp_size_t nflds);
|
||||||
|
|
||||||
static xp_char_t* __idxnde_to_str (
|
static xp_char_t* __idxnde_to_str (
|
||||||
@ -2537,6 +2538,7 @@ static xp_awk_val_t* __do_assignment_pos (
|
|||||||
run->inrec.d0 = v;
|
run->inrec.d0 = v;
|
||||||
xp_awk_refupval (v);
|
xp_awk_refupval (v);
|
||||||
|
|
||||||
|
/* TODO: this return value is wrong. consider reimplementing this function with setrecord and setfield... also verify setreocrd and setfield.. */
|
||||||
val = v;
|
val = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4278,7 +4280,7 @@ static xp_awk_val_t* __eval_call (
|
|||||||
}
|
}
|
||||||
/*xp_printf (XP_T("got return value\n")); */
|
/*xp_printf (XP_T("got return value\n")); */
|
||||||
|
|
||||||
/* this is the trick mentioned in __run_return.
|
/* this trick has been mentioned in __run_return.
|
||||||
* adjust the reference count of the return value.
|
* adjust the reference count of the return value.
|
||||||
* the value must not be freed even if the reference count
|
* the value must not be freed even if the reference count
|
||||||
* is decremented to zero because its reference has been incremented
|
* is decremented to zero because its reference has been incremented
|
||||||
@ -4301,7 +4303,7 @@ static int __get_reference (
|
|||||||
xp_awk_nde_var_t* tgt = (xp_awk_nde_var_t*)nde;
|
xp_awk_nde_var_t* tgt = (xp_awk_nde_var_t*)nde;
|
||||||
xp_awk_val_t** tmp;
|
xp_awk_val_t** tmp;
|
||||||
|
|
||||||
/* refer to __eval_indexed for application of similar concept */
|
/* refer to __eval_indexed for application of a similar concept */
|
||||||
|
|
||||||
if (nde->type == XP_AWK_NDE_NAMED)
|
if (nde->type == XP_AWK_NDE_NAMED)
|
||||||
{
|
{
|
||||||
@ -4320,28 +4322,24 @@ static int __get_reference (
|
|||||||
if (pair == XP_NULL) PANIC_I (run, XP_AWK_ENOMEM);
|
if (pair == XP_NULL) PANIC_I (run, XP_AWK_ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
//return (xp_awk_val_t**)&pair->val;
|
|
||||||
*ref = (xp_awk_val_t**)&pair->val;
|
*ref = (xp_awk_val_t**)&pair->val;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nde->type == XP_AWK_NDE_GLOBAL)
|
if (nde->type == XP_AWK_NDE_GLOBAL)
|
||||||
{
|
{
|
||||||
//return (xp_awk_val_t**)&STACK_GLOBAL(run,tgt->id.idxa);
|
|
||||||
*ref = (xp_awk_val_t**)&STACK_GLOBAL(run,tgt->id.idxa);
|
*ref = (xp_awk_val_t**)&STACK_GLOBAL(run,tgt->id.idxa);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nde->type == XP_AWK_NDE_LOCAL)
|
if (nde->type == XP_AWK_NDE_LOCAL)
|
||||||
{
|
{
|
||||||
//return (xp_awk_val_t**)&STACK_LOCAL(run,tgt->id.idxa);
|
|
||||||
*ref = (xp_awk_val_t**)&STACK_LOCAL(run,tgt->id.idxa);
|
*ref = (xp_awk_val_t**)&STACK_LOCAL(run,tgt->id.idxa);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nde->type == XP_AWK_NDE_ARG)
|
if (nde->type == XP_AWK_NDE_ARG)
|
||||||
{
|
{
|
||||||
//return (xp_awk_val_t**)&STACK_ARG(run,tgt->id.idxa);
|
|
||||||
*ref = (xp_awk_val_t**)&STACK_ARG(run,tgt->id.idxa);
|
*ref = (xp_awk_val_t**)&STACK_ARG(run,tgt->id.idxa);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -4360,8 +4358,6 @@ static int __get_reference (
|
|||||||
if (pair == XP_NULL) PANIC_I (run, XP_AWK_ENOMEM);
|
if (pair == XP_NULL) PANIC_I (run, XP_AWK_ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
//return __get_reference_indexed (
|
|
||||||
// run, tgt, (xp_awk_val_t**)&pair->val);
|
|
||||||
tmp = __get_reference_indexed (
|
tmp = __get_reference_indexed (
|
||||||
run, tgt, (xp_awk_val_t**)&pair->val);
|
run, tgt, (xp_awk_val_t**)&pair->val);
|
||||||
if (tmp == XP_NULL) return -1;
|
if (tmp == XP_NULL) return -1;
|
||||||
@ -4412,7 +4408,7 @@ static int __get_reference (
|
|||||||
if (n == 1) lv = (xp_long_t)rv;
|
if (n == 1) lv = (xp_long_t)rv;
|
||||||
if (!IS_VALID_POSIDX(lv)) PANIC_I (run, XP_AWK_EPOSIDX);
|
if (!IS_VALID_POSIDX(lv)) PANIC_I (run, XP_AWK_EPOSIDX);
|
||||||
|
|
||||||
*ref = (xp_awk_val_t**)(lv);
|
*ref = (xp_awk_val_t**)lv;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4848,19 +4844,61 @@ static int __read_record (xp_awk_run_t* run)
|
|||||||
|
|
||||||
int xp_awk_setrecord (void* run, const xp_char_t* str, xp_size_t len)
|
int xp_awk_setrecord (void* run, const xp_char_t* str, xp_size_t len)
|
||||||
{
|
{
|
||||||
if (__clear_record (run, xp_false) == -1) return -1;
|
xp_awk_run_t* r = (xp_awk_run_t*)run;
|
||||||
|
|
||||||
if (xp_awk_str_ncpy (
|
if (__clear_record (r, xp_false) == -1) return -1;
|
||||||
&((xp_awk_run_t*)run)->inrec.line, str, len) == (xp_size_t)-1)
|
|
||||||
|
if (xp_awk_str_ncpy (&r->inrec.line, str, len) == (xp_size_t)-1)
|
||||||
{
|
{
|
||||||
__clear_record (run, xp_false);
|
__clear_record (run, xp_false);
|
||||||
((xp_awk_run_t*)run)->errnum = XP_AWK_ENOMEM;
|
r->errnum = XP_AWK_ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return __set_record (run, str, len);
|
return __set_record (run, str, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int xp_awk_setfield (
|
||||||
|
void* run, xp_size_t idx, const xp_char_t* str, xp_size_t len)
|
||||||
|
{
|
||||||
|
xp_awk_run_t* r = (xp_awk_run_t*)run;
|
||||||
|
xp_awk_val_t* v;
|
||||||
|
int errnum;
|
||||||
|
|
||||||
|
if (!IS_VALID_POSIDX(idx))
|
||||||
|
{
|
||||||
|
r->errnum = XP_AWK_EPOSIDX;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx == 0) return xp_awk_setrecord (run, str, len);
|
||||||
|
|
||||||
|
if (__recomp_record_fields (r, idx, str, len) == -1)
|
||||||
|
{
|
||||||
|
errnum = r->errnum;
|
||||||
|
__clear_record (r, xp_false);
|
||||||
|
r->errnum = errnum;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* recompose $0 */
|
||||||
|
v = xp_awk_makestrval (r,
|
||||||
|
XP_AWK_STR_BUF(&r->inrec.line),
|
||||||
|
XP_AWK_STR_LEN(&r->inrec.line));
|
||||||
|
if (v == XP_NULL)
|
||||||
|
{
|
||||||
|
__clear_record (run, xp_false);
|
||||||
|
r->errnum = XP_AWK_ENOMEM;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
xp_awk_refdownval (run, r->inrec.d0);
|
||||||
|
r->inrec.d0 = v;
|
||||||
|
xp_awk_refupval (v);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int __set_record (
|
static int __set_record (
|
||||||
xp_awk_run_t* run, const xp_char_t* str, xp_size_t len)
|
xp_awk_run_t* run, const xp_char_t* str, xp_size_t len)
|
||||||
{
|
{
|
||||||
@ -5071,7 +5109,8 @@ static int __clear_record (xp_awk_run_t* run, xp_bool_t noline)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int __recomp_record_fields (
|
static int __recomp_record_fields (
|
||||||
xp_awk_run_t* run, xp_size_t lv, xp_char_t* str, xp_size_t len)
|
xp_awk_run_t* run, xp_size_t lv,
|
||||||
|
const xp_char_t* str, xp_size_t len)
|
||||||
{
|
{
|
||||||
xp_awk_val_t* v;
|
xp_awk_val_t* v;
|
||||||
xp_size_t max, i, nflds;
|
xp_size_t max, i, nflds;
|
||||||
|
5
ase/test/awk/t49.awk
Normal file
5
ase/test/awk/t49.awk
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
BEGIN { OFS=":"; }
|
||||||
|
{
|
||||||
|
print $5 = "abc";
|
||||||
|
print $0;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user