2010-04-14 00:37:53

by Frederic Weisbecker

[permalink] [raw]
Subject: [PATCH] perf: Fix accidentally preprocessed snprintf callback

struct sort_entry has a callback named snprintf that turns an
entry into a string result.

But there are glibc versions that implement snprintf through a
macro. The following expression is then going to get the snprintf
call preprocessed:

ent->snprintf(...)

to finally end up in a build error:

util/hist.c: Dans la fonction «hist_entry__snprintf» :
util/hist.c:539: erreur: «struct sort_entry» has no member named «__builtin___snprintf_chk»

To fix this, rename struct sort_entry::snprintf() callback to
to_string(), assuming at least Java methods naming won't ever
conflict with perf.

Signed-off-by: Frederic Weisbecker <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Ingo Molnar <[email protected]>
---
tools/perf/util/hist.c | 4 ++--
tools/perf/util/sort.c | 10 +++++-----
tools/perf/util/sort.h | 4 ++--
3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 18cf8b3..d07eccd 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -536,8 +536,8 @@ int hist_entry__snprintf(struct hist_entry *self,
continue;

ret += snprintf(s + ret, size - ret, "%s", sep ?: " ");
- ret += se->snprintf(self, s + ret, size - ret,
- se->width ? *se->width : 0);
+ ret += se->to_string(self, s + ret, size - ret,
+ se->width ? *se->width : 0);
}

return ret;
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 9d24d4b..b8acf51 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -32,7 +32,7 @@ static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf,
struct sort_entry sort_thread = {
.header = "Command: Pid",
.cmp = sort__thread_cmp,
- .snprintf = hist_entry__thread_snprintf,
+ .to_string = hist_entry__thread_snprintf,
.width = &threads__col_width,
};

@@ -40,27 +40,27 @@ struct sort_entry sort_comm = {
.header = "Command",
.cmp = sort__comm_cmp,
.collapse = sort__comm_collapse,
- .snprintf = hist_entry__comm_snprintf,
+ .to_string = hist_entry__comm_snprintf,
.width = &comms__col_width,
};

struct sort_entry sort_dso = {
.header = "Shared Object",
.cmp = sort__dso_cmp,
- .snprintf = hist_entry__dso_snprintf,
+ .to_string = hist_entry__dso_snprintf,
.width = &dsos__col_width,
};

struct sort_entry sort_sym = {
.header = "Symbol",
.cmp = sort__sym_cmp,
- .snprintf = hist_entry__sym_snprintf,
+ .to_string = hist_entry__sym_snprintf,
};

struct sort_entry sort_parent = {
.header = "Parent symbol",
.cmp = sort__parent_cmp,
- .snprintf = hist_entry__parent_snprintf,
+ .to_string = hist_entry__parent_snprintf,
.width = &parent_symbol__col_width,
};

diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 6d7b4be..3a29fb5 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -82,8 +82,8 @@ struct sort_entry {

int64_t (*cmp)(struct hist_entry *, struct hist_entry *);
int64_t (*collapse)(struct hist_entry *, struct hist_entry *);
- int (*snprintf)(struct hist_entry *self, char *bf, size_t size,
- unsigned int width);
+ int (*to_string)(struct hist_entry *self, char *bf, size_t size,
+ unsigned int width);
unsigned int *width;
bool elide;
};
--
1.6.2.3


2010-04-14 00:41:19

by Frederic Weisbecker

[permalink] [raw]
Subject: Re: [PATCH] perf: Fix accidentally preprocessed snprintf callback

On Wed, Apr 14, 2010 at 02:37:48AM +0200, Frederic Weisbecker wrote:
> struct sort_entry has a callback named snprintf that turns an
> entry into a string result.
>
> But there are glibc versions that implement snprintf through a
> macro. The following expression is then going to get the snprintf
> call preprocessed:
>
> ent->snprintf(...)
>
> to finally end up in a build error:
>
> util/hist.c: Dans la fonction ?hist_entry__snprintf? :
> util/hist.c:539: erreur: ?struct sort_entry? has no member named ?__builtin___snprintf_chk?
>
> To fix this, rename struct sort_entry::snprintf() callback to
> to_string(), assuming at least Java methods naming won't ever
> conflict with perf.


Note I'm not entirely happy with this to_string() renaming.
May be append_string() would have been better. I don't know.
snprintf() was just too good.
If you think about something else, don't hesistate to change,
or I can change it myself if you want.

Thanks.

2010-04-14 02:28:11

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: [PATCH] perf: Fix accidentally preprocessed snprintf callback

Em Wed, Apr 14, 2010 at 02:41:16AM +0200, Frederic Weisbecker escreveu:
> On Wed, Apr 14, 2010 at 02:37:48AM +0200, Frederic Weisbecker wrote:
> > struct sort_entry has a callback named snprintf that turns an
> > entry into a string result.
> >
> > But there are glibc versions that implement snprintf through a
> > macro. The following expression is then going to get the snprintf
> > call preprocessed:
> >
> > ent->snprintf(...)
> >
> > to finally end up in a build error:
> >
> > util/hist.c: Dans la fonction ?hist_entry__snprintf? :
> > util/hist.c:539: erreur: ?struct sort_entry? has no member named ?__builtin___snprintf_chk?
> >
> > To fix this, rename struct sort_entry::snprintf() callback to
> > to_string(), assuming at least Java methods naming won't ever
> > conflict with perf.
>
>
> Note I'm not entirely happy with this to_string() renaming.
> May be append_string() would have been better. I don't know.
> snprintf() was just too good.
> If you think about something else, don't hesistate to change,
> or I can change it myself if you want.

psnprintf() I guess, the intent was exactly to mean that it is indeed
similar to snprintf... dammit, there is already a psnprintf out there
:-\

Perhaps just do it as ->he_snprintf and have the other methods as well
prefixed with he as a shorthand for hist_entry, that is what the methods
operate, besides the string, ok?

- Arnaldo

2010-04-14 14:55:35

by Frederic Weisbecker

[permalink] [raw]
Subject: Re: [PATCH] perf: Fix accidentally preprocessed snprintf callback

On Tue, Apr 13, 2010 at 11:28:00PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Wed, Apr 14, 2010 at 02:41:16AM +0200, Frederic Weisbecker escreveu:
> > On Wed, Apr 14, 2010 at 02:37:48AM +0200, Frederic Weisbecker wrote:
> > > struct sort_entry has a callback named snprintf that turns an
> > > entry into a string result.
> > >
> > > But there are glibc versions that implement snprintf through a
> > > macro. The following expression is then going to get the snprintf
> > > call preprocessed:
> > >
> > > ent->snprintf(...)
> > >
> > > to finally end up in a build error:
> > >
> > > util/hist.c: Dans la fonction ?hist_entry__snprintf? :
> > > util/hist.c:539: erreur: ?struct sort_entry? has no member named ?__builtin___snprintf_chk?
> > >
> > > To fix this, rename struct sort_entry::snprintf() callback to
> > > to_string(), assuming at least Java methods naming won't ever
> > > conflict with perf.
> >
> >
> > Note I'm not entirely happy with this to_string() renaming.
> > May be append_string() would have been better. I don't know.
> > snprintf() was just too good.
> > If you think about something else, don't hesistate to change,
> > or I can change it myself if you want.
>
> psnprintf() I guess, the intent was exactly to mean that it is indeed
> similar to snprintf... dammit, there is already a psnprintf out there
> :-\
>
> Perhaps just do it as ->he_snprintf and have the other methods as well
> prefixed with he as a shorthand for hist_entry, that is what the methods
> operate, besides the string, ok?


Sure, I'll resend.

This is going to be se_sprintf() though, as it's about sort_entry, not
hist_entry :)

Thanks.

2010-04-14 17:09:42

by Frederic Weisbecker

[permalink] [raw]
Subject: [PATCH v2] struct sort_entry has a callback named snprintf that turns an entry into a string result.

But there are glibc versions that implement snprintf through a
macro. The following expression is then going to get the snprintf
call preprocessed:

ent->snprintf(...)

to finally end up in a build error:

util/hist.c: Dans la fonction «hist_entry__snprintf» :
util/hist.c:539: erreur: «struct sort_entry» has no member named «__builtin___snprintf_chk»

To fix this, prepend struct sort_entry callbacks with an "se_"
prefix.

Signed-off-by: Frederic Weisbecker <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Ingo Molnar <[email protected]>
---
tools/perf/util/hist.c | 28 ++++++++++++++--------------
tools/perf/util/sort.c | 42 +++++++++++++++++++++---------------------
tools/perf/util/sort.h | 12 ++++++------
3 files changed, 41 insertions(+), 41 deletions(-)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 18cf8b3..9c2b874 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -68,7 +68,7 @@ hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)
int64_t cmp = 0;

list_for_each_entry(se, &hist_entry__sort_list, list) {
- cmp = se->cmp(left, right);
+ cmp = se->se_cmp(left, right);
if (cmp)
break;
}
@@ -85,7 +85,7 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
list_for_each_entry(se, &hist_entry__sort_list, list) {
int64_t (*f)(struct hist_entry *, struct hist_entry *);

- f = se->collapse ?: se->cmp;
+ f = se->se_collapse ?: se->se_cmp;

cmp = f(left, right);
if (cmp)
@@ -536,8 +536,8 @@ int hist_entry__snprintf(struct hist_entry *self,
continue;

ret += snprintf(s + ret, size - ret, "%s", sep ?: " ");
- ret += se->snprintf(self, s + ret, size - ret,
- se->width ? *se->width : 0);
+ ret += se->se_snprintf(self, s + ret, size - ret,
+ se->se_width ? *se->se_width : 0);
}

return ret;
@@ -564,7 +564,7 @@ static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp,
if (sort__first_dimension == SORT_COMM) {
struct sort_entry *se = list_first_entry(&hist_entry__sort_list,
typeof(*se), list);
- left_margin = se->width ? *se->width : 0;
+ left_margin = se->se_width ? *se->se_width : 0;
left_margin -= thread__comm_len(self->thread);
}

@@ -615,22 +615,22 @@ size_t perf_session__fprintf_hists(struct rb_root *hists,
if (se->elide)
continue;
if (sep) {
- fprintf(fp, "%c%s", *sep, se->header);
+ fprintf(fp, "%c%s", *sep, se->se_header);
continue;
}
- width = strlen(se->header);
- if (se->width) {
+ width = strlen(se->se_header);
+ if (se->se_width) {
if (symbol_conf.col_width_list_str) {
if (col_width) {
- *se->width = atoi(col_width);
+ *se->se_width = atoi(col_width);
col_width = strchr(col_width, ',');
if (col_width)
++col_width;
}
}
- width = *se->width = max(*se->width, width);
+ width = *se->se_width = max(*se->se_width, width);
}
- fprintf(fp, " %*s", width, se->header);
+ fprintf(fp, " %*s", width, se->se_header);
}
fprintf(fp, "\n");

@@ -652,10 +652,10 @@ size_t perf_session__fprintf_hists(struct rb_root *hists,
continue;

fprintf(fp, " ");
- if (se->width)
- width = *se->width;
+ if (se->se_width)
+ width = *se->se_width;
else
- width = strlen(se->header);
+ width = strlen(se->se_header);
for (i = 0; i < width; i++)
fprintf(fp, ".");
}
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 9d24d4b..da30b30 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -30,38 +30,38 @@ static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf,
size_t size, unsigned int width);

struct sort_entry sort_thread = {
- .header = "Command: Pid",
- .cmp = sort__thread_cmp,
- .snprintf = hist_entry__thread_snprintf,
- .width = &threads__col_width,
+ .se_header = "Command: Pid",
+ .se_cmp = sort__thread_cmp,
+ .se_snprintf = hist_entry__thread_snprintf,
+ .se_width = &threads__col_width,
};

struct sort_entry sort_comm = {
- .header = "Command",
- .cmp = sort__comm_cmp,
- .collapse = sort__comm_collapse,
- .snprintf = hist_entry__comm_snprintf,
- .width = &comms__col_width,
+ .se_header = "Command",
+ .se_cmp = sort__comm_cmp,
+ .se_collapse = sort__comm_collapse,
+ .se_snprintf = hist_entry__comm_snprintf,
+ .se_width = &comms__col_width,
};

struct sort_entry sort_dso = {
- .header = "Shared Object",
- .cmp = sort__dso_cmp,
- .snprintf = hist_entry__dso_snprintf,
- .width = &dsos__col_width,
+ .se_header = "Shared Object",
+ .se_cmp = sort__dso_cmp,
+ .se_snprintf = hist_entry__dso_snprintf,
+ .se_width = &dsos__col_width,
};

struct sort_entry sort_sym = {
- .header = "Symbol",
- .cmp = sort__sym_cmp,
- .snprintf = hist_entry__sym_snprintf,
+ .se_header = "Symbol",
+ .se_cmp = sort__sym_cmp,
+ .se_snprintf = hist_entry__sym_snprintf,
};

struct sort_entry sort_parent = {
- .header = "Parent symbol",
- .cmp = sort__parent_cmp,
- .snprintf = hist_entry__parent_snprintf,
- .width = &parent_symbol__col_width,
+ .se_header = "Parent symbol",
+ .se_cmp = sort__parent_cmp,
+ .se_snprintf = hist_entry__parent_snprintf,
+ .se_width = &parent_symbol__col_width,
};

struct sort_dimension {
@@ -255,7 +255,7 @@ int sort_dimension__add(const char *tok)
if (strncasecmp(tok, sd->name, strlen(tok)))
continue;

- if (sd->entry->collapse)
+ if (sd->entry->se_collapse)
sort__need_collapse = 1;

if (sd->entry == &sort_parent) {
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 6d7b4be..1d857aa 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -78,13 +78,13 @@ enum sort_type {
struct sort_entry {
struct list_head list;

- const char *header;
+ const char *se_header;

- int64_t (*cmp)(struct hist_entry *, struct hist_entry *);
- int64_t (*collapse)(struct hist_entry *, struct hist_entry *);
- int (*snprintf)(struct hist_entry *self, char *bf, size_t size,
- unsigned int width);
- unsigned int *width;
+ int64_t (*se_cmp)(struct hist_entry *, struct hist_entry *);
+ int64_t (*se_collapse)(struct hist_entry *, struct hist_entry *);
+ int (*se_snprintf)(struct hist_entry *self, char *bf, size_t size,
+ unsigned int width);
+ unsigned int *se_width;
bool elide;
};

--
1.6.2.3

2010-04-14 17:11:35

by Frederic Weisbecker

[permalink] [raw]
Subject: [PATCH v3] perf: Fix accidentally preprocessed snprintf callback

struct sort_entry has a callback named snprintf that turns an
entry into a string result.
But there are glibc versions that implement snprintf through a
macro. The following expression is then going to get the snprintf
call preprocessed:

ent->snprintf(...)

to finally end up in a build error:

util/hist.c: Dans la fonction «hist_entry__snprintf» :
util/hist.c:539: erreur: «struct sort_entry» has no member named «__builtin___snprintf_chk»

To fix this, prepend struct sort_entry callbacks with an "se_"
prefix.

Signed-off-by: Frederic Weisbecker <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Ingo Molnar <[email protected]>
---
tools/perf/util/hist.c | 28 ++++++++++++++--------------
tools/perf/util/sort.c | 42 +++++++++++++++++++++---------------------
tools/perf/util/sort.h | 12 ++++++------
3 files changed, 41 insertions(+), 41 deletions(-)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 18cf8b3..9c2b874 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -68,7 +68,7 @@ hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)
int64_t cmp = 0;

list_for_each_entry(se, &hist_entry__sort_list, list) {
- cmp = se->cmp(left, right);
+ cmp = se->se_cmp(left, right);
if (cmp)
break;
}
@@ -85,7 +85,7 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
list_for_each_entry(se, &hist_entry__sort_list, list) {
int64_t (*f)(struct hist_entry *, struct hist_entry *);

- f = se->collapse ?: se->cmp;
+ f = se->se_collapse ?: se->se_cmp;

cmp = f(left, right);
if (cmp)
@@ -536,8 +536,8 @@ int hist_entry__snprintf(struct hist_entry *self,
continue;

ret += snprintf(s + ret, size - ret, "%s", sep ?: " ");
- ret += se->snprintf(self, s + ret, size - ret,
- se->width ? *se->width : 0);
+ ret += se->se_snprintf(self, s + ret, size - ret,
+ se->se_width ? *se->se_width : 0);
}

return ret;
@@ -564,7 +564,7 @@ static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp,
if (sort__first_dimension == SORT_COMM) {
struct sort_entry *se = list_first_entry(&hist_entry__sort_list,
typeof(*se), list);
- left_margin = se->width ? *se->width : 0;
+ left_margin = se->se_width ? *se->se_width : 0;
left_margin -= thread__comm_len(self->thread);
}

@@ -615,22 +615,22 @@ size_t perf_session__fprintf_hists(struct rb_root *hists,
if (se->elide)
continue;
if (sep) {
- fprintf(fp, "%c%s", *sep, se->header);
+ fprintf(fp, "%c%s", *sep, se->se_header);
continue;
}
- width = strlen(se->header);
- if (se->width) {
+ width = strlen(se->se_header);
+ if (se->se_width) {
if (symbol_conf.col_width_list_str) {
if (col_width) {
- *se->width = atoi(col_width);
+ *se->se_width = atoi(col_width);
col_width = strchr(col_width, ',');
if (col_width)
++col_width;
}
}
- width = *se->width = max(*se->width, width);
+ width = *se->se_width = max(*se->se_width, width);
}
- fprintf(fp, " %*s", width, se->header);
+ fprintf(fp, " %*s", width, se->se_header);
}
fprintf(fp, "\n");

@@ -652,10 +652,10 @@ size_t perf_session__fprintf_hists(struct rb_root *hists,
continue;

fprintf(fp, " ");
- if (se->width)
- width = *se->width;
+ if (se->se_width)
+ width = *se->se_width;
else
- width = strlen(se->header);
+ width = strlen(se->se_header);
for (i = 0; i < width; i++)
fprintf(fp, ".");
}
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 9d24d4b..da30b30 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -30,38 +30,38 @@ static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf,
size_t size, unsigned int width);

struct sort_entry sort_thread = {
- .header = "Command: Pid",
- .cmp = sort__thread_cmp,
- .snprintf = hist_entry__thread_snprintf,
- .width = &threads__col_width,
+ .se_header = "Command: Pid",
+ .se_cmp = sort__thread_cmp,
+ .se_snprintf = hist_entry__thread_snprintf,
+ .se_width = &threads__col_width,
};

struct sort_entry sort_comm = {
- .header = "Command",
- .cmp = sort__comm_cmp,
- .collapse = sort__comm_collapse,
- .snprintf = hist_entry__comm_snprintf,
- .width = &comms__col_width,
+ .se_header = "Command",
+ .se_cmp = sort__comm_cmp,
+ .se_collapse = sort__comm_collapse,
+ .se_snprintf = hist_entry__comm_snprintf,
+ .se_width = &comms__col_width,
};

struct sort_entry sort_dso = {
- .header = "Shared Object",
- .cmp = sort__dso_cmp,
- .snprintf = hist_entry__dso_snprintf,
- .width = &dsos__col_width,
+ .se_header = "Shared Object",
+ .se_cmp = sort__dso_cmp,
+ .se_snprintf = hist_entry__dso_snprintf,
+ .se_width = &dsos__col_width,
};

struct sort_entry sort_sym = {
- .header = "Symbol",
- .cmp = sort__sym_cmp,
- .snprintf = hist_entry__sym_snprintf,
+ .se_header = "Symbol",
+ .se_cmp = sort__sym_cmp,
+ .se_snprintf = hist_entry__sym_snprintf,
};

struct sort_entry sort_parent = {
- .header = "Parent symbol",
- .cmp = sort__parent_cmp,
- .snprintf = hist_entry__parent_snprintf,
- .width = &parent_symbol__col_width,
+ .se_header = "Parent symbol",
+ .se_cmp = sort__parent_cmp,
+ .se_snprintf = hist_entry__parent_snprintf,
+ .se_width = &parent_symbol__col_width,
};

struct sort_dimension {
@@ -255,7 +255,7 @@ int sort_dimension__add(const char *tok)
if (strncasecmp(tok, sd->name, strlen(tok)))
continue;

- if (sd->entry->collapse)
+ if (sd->entry->se_collapse)
sort__need_collapse = 1;

if (sd->entry == &sort_parent) {
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 6d7b4be..1d857aa 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -78,13 +78,13 @@ enum sort_type {
struct sort_entry {
struct list_head list;

- const char *header;
+ const char *se_header;

- int64_t (*cmp)(struct hist_entry *, struct hist_entry *);
- int64_t (*collapse)(struct hist_entry *, struct hist_entry *);
- int (*snprintf)(struct hist_entry *self, char *bf, size_t size,
- unsigned int width);
- unsigned int *width;
+ int64_t (*se_cmp)(struct hist_entry *, struct hist_entry *);
+ int64_t (*se_collapse)(struct hist_entry *, struct hist_entry *);
+ int (*se_snprintf)(struct hist_entry *self, char *bf, size_t size,
+ unsigned int width);
+ unsigned int *se_width;
bool elide;
};

--
1.6.2.3

2010-04-14 17:31:48

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: [PATCH v3] perf: Fix accidentally preprocessed snprintf callback

Em Wed, Apr 14, 2010 at 07:11:29PM +0200, Frederic Weisbecker escreveu:
> struct sort_entry has a callback named snprintf that turns an
> entry into a string result.
> But there are glibc versions that implement snprintf through a
> macro. The following expression is then going to get the snprintf
> call preprocessed:
>
> ent->snprintf(...)
>
> to finally end up in a build error:
>
> util/hist.c: Dans la fonction ?hist_entry__snprintf? :
> util/hist.c:539: erreur: ?struct sort_entry? has no member named ?__builtin___snprintf_chk?
>
> To fix this, prepend struct sort_entry callbacks with an "se_"
> prefix.

Thanks, I'll queue this one up

- Arnaldo