gdb: rename cfunc to simple_func
After browsing the CLI code for quite a while and trying really hard, I reached the conclusion that I can't give a meaningful explanation of what "sfunc" and "cfunc" functions are, in cmd_list_element. I don't see a logic at all. That makes it very difficult to do any kind of change. Unless somebody can make sense out of all that, I'd like to try to retro-fit some logic in the cmd_list_element callback function code so that we can understand what is going on, do some cleanups and add new features. The first change is about "cfunc". I can't figure out what the "c" in cfunc means. It's not const, because there's already "const" in "cmd_const_cfunc_ftype", and the previous "cmd_cfunc_ftype" had nothing const.. It's not "cmd" or "command", because there's already "cmd" in "cmd_const_cfunc_ftype". The "main" command callback, cmd_list_element::func, has three parameters, whereas cfunc has two. It is missing the cmd_list_element parameter. So the only reason I see for cfunc to exist is to be a shim between the three and two parameter versions. Most commands don't need to receive the cmd_list_element object, so adding it everywhere would be long and would just add more unnecessary boilerplate. So since this is the "simple" version of the callback, compared to the "full", I suggest renaming cmd_const_cfunc_ftype into cmd_simple_func_ftype, as well as everything (like the utility functions) that goes with it. Change-Id: I4e46cacfd77a66bc1cbf683f6a362072504b7868
This commit is contained in:
parent
4e93ea6e67
commit
3a553c80da
5 changed files with 53 additions and 44 deletions
|
@ -443,7 +443,7 @@ complete_command (const char *arg, int from_tty)
|
||||||
int
|
int
|
||||||
is_complete_command (struct cmd_list_element *c)
|
is_complete_command (struct cmd_list_element *c)
|
||||||
{
|
{
|
||||||
return cmd_cfunc_eq (c, complete_command);
|
return cmd_simple_func_eq (c, complete_command);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -94,22 +94,23 @@ print_help_for_command (struct cmd_list_element *c,
|
||||||
|
|
||||||
/* Set the callback function for the specified command. For each both
|
/* Set the callback function for the specified command. For each both
|
||||||
the commands callback and func() are set. The latter set to a
|
the commands callback and func() are set. The latter set to a
|
||||||
bounce function (unless cfunc / sfunc is NULL that is). */
|
bounce function (unless simple_func / sfunc is NULL that is). */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_const_cfunc (struct cmd_list_element *c, const char *args, int from_tty)
|
do_simple_func (struct cmd_list_element *c, const char *args, int from_tty)
|
||||||
{
|
{
|
||||||
c->function.const_cfunc (args, from_tty);
|
c->function.simple_func (args, from_tty);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_cmd_cfunc (struct cmd_list_element *cmd, cmd_const_cfunc_ftype *cfunc)
|
set_cmd_simple_func (struct cmd_list_element *cmd, cmd_simple_func_ftype *simple_func)
|
||||||
{
|
{
|
||||||
if (cfunc == NULL)
|
if (simple_func == NULL)
|
||||||
cmd->func = NULL;
|
cmd->func = NULL;
|
||||||
else
|
else
|
||||||
cmd->func = do_const_cfunc;
|
cmd->func = do_simple_func;
|
||||||
cmd->function.const_cfunc = cfunc;
|
|
||||||
|
cmd->function.simple_func = simple_func;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -129,9 +130,10 @@ set_cmd_sfunc (struct cmd_list_element *cmd, cmd_const_sfunc_ftype *sfunc)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
cmd_cfunc_eq (struct cmd_list_element *cmd, cmd_const_cfunc_ftype *cfunc)
|
cmd_simple_func_eq (struct cmd_list_element *cmd, cmd_simple_func_ftype *simple_func)
|
||||||
{
|
{
|
||||||
return cmd->func == do_const_cfunc && cmd->function.const_cfunc == cfunc;
|
return (cmd->func == do_simple_func
|
||||||
|
&& cmd->function.simple_func == simple_func);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -238,17 +240,17 @@ add_cmd (const char *name, enum command_class theclass,
|
||||||
{
|
{
|
||||||
cmd_list_element *result = do_add_cmd (name, theclass, doc, list);
|
cmd_list_element *result = do_add_cmd (name, theclass, doc, list);
|
||||||
result->func = NULL;
|
result->func = NULL;
|
||||||
result->function.const_cfunc = NULL;
|
result->function.simple_func = NULL;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cmd_list_element *
|
struct cmd_list_element *
|
||||||
add_cmd (const char *name, enum command_class theclass,
|
add_cmd (const char *name, enum command_class theclass,
|
||||||
cmd_const_cfunc_ftype *fun,
|
cmd_simple_func_ftype *fun,
|
||||||
const char *doc, struct cmd_list_element **list)
|
const char *doc, struct cmd_list_element **list)
|
||||||
{
|
{
|
||||||
cmd_list_element *result = do_add_cmd (name, theclass, doc, list);
|
cmd_list_element *result = do_add_cmd (name, theclass, doc, list);
|
||||||
set_cmd_cfunc (result, fun);
|
set_cmd_simple_func (result, fun);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +258,7 @@ add_cmd (const char *name, enum command_class theclass,
|
||||||
|
|
||||||
struct cmd_list_element *
|
struct cmd_list_element *
|
||||||
add_cmd_suppress_notification (const char *name, enum command_class theclass,
|
add_cmd_suppress_notification (const char *name, enum command_class theclass,
|
||||||
cmd_const_cfunc_ftype *fun, const char *doc,
|
cmd_simple_func_ftype *fun, const char *doc,
|
||||||
struct cmd_list_element **list,
|
struct cmd_list_element **list,
|
||||||
int *suppress_notification)
|
int *suppress_notification)
|
||||||
{
|
{
|
||||||
|
@ -359,7 +361,7 @@ update_prefix_field_of_prefixed_commands (struct cmd_list_element *c)
|
||||||
|
|
||||||
struct cmd_list_element *
|
struct cmd_list_element *
|
||||||
add_prefix_cmd (const char *name, enum command_class theclass,
|
add_prefix_cmd (const char *name, enum command_class theclass,
|
||||||
cmd_const_cfunc_ftype *fun,
|
cmd_simple_func_ftype *fun,
|
||||||
const char *doc, struct cmd_list_element **subcommands,
|
const char *doc, struct cmd_list_element **subcommands,
|
||||||
int allow_unknown, struct cmd_list_element **list)
|
int allow_unknown, struct cmd_list_element **list)
|
||||||
{
|
{
|
||||||
|
@ -432,7 +434,7 @@ add_show_prefix_cmd (const char *name, enum command_class theclass,
|
||||||
struct cmd_list_element *
|
struct cmd_list_element *
|
||||||
add_prefix_cmd_suppress_notification
|
add_prefix_cmd_suppress_notification
|
||||||
(const char *name, enum command_class theclass,
|
(const char *name, enum command_class theclass,
|
||||||
cmd_const_cfunc_ftype *fun,
|
cmd_simple_func_ftype *fun,
|
||||||
const char *doc, struct cmd_list_element **subcommands,
|
const char *doc, struct cmd_list_element **subcommands,
|
||||||
int allow_unknown, struct cmd_list_element **list,
|
int allow_unknown, struct cmd_list_element **list,
|
||||||
int *suppress_notification)
|
int *suppress_notification)
|
||||||
|
@ -448,7 +450,7 @@ add_prefix_cmd_suppress_notification
|
||||||
|
|
||||||
struct cmd_list_element *
|
struct cmd_list_element *
|
||||||
add_abbrev_prefix_cmd (const char *name, enum command_class theclass,
|
add_abbrev_prefix_cmd (const char *name, enum command_class theclass,
|
||||||
cmd_const_cfunc_ftype *fun, const char *doc,
|
cmd_simple_func_ftype *fun, const char *doc,
|
||||||
struct cmd_list_element **subcommands,
|
struct cmd_list_element **subcommands,
|
||||||
int allow_unknown, struct cmd_list_element **list)
|
int allow_unknown, struct cmd_list_element **list)
|
||||||
{
|
{
|
||||||
|
@ -460,7 +462,7 @@ add_abbrev_prefix_cmd (const char *name, enum command_class theclass,
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is an empty "cfunc". */
|
/* This is an empty "simple func". */
|
||||||
void
|
void
|
||||||
not_just_help_class_command (const char *args, int from_tty)
|
not_just_help_class_command (const char *args, int from_tty)
|
||||||
{
|
{
|
||||||
|
@ -951,7 +953,7 @@ delete_cmd (const char *name, struct cmd_list_element **list,
|
||||||
/* Add an element to the list of info subcommands. */
|
/* Add an element to the list of info subcommands. */
|
||||||
|
|
||||||
struct cmd_list_element *
|
struct cmd_list_element *
|
||||||
add_info (const char *name, cmd_const_cfunc_ftype *fun, const char *doc)
|
add_info (const char *name, cmd_simple_func_ftype *fun, const char *doc)
|
||||||
{
|
{
|
||||||
return add_cmd (name, class_info, fun, doc, &infolist);
|
return add_cmd (name, class_info, fun, doc, &infolist);
|
||||||
}
|
}
|
||||||
|
@ -968,7 +970,7 @@ add_info_alias (const char *name, cmd_list_element *target, int abbrev_flag)
|
||||||
|
|
||||||
struct cmd_list_element *
|
struct cmd_list_element *
|
||||||
add_com (const char *name, enum command_class theclass,
|
add_com (const char *name, enum command_class theclass,
|
||||||
cmd_const_cfunc_ftype *fun,
|
cmd_simple_func_ftype *fun,
|
||||||
const char *doc)
|
const char *doc)
|
||||||
{
|
{
|
||||||
return add_cmd (name, theclass, fun, doc, &cmdlist);
|
return add_cmd (name, theclass, fun, doc, &cmdlist);
|
||||||
|
@ -990,7 +992,7 @@ add_com_alias (const char *name, cmd_list_element *target,
|
||||||
|
|
||||||
struct cmd_list_element *
|
struct cmd_list_element *
|
||||||
add_com_suppress_notification (const char *name, enum command_class theclass,
|
add_com_suppress_notification (const char *name, enum command_class theclass,
|
||||||
cmd_const_cfunc_ftype *fun, const char *doc,
|
cmd_simple_func_ftype *fun, const char *doc,
|
||||||
int *suppress_notification)
|
int *suppress_notification)
|
||||||
{
|
{
|
||||||
return add_cmd_suppress_notification (name, theclass, fun, doc,
|
return add_cmd_suppress_notification (name, theclass, fun, doc,
|
||||||
|
@ -2167,5 +2169,5 @@ int
|
||||||
cli_user_command_p (struct cmd_list_element *cmd)
|
cli_user_command_p (struct cmd_list_element *cmd)
|
||||||
{
|
{
|
||||||
return (cmd->theclass == class_user
|
return (cmd->theclass == class_user
|
||||||
&& (cmd->func == do_const_cfunc || cmd->func == do_sfunc));
|
&& (cmd->func == do_simple_func || cmd->func == do_sfunc));
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,8 +174,12 @@ struct cmd_list_element
|
||||||
to one of the below. */
|
to one of the below. */
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
/* If type is not_set_cmd, call it like this: */
|
/* Most commands don't need the cmd_list_element parameter passed to FUNC.
|
||||||
cmd_const_cfunc_ftype *const_cfunc;
|
They therefore register a command of this type, which doesn't have the
|
||||||
|
cmd_list_element parameter. do_simple_func is installed as FUNC, and
|
||||||
|
acts as a shim between the two. */
|
||||||
|
cmd_simple_func_ftype *simple_func;
|
||||||
|
|
||||||
/* If type is set_cmd or show_cmd, first set the variables,
|
/* If type is set_cmd or show_cmd, first set the variables,
|
||||||
and then call this: */
|
and then call this: */
|
||||||
cmd_const_sfunc_ftype *sfunc;
|
cmd_const_sfunc_ftype *sfunc;
|
||||||
|
|
|
@ -128,7 +128,10 @@ var_types;
|
||||||
/* This structure records one command'd definition. */
|
/* This structure records one command'd definition. */
|
||||||
struct cmd_list_element;
|
struct cmd_list_element;
|
||||||
|
|
||||||
typedef void cmd_const_cfunc_ftype (const char *args, int from_tty);
|
/* The "simple" signature of command callbacks, which doesn't include a
|
||||||
|
cmd_list_element parameter. */
|
||||||
|
|
||||||
|
typedef void cmd_simple_func_ftype (const char *args, int from_tty);
|
||||||
|
|
||||||
/* This structure specifies notifications to be suppressed by a cli
|
/* This structure specifies notifications to be suppressed by a cli
|
||||||
command interpreter. */
|
command interpreter. */
|
||||||
|
@ -158,7 +161,7 @@ extern bool valid_cmd_char_p (int c);
|
||||||
/* Const-correct variant of the above. */
|
/* Const-correct variant of the above. */
|
||||||
|
|
||||||
extern struct cmd_list_element *add_cmd (const char *, enum command_class,
|
extern struct cmd_list_element *add_cmd (const char *, enum command_class,
|
||||||
cmd_const_cfunc_ftype *fun,
|
cmd_simple_func_ftype *fun,
|
||||||
const char *,
|
const char *,
|
||||||
struct cmd_list_element **);
|
struct cmd_list_element **);
|
||||||
|
|
||||||
|
@ -170,7 +173,7 @@ extern struct cmd_list_element *add_cmd (const char *, enum command_class,
|
||||||
|
|
||||||
extern struct cmd_list_element *add_cmd_suppress_notification
|
extern struct cmd_list_element *add_cmd_suppress_notification
|
||||||
(const char *name, enum command_class theclass,
|
(const char *name, enum command_class theclass,
|
||||||
cmd_const_cfunc_ftype *fun, const char *doc,
|
cmd_simple_func_ftype *fun, const char *doc,
|
||||||
struct cmd_list_element **list,
|
struct cmd_list_element **list,
|
||||||
int *suppress_notification);
|
int *suppress_notification);
|
||||||
|
|
||||||
|
@ -181,7 +184,7 @@ extern struct cmd_list_element *add_alias_cmd (const char *,
|
||||||
|
|
||||||
|
|
||||||
extern struct cmd_list_element *add_prefix_cmd (const char *, enum command_class,
|
extern struct cmd_list_element *add_prefix_cmd (const char *, enum command_class,
|
||||||
cmd_const_cfunc_ftype *fun,
|
cmd_simple_func_ftype *fun,
|
||||||
const char *,
|
const char *,
|
||||||
struct cmd_list_element **,
|
struct cmd_list_element **,
|
||||||
int,
|
int,
|
||||||
|
@ -203,7 +206,7 @@ extern struct cmd_list_element *add_show_prefix_cmd
|
||||||
|
|
||||||
extern struct cmd_list_element *add_prefix_cmd_suppress_notification
|
extern struct cmd_list_element *add_prefix_cmd_suppress_notification
|
||||||
(const char *name, enum command_class theclass,
|
(const char *name, enum command_class theclass,
|
||||||
cmd_const_cfunc_ftype *fun,
|
cmd_simple_func_ftype *fun,
|
||||||
const char *doc, struct cmd_list_element **subcommands,
|
const char *doc, struct cmd_list_element **subcommands,
|
||||||
int allow_unknown,
|
int allow_unknown,
|
||||||
struct cmd_list_element **list,
|
struct cmd_list_element **list,
|
||||||
|
@ -211,7 +214,7 @@ extern struct cmd_list_element *add_prefix_cmd_suppress_notification
|
||||||
|
|
||||||
extern struct cmd_list_element *add_abbrev_prefix_cmd (const char *,
|
extern struct cmd_list_element *add_abbrev_prefix_cmd (const char *,
|
||||||
enum command_class,
|
enum command_class,
|
||||||
cmd_const_cfunc_ftype *fun,
|
cmd_simple_func_ftype *fun,
|
||||||
const char *,
|
const char *,
|
||||||
struct cmd_list_element
|
struct cmd_list_element
|
||||||
**, int,
|
**, int,
|
||||||
|
@ -250,8 +253,8 @@ extern void set_cmd_completer_handle_brkchars (struct cmd_list_element *,
|
||||||
|
|
||||||
/* HACK: cagney/2002-02-23: Code, mostly in tracepoints.c, grubs
|
/* HACK: cagney/2002-02-23: Code, mostly in tracepoints.c, grubs
|
||||||
around in cmd objects to test the value of the commands sfunc(). */
|
around in cmd objects to test the value of the commands sfunc(). */
|
||||||
extern int cmd_cfunc_eq (struct cmd_list_element *cmd,
|
extern int cmd_simple_func_eq (struct cmd_list_element *cmd,
|
||||||
cmd_const_cfunc_ftype *cfun);
|
cmd_simple_func_ftype *cfun);
|
||||||
|
|
||||||
/* Execute CMD's pre/post hook. Throw an error if the command fails.
|
/* Execute CMD's pre/post hook. Throw an error if the command fails.
|
||||||
If already executing this pre/post hook, or there is no pre/post
|
If already executing this pre/post hook, or there is no pre/post
|
||||||
|
@ -346,7 +349,7 @@ extern int lookup_cmd_composition (const char *text,
|
||||||
struct cmd_list_element **cmd);
|
struct cmd_list_element **cmd);
|
||||||
|
|
||||||
extern struct cmd_list_element *add_com (const char *, enum command_class,
|
extern struct cmd_list_element *add_com (const char *, enum command_class,
|
||||||
cmd_const_cfunc_ftype *fun,
|
cmd_simple_func_ftype *fun,
|
||||||
const char *);
|
const char *);
|
||||||
|
|
||||||
extern cmd_list_element *add_com_alias (const char *name,
|
extern cmd_list_element *add_com_alias (const char *name,
|
||||||
|
@ -356,11 +359,11 @@ extern cmd_list_element *add_com_alias (const char *name,
|
||||||
|
|
||||||
extern struct cmd_list_element *add_com_suppress_notification
|
extern struct cmd_list_element *add_com_suppress_notification
|
||||||
(const char *name, enum command_class theclass,
|
(const char *name, enum command_class theclass,
|
||||||
cmd_const_cfunc_ftype *fun, const char *doc,
|
cmd_simple_func_ftype *fun, const char *doc,
|
||||||
int *supress_notification);
|
int *supress_notification);
|
||||||
|
|
||||||
extern struct cmd_list_element *add_info (const char *,
|
extern struct cmd_list_element *add_info (const char *,
|
||||||
cmd_const_cfunc_ftype *fun,
|
cmd_simple_func_ftype *fun,
|
||||||
const char *);
|
const char *);
|
||||||
|
|
||||||
extern cmd_list_element *add_info_alias (const char *name,
|
extern cmd_list_element *add_info_alias (const char *name,
|
||||||
|
|
|
@ -655,7 +655,7 @@ validate_actionline (const char *line, struct breakpoint *b)
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
error (_("`%s' is not a tracepoint action, or is ambiguous."), p);
|
error (_("`%s' is not a tracepoint action, or is ambiguous."), p);
|
||||||
|
|
||||||
if (cmd_cfunc_eq (c, collect_pseudocommand))
|
if (cmd_simple_func_eq (c, collect_pseudocommand))
|
||||||
{
|
{
|
||||||
int trace_string = 0;
|
int trace_string = 0;
|
||||||
|
|
||||||
|
@ -723,7 +723,7 @@ validate_actionline (const char *line, struct breakpoint *b)
|
||||||
while (p && *p++ == ',');
|
while (p && *p++ == ',');
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (cmd_cfunc_eq (c, teval_pseudocommand))
|
else if (cmd_simple_func_eq (c, teval_pseudocommand))
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{ /* Repeat over a comma-separated list. */
|
{ /* Repeat over a comma-separated list. */
|
||||||
|
@ -750,7 +750,7 @@ validate_actionline (const char *line, struct breakpoint *b)
|
||||||
while (p && *p++ == ',');
|
while (p && *p++ == ',');
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (cmd_cfunc_eq (c, while_stepping_pseudocommand))
|
else if (cmd_simple_func_eq (c, while_stepping_pseudocommand))
|
||||||
{
|
{
|
||||||
char *endp;
|
char *endp;
|
||||||
|
|
||||||
|
@ -761,7 +761,7 @@ validate_actionline (const char *line, struct breakpoint *b)
|
||||||
p = endp;
|
p = endp;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (cmd_cfunc_eq (c, end_actions_pseudocommand))
|
else if (cmd_simple_func_eq (c, end_actions_pseudocommand))
|
||||||
;
|
;
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -1308,7 +1308,7 @@ encode_actions_1 (struct command_line *action,
|
||||||
if (cmd == 0)
|
if (cmd == 0)
|
||||||
error (_("Bad action list item: %s"), action_exp);
|
error (_("Bad action list item: %s"), action_exp);
|
||||||
|
|
||||||
if (cmd_cfunc_eq (cmd, collect_pseudocommand))
|
if (cmd_simple_func_eq (cmd, collect_pseudocommand))
|
||||||
{
|
{
|
||||||
int trace_string = 0;
|
int trace_string = 0;
|
||||||
|
|
||||||
|
@ -1464,7 +1464,7 @@ encode_actions_1 (struct command_line *action,
|
||||||
}
|
}
|
||||||
while (action_exp && *action_exp++ == ',');
|
while (action_exp && *action_exp++ == ',');
|
||||||
} /* if */
|
} /* if */
|
||||||
else if (cmd_cfunc_eq (cmd, teval_pseudocommand))
|
else if (cmd_simple_func_eq (cmd, teval_pseudocommand))
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{ /* Repeat over a comma-separated list. */
|
{ /* Repeat over a comma-separated list. */
|
||||||
|
@ -1488,7 +1488,7 @@ encode_actions_1 (struct command_line *action,
|
||||||
}
|
}
|
||||||
while (action_exp && *action_exp++ == ',');
|
while (action_exp && *action_exp++ == ',');
|
||||||
} /* if */
|
} /* if */
|
||||||
else if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
|
else if (cmd_simple_func_eq (cmd, while_stepping_pseudocommand))
|
||||||
{
|
{
|
||||||
/* We check against nested while-stepping when setting
|
/* We check against nested while-stepping when setting
|
||||||
breakpoint action, so no way to run into nested
|
breakpoint action, so no way to run into nested
|
||||||
|
@ -2690,13 +2690,13 @@ trace_dump_actions (struct command_line *action,
|
||||||
if (cmd == 0)
|
if (cmd == 0)
|
||||||
error (_("Bad action list item: %s"), action_exp);
|
error (_("Bad action list item: %s"), action_exp);
|
||||||
|
|
||||||
if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
|
if (cmd_simple_func_eq (cmd, while_stepping_pseudocommand))
|
||||||
{
|
{
|
||||||
gdb_assert (action->body_list_1 == nullptr);
|
gdb_assert (action->body_list_1 == nullptr);
|
||||||
trace_dump_actions (action->body_list_0.get (),
|
trace_dump_actions (action->body_list_0.get (),
|
||||||
1, stepping_frame, from_tty);
|
1, stepping_frame, from_tty);
|
||||||
}
|
}
|
||||||
else if (cmd_cfunc_eq (cmd, collect_pseudocommand))
|
else if (cmd_simple_func_eq (cmd, collect_pseudocommand))
|
||||||
{
|
{
|
||||||
/* Display the collected data.
|
/* Display the collected data.
|
||||||
For the trap frame, display only what was collected at
|
For the trap frame, display only what was collected at
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue