Commit 11be5291 authored by Miguel de Icaza's avatar Miguel de Icaza Committed by Arturo Espinosa

OH MY GOD! This has been on my laptop for AGES! and it never went into CVS. What a dork I am

So, here it is:

1998-11-13  Miguel de Icaza  <miguel@nuclecu.unam.mx>

	* src/sheet-autofill.c (autofill_cell): Simplify by using
	cell_set_formula_tree

	* src/expr.c (expr_parse_string): Take a sheet argument
	(expr_decode_tree): Same

	* sheet.c (cellref_name): Now takes a sheet argument and decodes the
	cellref depending on the sheet.

	* cell.c (CellRef): Now they include the sheet location.
parent 7eae5d28
1998-11-13 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/sheet-autofill.c (autofill_cell): Simplify by using
cell_set_formula_tree
* src/expr.c (expr_parse_string): Take a sheet argument
(expr_decode_tree): Same
* sheet.c (cellref_name): Now takes a sheet argument and decodes the
cellref depending on the sheet.
* cell.c (CellRef): Now they include the sheet location.
1998-11-28 Michael Meeks <mejm2@cam.ac.uk>
* plugins/excel/ms-ole.c, plugins/excel/ms-ole.h: Total re-write
......
1998-11-13 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/sheet-autofill.c (autofill_cell): Simplify by using
cell_set_formula_tree
* src/expr.c (expr_parse_string): Take a sheet argument
(expr_decode_tree): Same
* sheet.c (cellref_name): Now takes a sheet argument and decodes the
cellref depending on the sheet.
* cell.c (CellRef): Now they include the sheet location.
1998-11-28 Michael Meeks <mejm2@cam.ac.uk>
* plugins/excel/ms-ole.c, plugins/excel/ms-ole.h: Total re-write
......
1998-11-13 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/sheet-autofill.c (autofill_cell): Simplify by using
cell_set_formula_tree
* src/expr.c (expr_parse_string): Take a sheet argument
(expr_decode_tree): Same
* sheet.c (cellref_name): Now takes a sheet argument and decodes the
cellref depending on the sheet.
* cell.c (CellRef): Now they include the sheet location.
1998-11-28 Michael Meeks <mejm2@cam.ac.uk>
* plugins/excel/ms-ole.c, plugins/excel/ms-ole.h: Total re-write
......
1998-11-13 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/sheet-autofill.c (autofill_cell): Simplify by using
cell_set_formula_tree
* src/expr.c (expr_parse_string): Take a sheet argument
(expr_decode_tree): Same
* sheet.c (cellref_name): Now takes a sheet argument and decodes the
cellref depending on the sheet.
* cell.c (CellRef): Now they include the sheet location.
1998-11-28 Michael Meeks <mejm2@cam.ac.uk>
* plugins/excel/ms-ole.c, plugins/excel/ms-ole.h: Total re-write
......
......@@ -314,7 +314,7 @@ void ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q,
ref = getRefV7 (BIFF_GETBYTE(cur+2), BIFF_GETWORD(cur), fn_col, fn_row) ;
ptg_length = 3 ;
}
buffer = cellref_name (ref, fn_col, fn_row) ;
buffer = cellref_name (ref, sheet->gnum_sheet, fn_col, fn_row) ;
parse_list_push_raw(stack, strdup (buffer), NO_PRECEDENCE) ;
printf ("%s\n", buffer) ;
free (ref) ;
......@@ -336,9 +336,9 @@ void ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q,
last = getRefV7(BIFF_GETBYTE(cur+5), BIFF_GETWORD(cur+2), fn_col, fn_row) ;
ptg_length = 6 ;
}
strcpy (buffer, cellref_name (first, fn_col, fn_row)) ;
strcpy (buffer, cellref_name (first, sheet->gnum_sheet, fn_col, fn_row)) ;
strcat (buffer, ":") ;
strcat (buffer, cellref_name (last, fn_col, fn_row)) ;
strcat (buffer, cellref_name (last, sheet->gnum_sheet, fn_col, fn_row)) ;
parse_list_push_raw(stack, strdup (buffer), NO_PRECEDENCE) ;
printf ("%s\n", buffer) ;
free (first) ;
......
......@@ -314,7 +314,7 @@ void ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q,
ref = getRefV7 (BIFF_GETBYTE(cur+2), BIFF_GETWORD(cur), fn_col, fn_row) ;
ptg_length = 3 ;
}
buffer = cellref_name (ref, fn_col, fn_row) ;
buffer = cellref_name (ref, sheet->gnum_sheet, fn_col, fn_row) ;
parse_list_push_raw(stack, strdup (buffer), NO_PRECEDENCE) ;
printf ("%s\n", buffer) ;
free (ref) ;
......@@ -336,9 +336,9 @@ void ms_excel_parse_formula (MS_EXCEL_SHEET *sheet, BIFF_QUERY *q,
last = getRefV7(BIFF_GETBYTE(cur+5), BIFF_GETWORD(cur+2), fn_col, fn_row) ;
ptg_length = 6 ;
}
strcpy (buffer, cellref_name (first, fn_col, fn_row)) ;
strcpy (buffer, cellref_name (first, sheet->gnum_sheet, fn_col, fn_row)) ;
strcat (buffer, ":") ;
strcat (buffer, cellref_name (last, fn_col, fn_row)) ;
strcat (buffer, cellref_name (last, sheet->gnum_sheet, fn_col, fn_row)) ;
parse_list_push_raw(stack, strdup (buffer), NO_PRECEDENCE) ;
printf ("%s\n", buffer) ;
free (first) ;
......
......@@ -47,6 +47,7 @@ cell_set_formula (Cell *cell, char *text)
cell_modified (cell);
cell->parsed_node = expr_parse_string (&text [1],
cell->sheet,
cell->col->pos,
cell->row->pos,
&desired_format,
......@@ -1477,7 +1478,7 @@ cell_get_text (Cell *cell)
if (cell->parsed_node){
char *func, *ret;
func = expr_decode_tree (cell->parsed_node, cell->col->pos, cell->row->pos);
func = expr_decode_tree (cell->parsed_node, cell->sheet, cell->col->pos, cell->row->pos);
ret = g_copy_strings ("=", func, NULL);
g_free (func);
......
......@@ -28,16 +28,22 @@ ParseErr parser_error;
/* The expression tree returned from the parser */
ExprTree *parser_result;
/* The sheet where the parsing takes place */
void *parser_sheet;
/* Location where the parsing is taking place */
int parser_col, parser_row;
ExprTree *
expr_parse_string (char *expr, int col, int row, char **desired_format, char **error_msg)
expr_parse_string (char *expr, void *sheet, int col, int row, char **desired_format, char **error_msg)
{
parser_expr = expr;
g_return_val_if_fail (expr != NULL, NULL);
parser_expr = expr;
parser_error = PARSE_OK;
parser_col = col;
parser_row = row;
parser_col = col;
parser_row = row;
parser_sheet = sheet;
parser_desired_format = NULL;
yyparse ();
......@@ -970,7 +976,7 @@ bigger_prec (Operation parent, Operation this)
* create a string representation.
*/
static char *
do_expr_decode_tree (ExprTree *tree, int col, int row, Operation parent_op)
do_expr_decode_tree (ExprTree *tree, void *sheet, int col, int row, Operation parent_op)
{
static const char *binary_operation_names [] = {
"=", ">", "<", ">=", "<=", "<>",
......@@ -995,8 +1001,8 @@ do_expr_decode_tree (ExprTree *tree, int col, int row, Operation parent_op)
char *a, *b, *res;
char const *op;
a = do_expr_decode_tree (tree->u.binary.value_a, col, row, tree->oper);
b = do_expr_decode_tree (tree->u.binary.value_b, col, row, tree->oper);
a = do_expr_decode_tree (tree->u.binary.value_a, sheet, col, row, tree->oper);
b = do_expr_decode_tree (tree->u.binary.value_b, sheet, col, row, tree->oper);
op = binary_operation_names [tree->oper];
if (bigger_prec (parent_op, tree->oper))
......@@ -1012,7 +1018,7 @@ do_expr_decode_tree (ExprTree *tree, int col, int row, Operation parent_op)
case OPER_NEG: {
char *res, *a;
a = do_expr_decode_tree (tree->u.value, col, row, tree->oper);
a = do_expr_decode_tree (tree->u.value, sheet, col, row, tree->oper);
res = g_copy_strings ("-", a);
g_free (a);
return res;
......@@ -1037,7 +1043,7 @@ do_expr_decode_tree (ExprTree *tree, int col, int row, Operation parent_op)
for (l = arg_list; l; l = l->next, i++){
ExprTree *t = l->data;
args [i] = do_expr_decode_tree (t, col, row, OPER_CONSTANT);
args [i] = do_expr_decode_tree (t, sheet, col, row, OPER_CONSTANT);
len += strlen (args [i]) + 1;
}
len++;
......@@ -1067,14 +1073,17 @@ do_expr_decode_tree (ExprTree *tree, int col, int row, Operation parent_op)
Value *v = tree->u.constant;
if (v->type == VALUE_CELLRANGE){
char buffer_a [20], buffer_b [20], *a;
char *a, *b, *res;
a = cellref_name (&v->v.cell_range.cell_a, sheet, col, row);
b = cellref_name (&v->v.cell_range.cell_b, sheet, col, row);
a = cellref_name (&v->v.cell_range.cell_a, col, row);
strcpy (buffer_a, a);
a = cellref_name (&v->v.cell_range.cell_b, col, row);
strcpy (buffer_b, a);
res = g_copy_strings (a, ":", b, NULL);
return g_copy_strings (buffer_a, ":", buffer_b, NULL);
g_free (a);
g_free (b);
return res;
} else {
if (v->type == VALUE_STRING){
return g_copy_strings ("\"", v->v.str->str, "\"", NULL);
......@@ -1087,7 +1096,7 @@ do_expr_decode_tree (ExprTree *tree, int col, int row, Operation parent_op)
CellRef *cell_ref;
cell_ref = &tree->u.constant->v.cell;
return g_strdup (cellref_name (cell_ref, col, row));
return cellref_name (cell_ref, sheet, col, row);
}
}
......@@ -1096,9 +1105,12 @@ do_expr_decode_tree (ExprTree *tree, int col, int row, Operation parent_op)
}
char *
expr_decode_tree (ExprTree *tree, int col, int row)
expr_decode_tree (ExprTree *tree, void *sheet, int col, int row)
{
g_return_val_if_fail (tree != NULL, NULL);
return do_expr_decode_tree (tree, col, row, OPER_CONSTANT);
g_return_val_if_fail (sheet != NULL, NULL);
g_return_val_if_fail (IS_SHEET (sheet), NULL);
return do_expr_decode_tree (tree, sheet, col, row, OPER_CONSTANT);
}
......@@ -32,12 +32,8 @@ typedef enum {
} ValueType;
typedef struct {
int col;
int row;
} CellPos;
typedef struct {
int col, row;
void *sheet;
int col, row;
unsigned int col_relative:1;
unsigned int row_relative:1;
......@@ -81,11 +77,6 @@ struct ExprTree {
} binary;
struct ExprTree *value;
struct {
void *sheet;
CellRef cell;
} extref;
} u;
};
......@@ -135,14 +126,18 @@ extern char *parser_expr;
extern char *parser_desired_format;
extern ParseErr parser_error;
extern ExprTree *parser_result;
extern void *parser_sheet;
extern int parser_col, parser_row;
void cell_get_abs_col_row (CellRef *cell_ref, int eval_col, int eval_row, int *col, int *row);
void cell_get_abs_col_row (CellRef *cell_ref,
int eval_col, int eval_row,
int *col, int *row);
ExprTree *expr_parse_string (char *expr, int col, int row,
ExprTree *expr_parse_string (char *expr, void *sheet, int col, int row,
char **desired_format, char **error_msg);
char *expr_decode_tree (ExprTree *tree, int col, int row);
char *expr_decode_tree (ExprTree *tree, void *sheet,
int col, int row);
void expr_tree_ref (ExprTree *tree);
void expr_tree_unref (ExprTree *tree);
......
......@@ -77,6 +77,7 @@ gnumeric_selection (void *tsheet, GList *expr_node_list, int eval_col, int eval_
/* Fill it in */
/* start */
cell_ref = &single_value->v.cell_range.cell_a;
cell_ref->sheet = tsheet;
cell_ref->col_relative = 0;
cell_ref->row_relative = 0;
......@@ -85,6 +86,7 @@ gnumeric_selection (void *tsheet, GList *expr_node_list, int eval_col, int eval_
/* end */
cell_ref = &single_value->v.cell_range.cell_b;
cell_ref->sheet = tsheet;
cell_ref->col_relative = 0;
cell_ref->row_relative = 0;
......
......@@ -77,6 +77,7 @@ gnumeric_selection (void *tsheet, GList *expr_node_list, int eval_col, int eval_
/* Fill it in */
/* start */
cell_ref = &single_value->v.cell_range.cell_a;
cell_ref->sheet = tsheet;
cell_ref->col_relative = 0;
cell_ref->row_relative = 0;
......@@ -85,6 +86,7 @@ gnumeric_selection (void *tsheet, GList *expr_node_list, int eval_col, int eval_
/* end */
cell_ref = &single_value->v.cell_range.cell_b;
cell_ref->sheet = tsheet;
cell_ref->col_relative = 0;
cell_ref->row_relative = 0;
......
......@@ -13,4 +13,5 @@ void gtk_radio_button_select (GSList *group, int n);
char *font_get_bold_name (char *fontname);
char *font_get_italic_name (char *fontname);
char *font_change_component (char *fontname, int idx, char *value);
#endif /* GNUMERIC_GNUMERIC_UTIL_H */
......@@ -13,4 +13,5 @@ void gtk_radio_button_select (GSList *group, int n);
char *font_get_bold_name (char *fontname);
char *font_get_italic_name (char *fontname);
char *font_change_component (char *fontname, int idx, char *value);
#endif /* GNUMERIC_GNUMERIC_UTIL_H */
......@@ -90,41 +90,6 @@ cell_name (int col, int row)
return buffer;
}
char *
cellref_name (CellRef *cell_ref, int eval_col, int eval_row)
{
static char buffer [sizeof (long) * 4];
char *p = buffer;
int col, row;
if (cell_ref->col_relative)
col = eval_col + cell_ref->col;
else {
*p++ = '$';
col = cell_ref->col;
}
if (col <= 'Z'-'A'){
*p++ = col + 'A';
} else {
int a = col / ('Z'-'A'+1);
int b = col % ('Z'-'A'+1);
*p++ = a + 'A' - 1;
*p++ = b + 'A';
}
if (cell_ref->row_relative)
row = eval_row + cell_ref->row;
else {
*p++ = '$';
row = cell_ref->row;
}
sprintf (p, "%d", row+1);
return buffer;
}
char *
col_name (int col)
{
......
......@@ -6,8 +6,6 @@ void int_get_from_range (char *start, char *end, int_t *t);
void float_get_from_range (char *start, char *end, float_t *t);
char *cell_name (int col, int row);
char *cellref_name (CellRef *cell_ref, int eval_col, int eval_row);
int parse_cell_name (char *cell_str, int *col, int *row);
char *col_name (int col);
......
......@@ -73,13 +73,18 @@ gnumeric_main (void *closure, int argc, char *argv [])
gnome_config_drop_all ();
}
#ifdef HAVE_GUILE
int
main (int argc, char *argv [])
{
#ifdef HAVE_GUILE
scm_boot_guile(argc, argv, gnumeric_main, 0);
return 0;
}
#else
int
main (int argc, char *argv [])
{
gnumeric_main(0, argc, argv);
#endif
return 0;
}
#endif
......@@ -73,13 +73,18 @@ gnumeric_main (void *closure, int argc, char *argv [])
gnome_config_drop_all ();
}
#ifdef HAVE_GUILE
int
main (int argc, char *argv [])
{
#ifdef HAVE_GUILE
scm_boot_guile(argc, argv, gnumeric_main, 0);
return 0;
}
#else
int
main (int argc, char *argv [])
{
gnumeric_main(0, argc, argv);
#endif
return 0;
}
#endif
......@@ -20,12 +20,12 @@
/* Allocation with disposal-on-error */
static void *alloc_buffer (int size);
static void register_symbol (Symbol *sym);
static void alloc_clean (void);
static void alloc_glist (GList *l);
static void forget_glist (GList *list);
static void forget_tree (ExprTree *tree);
static void alloc_list_free (void);
static void register_symbol (Symbol *sym);
static void alloc_clean (void);
static void alloc_glist (GList *l);
static void forget_glist (GList *list);
static void forget_tree (ExprTree *tree);
static void alloc_list_free (void);
static void *v_new (void);
#define ERROR -1
......@@ -67,7 +67,6 @@ build_binop (ExprTree *l, Operation op, ExprTree *r)
return res;
}
%}
%union {
......@@ -225,7 +224,8 @@ return_cellref (char *p)
ref->col_relative = col_relative;
ref->row_relative = row_relative;
ref->sheet = parser_sheet;
e->u.constant = v;
yylval.tree = e;
......
......@@ -512,13 +512,7 @@ autofill_cell (Cell *cell, int idx, FillItem *fi)
}
case FILL_FORMULA: {
char *text, *formula;
text = expr_decode_tree (fi->v.formula, cell->col->pos, cell->row->pos);
formula = g_copy_strings ("=", text, NULL);
cell_set_text (cell, formula);
g_free (text);
g_free (formula);
cell_set_formula_tree (cell, fi->v.formula);
return;
}
......
......@@ -18,6 +18,12 @@
#define GNUMERIC_SHEET_VIEW(p) GNUMERIC_SHEET (SHEET_VIEW(p)->sheet_view);
/* Used to locate cells in a sheet */
typedef struct {
int col;
int row;
} CellPos;
void
sheet_redraw_all (Sheet *sheet)
{
......@@ -1702,14 +1708,14 @@ Cell *
sheet_cell_get (Sheet *sheet, int col, int row)
{
Cell *cell;
CellPos cellref;
CellPos cellpos;
g_return_val_if_fail (sheet != NULL, NULL);
g_return_val_if_fail (IS_SHEET (sheet), NULL);
cellref.col = col;
cellref.row = row;
cell = g_hash_table_lookup (sheet->cell_hash, &cellref);
cellpos.col = col;
cellpos.row = row;
cell = g_hash_table_lookup (sheet->cell_hash, &cellpos);
return cell;
}
......@@ -1840,7 +1846,7 @@ CRowSort (gconstpointer a, gconstpointer b)
static void
sheet_cell_add_to_hash (Sheet *sheet, Cell *cell)
{
CellPos *cellref;
CellPos *cellpos;
Cell *cell_on_spot;
int left, right;
......@@ -1849,11 +1855,11 @@ sheet_cell_add_to_hash (Sheet *sheet, Cell *cell)
if (cell_on_spot)
cell_unregister_span (cell_on_spot);
cellref = g_new (CellPos, 1);
cellref->col = cell->col->pos;
cellref->row = cell->row->pos;
cellpos = g_new (CellPos, 1);
cellpos->col = cell->col->pos;
cellpos->row = cell->row->pos;
g_hash_table_insert (sheet->cell_hash, cellref, cell);
g_hash_table_insert (sheet->cell_hash, cellpos, cell);
/*
* Now register the sizes of our cells
......@@ -1908,15 +1914,15 @@ sheet_cell_new (Sheet *sheet, int col, int row)
static void
sheet_cell_remove_from_hash (Sheet *sheet, Cell *cell)
{
CellPos cellref;
CellPos cellpos;
void *original_key;
cellref.col = cell->col->pos;
cellref.row = cell->row->pos;
cellpos.col = cell->col->pos;
cellpos.row = cell->row->pos;
cell_unregister_span (cell);
g_hash_table_lookup_extended (sheet->cell_hash, &cellref, &original_key, NULL);
g_hash_table_remove (sheet->cell_hash, &cellref);
g_hash_table_lookup_extended (sheet->cell_hash, &cellpos, &original_key, NULL);
g_hash_table_remove (sheet->cell_hash, &cellpos);
g_free (original_key);
}
......@@ -2432,7 +2438,6 @@ void
sheet_insert_col (Sheet *sheet, int col, int count)
{
GList *cur_col, *deps;
CellPos cellref;
int col_count;
g_return_if_fail (sheet != NULL);
......@@ -2457,7 +2462,6 @@ sheet_insert_col (Sheet *sheet, int col, int count)
break;
/* 1.1 Move every cell on this column count positions */
cellref.col = ci->pos;
new_column = ci->pos + count;
if (new_column > SHEET_MAX_COLS-1){
......@@ -3143,3 +3147,53 @@ sheet_show_cursor (Sheet *sheet)
sheet_view_show_cursor (sheet_view);
}
}
char *
cellref_name (CellRef *cell_ref, Sheet *eval_sheet, int eval_col, int eval_row)
{
static char buffer [sizeof (long) * 4];
char *p = buffer;
int col, row;
if (cell_ref->col_relative)
col = eval_col + cell_ref->col;
else {
*p++ = '$';
col = cell_ref->col;
}
if (col <= 'Z'-'A'){
*p++ = col + 'A';
} else {
int a = col / ('Z'-'A'+1);
int b = col % ('Z'-'A'+1);
*p++ = a + 'A' - 1;
*p++ = b + 'A';
}
if (cell_ref->row_relative)
row = eval_row + cell_ref->row;
else {
*p++ = '$';
row = cell_ref->row;
}
sprintf (p, "%d", row+1);
/* If it is a non-local reference, add the path to the external sheet */
if (cell_ref->sheet == eval_sheet || cell_ref->sheet == NULL)
return g_strdup (buffer);
else {
Sheet *sheet = cell_ref->sheet;
char *s;
if (strchr (sheet->name, ' '))
s = g_copy_strings ("'", sheet->name, "'!", buffer, NULL);
else
s = g_copy_strings (sheet->name, "!", buffer, NULL);
return s;
}
}
......@@ -333,6 +333,11 @@ void sheet_fill_selection_with (Sheet *sheet, char *text);
void sheet_show_cursor (Sheet *sheet);
void sheet_hide_cursor (Sheet *sheet);
char *cellref_name (CellRef *cell_ref,
Sheet *eval_sheet,
int eval_col,
int eval_row);
/*
* Workbook
*/
......
......@@ -30,7 +30,7 @@ main ()
for (i = 0; exp [i]; i++){
printf ("Expression: %s; ", exp [i]);
node = expr_parse_string (exp [i], 0, 0, NULL, &error);
node = expr_parse_string (exp [i], 0, 0, 0, NULL, &error);
if (node == NULL){
printf ("parse error: %s\n", error);
continue;
......
......@@ -90,41 +90,6 @@ cell_name (int col, int row)
return buffer;
}
char *
cellref_name (CellRef *cell_ref, int eval_col, int eval_row)
{
static char buffer [sizeof (long) * 4];
char *p = buffer;
int col, row;
if (cell_ref->col_relative)
col = eval_col + cell_ref->col;
else {
*p++ = '$';
col = cell_ref->col;
}
if (col <= 'Z'-'A'){
*p++ = col + 'A';
} else {
int a = col / ('Z'-'A'+1);
int b = col % ('Z'-'A'+1);
*p++ = a + 'A' - 1;
*p++ = b + 'A';
}
if (cell_ref->row_relative)
row = eval_row + cell_ref->row;
else {
*p++ = '$';
row = cell_ref->row;
}
sprintf (p, "%d", row+1);
return buffer;
}
char *
col_name (int col)
{
......
......@@ -6,8 +6,6 @@ void int_get_from_range (char *start, char *end, int_t *t);
void float_get_from_range (char *start, char *end, float_t *t);
char *cell_name (int col, int row);
char *cellref_name (CellRef *cell_ref, int eval_col, int eval_row);
int parse_cell_name (char *cell_str, int *col, int *row);
char *col_name (int col);
......
......@@ -1040,7 +1040,7 @@ workbook_set_auto_expr (Workbook *wb, char *description, char *expression)
expr_tree_unref (wb->auto_expr);
string_unref (wb->auto_expr_desc);
}
wb->auto_expr = expr_parse_string (expression, 0, 0, NULL, &error);
wb->auto_expr = expr_parse_string (expression, 0, 0, 0, NULL, &error);
wb->auto_expr_desc = string_get (description);
return error;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment