[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Findutils-patches] [PATCH 6/7] Refactor insert_fprintf to minimise call
From: |
James Youngman |
Subject: |
[Findutils-patches] [PATCH 6/7] Refactor insert_fprintf to minimise calls to make_segment. |
Date: |
Wed, 29 Jun 2011 10:16:55 +0100 |
* find/print.c (get_format_flags_length): Factor out of
insert_fprintf; computes the length of the format flags for a
format specifier (that is everything after the % but before the
format control character).
(get_format_specifer_length): Also factored out of insert_fprintf;
returns the number of format control characters (e.g. 2 for %A@)
or 0 for error.
(insert_fprintf): Keep fmt_editpos and fmt_inpos more closely in
step, instead of initialising fmt_inpos only when we need it (the
idea eventually will be to make fmt_inpos the loop control
variable). Call get_format_specifer_length and
get_format_flags_length when needed. Reduce the number of
different calls to make_segment. We now have one for each KIND_
value plus one for the error case.
---
ChangeLog | 18 +++++++++
find/print.c | 116 ++++++++++++++++++++++++++++++++++++----------------------
2 files changed, 90 insertions(+), 44 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 0bd6aaf..2e477d3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2011-06-28 James Youngman <address@hidden>
+
+ Refactor insert_fprintf to minimise calls to make_segment.
+ * find/print.c (get_format_flags_length): Factor out of
+ insert_fprintf; computes the length of the format flags for a
+ format specifier (that is everything after the % but before the
+ format control character).
+ (get_format_specifer_length): Also factored out of insert_fprintf;
+ returns the number of format control characters (e.g. 2 for %A@)
+ or 0 for error.
+ (insert_fprintf): Keep fmt_editpos and fmt_inpos more closely in
+ step, instead of initialising fmt_inpos only when we need it (the
+ idea eventually will be to make fmt_inpos the loop control
+ variable). Call get_format_specifer_length and
+ get_format_flags_length when needed. Reduce the number of
+ different calls to make_segment. We now have one for each KIND_
+ value plus one for the error case.
+
2011-06-27 James Youngman <address@hidden>
Factor some of the code out of insert_fprintf.
diff --git a/find/print.c b/find/print.c
index fc72591..862be43 100644
--- a/find/print.c
+++ b/find/print.c
@@ -272,6 +272,41 @@ parse_escape_char(const char ch)
}
+static size_t
+get_format_flags_length(const char *p)
+{
+ size_t n = 0;
+ /* Scan past flags, width and precision, to verify kind. */
+ for (; p[++n] && strchr ("-+ #", p[n]);)
+ {
+ /* Do nothing. */
+ }
+ while (ISDIGIT (p[n]))
+ n++;
+ if (p[n] == '.')
+ for (n++; ISDIGIT (p[n]); n++)
+ /* Do nothing. */ ;
+ return n;
+}
+
+static size_t
+get_format_specifer_length(char ch)
+{
+ if (strchr ("abcdDfFgGhHiklmMnpPsStuUyYZ%", ch))
+ {
+ return 1;
+ }
+ else if (strchr ("ABCT", ch))
+ {
+ return 2;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+
bool
insert_fprintf (struct format_val *vec,
const struct parser_table *entry,
@@ -335,72 +370,65 @@ insert_fprintf (struct format_val *vec,
}
else if (fmt_editpos[0] == '%')
{
- if (fmt_editpos[1] == '%')
- {
- /* % escapes itself. That is, %% produces just %. */
- fmt_inpos = fmt_editpos+1;
- }
- else if (fmt_editpos[1] == 0)
+ size_t len;
+ fmt_inpos = fmt_editpos;
+ if (fmt_inpos[1] == 0)
{
/* Trailing %. We don't like those. */
error (EXIT_FAILURE, 0,
- _("error: %s at end of format string"), fmt_editpos);
+ _("error: %s at end of format string"), fmt_inpos);
}
+
+ if (fmt_inpos[1] == '%') /* %% produces just %. */
+ len = 1;
else
+ len = get_format_flags_length(fmt_inpos);
+ fmt_inpos += len;
+ fmt_editpos += len;
+
+ assert (fmt_inpos == fmt_editpos);
+ len = get_format_specifer_length (fmt_inpos[0]);
+ if (len && (fmt_inpos[len-1]))
{
- /* Scan past flags, width and precision, to verify kind. */
- for (fmt_inpos = fmt_editpos;
- *++fmt_inpos && strchr ("-+ #", *fmt_inpos);)
- {
- /* Do nothing. */
- }
- while (ISDIGIT (*fmt_inpos))
- fmt_inpos++;
- if (*fmt_inpos == '.')
- for (fmt_inpos++; ISDIGIT (*fmt_inpos); fmt_inpos++)
- /* Do nothing. */ ;
- }
- if (strchr ("abcdDfFgGhHiklmMnpPsStuUyYZ%", *fmt_inpos))
- {
- segmentp = make_segment (segmentp, segstart, fmt_inpos - segstart,
- KIND_FORMAT, *fmt_inpos, 0,
- our_pred);
- fmt_editpos = fmt_inpos;
- segstart = fmt_editpos + 1;
- }
- else if (strchr ("ABCT", *fmt_inpos) && fmt_inpos[1])
- {
- segmentp = make_segment (segmentp, segstart, fmt_inpos - segstart,
- KIND_FORMAT, fmt_inpos[0], fmt_inpos[1],
+ const char fmt2 = (len == 2) ? fmt_inpos[1] : 0;
+ segmentp = make_segment (segmentp, segstart,
+ fmt_editpos - segstart,
+ KIND_FORMAT, *fmt_inpos, fmt2,
our_pred);
- fmt_editpos = fmt_inpos + 1;
- segstart = fmt_editpos + 1;
+ fmt_editpos += (len - 1);
+ fmt_inpos += (len - 1);
}
else
{
- switch (*fmt_inpos)
+ if (strchr ("{[(", *fmt_inpos))
{
- case '{':
- case '[':
- case '(':
error (EXIT_FAILURE, 0,
_("error: the format directive `%%%c' is reserved for
future use"),
(int)*fmt_inpos);
/*NOTREACHED*/
- break;
+ }
- default:
+ if (len == 2 && !fmt_inpos[1])
+ {
+ error (0, 0,
+ _("warning: format directive `%%%c' "
+ "should be followed by another character"),
+ *fmt_inpos);
+ }
+ else
+ {
/* An unrecognized % escape. Print the char after the %. */
error (0, 0,
_("warning: unrecognized format directive `%%%c'"),
*fmt_inpos);
- segmentp = make_segment (segmentp,
- segstart, fmt_editpos - segstart,
- KIND_PLAIN, 0, 0,
- our_pred);
- segstart = fmt_editpos + 1;
}
+ ++fmt_inpos;
+ segmentp = make_segment (segmentp,
+ segstart, fmt_inpos - segstart,
+ KIND_PLAIN, 0, 0,
+ our_pred);
}
+ segstart = fmt_editpos + 1;
}
}
--
1.7.2.5
- [Findutils-patches] [PATCH 1/7] Clarify variable naming in insert_fprintf., James Youngman, 2011/06/29
- [Findutils-patches] [PATCH 4/7] Separate out the handling of \c., James Youngman, 2011/06/29
- [Findutils-patches] [PATCH 5/7] Factor some of the code out of insert_fprintf., James Youngman, 2011/06/29
- [Findutils-patches] [PATCH 3/7] Remove some redundant continue statements., James Youngman, 2011/06/29
- [Findutils-patches] [PATCH 2/7] Simplify -fprintf %%; handle %% like a regular format specifier., James Youngman, 2011/06/29
- [Findutils-patches] [PATCH 7/7] Fix some constness warnings when dealing with -printf formats., James Youngman, 2011/06/29
- [Findutils-patches] [PATCH 6/7] Refactor insert_fprintf to minimise calls to make_segment.,
James Youngman <=