summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Youngman <jay@gnu.org>2011-06-17 23:29:41 +0100
committerJames Youngman <jay@gnu.org>2011-06-18 20:08:34 +0100
commit3953192b4e3e750e0795eae803524a67ad15e48f (patch)
tree158f9512a846a4b17c09e9fd3cc51a7682170943
parentd8260ba1e0729ad27f0fc5d857431a8babb266c6 (diff)
downloadfindutils-3953192b4e3e750e0795eae803524a67ad15e48f.tar.gz
Split find's printf-related code into a new file.
* find/print.h: New file. Declare insert_fprintf and make_segment. * find/print.c: New file. Move definitions of insert_fprintf and make_segment to here. * find/parser.c: Include "parser.h". Move declarations of insert_fprintf and make_segment into that file; move the definitions into parser.c. * find/Makefile.am (libfindtools_a_SOURCES): Add print.c. (EXTRA_DIST): Add print.h. * po/POTFILES.in: Add find/print.c.
-rw-r--r--ChangeLog14
-rw-r--r--find/Makefile.am4
-rw-r--r--find/parser.c312
-rw-r--r--find/print.c346
-rw-r--r--find/print.h16
-rw-r--r--po/POTFILES.in1
6 files changed, 380 insertions, 313 deletions
diff --git a/ChangeLog b/ChangeLog
index 0fdcf460..15ebc96d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2011-06-17 James Youngman <jay@gnu.org>
+
+ Split find's printf-related code into a new file.
+ * find/print.h: New file. Declare insert_fprintf and
+ make_segment.
+ * find/print.c: New file. Move definitions of insert_fprintf and
+ make_segment to here.
+ * find/parser.c: Include "parser.h". Move declarations of
+ insert_fprintf and make_segment into that file; move the
+ definitions into parser.c.
+ * find/Makefile.am (libfindtools_a_SOURCES): Add print.c.
+ (EXTRA_DIST): Add print.h.
+ * po/POTFILES.in: Add find/print.c.
+
2011-06-15 James Youngman <jay@gnu.org>
Fix compiler warnings in lib/regextype.c and find/parser.c.
diff --git a/find/Makefile.am b/find/Makefile.am
index bfb50ce1..67fd682a 100644
--- a/find/Makefile.am
+++ b/find/Makefile.am
@@ -5,7 +5,7 @@ localedir = $(datadir)/locale
# regexprops_SOURCES = regexprops.c
noinst_LIBRARIES = libfindtools.a
-libfindtools_a_SOURCES = finddata.c fstype.c parser.c pred.c exec.c tree.c util.c sharefile.c
+libfindtools_a_SOURCES = finddata.c fstype.c parser.c pred.c exec.c tree.c util.c sharefile.c print.c
# We always build two versions of find, one with fts, one without.
@@ -29,7 +29,7 @@ endif
# We don't just include man_MANS in EXTRA_DIST because while the value of
# man_MANS is not always the same, we want to distribute all of those files.
-EXTRA_DIST = defs.h sharefile.h find.1 ftsfind.1 oldfind.1
+EXTRA_DIST = defs.h sharefile.h print.h find.1 ftsfind.1 oldfind.1
INCLUDES = -I../gl/lib -I$(top_srcdir)/lib -I$(top_srcdir)/gl/lib -I../intl -DLOCALEDIR=\"$(localedir)\"
LDADD = ./libfindtools.a ../lib/libfind.a ../gl/lib/libgnulib.a $(LIBINTL) $(LIB_CLOCK_GETTIME) $(LIB_EACCESS) $(LIB_SELINUX) $(LIB_CLOSE) $(MODF_LIBM) $(FINDLIBS)
SUBDIRS = . testsuite
diff --git a/find/parser.c b/find/parser.c
index d1ee52ad..a81aeb29 100644
--- a/find/parser.c
+++ b/find/parser.c
@@ -44,6 +44,7 @@
#include "safe-atoi.h"
#include "fdleak.h"
#include "splitstring.h"
+#include "print.h"
#include <fcntl.h>
@@ -70,12 +71,6 @@
# define N_(String) String
#endif
-#if defined STDC_HEADERS
-# define ISDIGIT(c) isdigit ((unsigned char)c)
-#else
-# define ISDIGIT(c) (isascii ((unsigned char)c) && isdigit ((unsigned char)c))
-#endif
-
#ifndef HAVE_ENDGRENT
#define endgrent ()
#endif
@@ -166,16 +161,6 @@ static bool insert_type (char **argv, int *arg_ptr,
static bool insert_regex (char *argv[], int *arg_ptr,
const struct parser_table *entry,
int regex_options);
-static bool insert_fprintf (struct format_val *vec,
- const struct parser_table *entry,
- PRED_FUNC func,
- const char *format);
-
-static struct segment **make_segment (struct segment **segment,
- char *format, int len,
- int kind, char format_char,
- char aux_format_char,
- struct predicate *pred);
static bool insert_exec_ok (const char *action,
const struct parser_table *entry,
char *argv[],
@@ -2937,301 +2922,6 @@ stream_is_tty (FILE *fp)
-/* XXX: do we need to pass FUNC to this function? */
-static bool
-insert_fprintf (struct format_val *vec,
- const struct parser_table *entry, PRED_FUNC func,
- const char *format_const)
-{
- char *format = (char*)format_const; /* XXX: casting away constness */
- register char *scan; /* Current address in scanning `format'. */
- register char *scan2; /* Address inside of element being scanned. */
- struct segment **segmentp; /* Address of current segment. */
- struct predicate *our_pred;
-
- our_pred = insert_primary_withpred (entry, func, format_const);
- our_pred->side_effects = our_pred->no_default_print = true;
- our_pred->args.printf_vec = *vec;
- our_pred->need_type = false;
- our_pred->need_stat = false;
- our_pred->p_cost = NeedsNothing;
-
- segmentp = &our_pred->args.printf_vec.segment;
- *segmentp = NULL;
-
- for (scan = format; *scan; scan++)
- {
- if (*scan == '\\')
- {
- scan2 = scan + 1;
- if (*scan2 >= '0' && *scan2 <= '7')
- {
- register int n, i;
-
- for (i = n = 0; i < 3 && (*scan2 >= '0' && *scan2 <= '7');
- i++, scan2++)
- n = 8 * n + *scan2 - '0';
- scan2--;
- *scan = n;
- }
- else
- {
- switch (*scan2)
- {
- case 'a':
- *scan = 7;
- break;
- case 'b':
- *scan = '\b';
- break;
- case 'c':
- make_segment (segmentp, format, scan - format,
- KIND_STOP, 0, 0,
- our_pred);
- if (our_pred->need_stat && (our_pred->p_cost < NeedsStatInfo))
- our_pred->p_cost = NeedsStatInfo;
- return true;
- case 'f':
- *scan = '\f';
- break;
- case 'n':
- *scan = '\n';
- break;
- case 'r':
- *scan = '\r';
- break;
- case 't':
- *scan = '\t';
- break;
- case 'v':
- *scan = '\v';
- break;
- case '\\':
- /* *scan = '\\'; * it already is */
- break;
- default:
- error (0, 0,
- _("warning: unrecognized escape `\\%c'"), *scan2);
- scan++;
- continue;
- }
- }
- segmentp = make_segment (segmentp, format, scan - format + 1,
- KIND_PLAIN, 0, 0,
- our_pred);
- format = scan2 + 1; /* Move past the escape. */
- scan = scan2; /* Incremented immediately by `for'. */
- }
- else if (*scan == '%')
- {
- if (scan[1] == 0)
- {
- /* Trailing %. We don't like those. */
- error (EXIT_FAILURE, 0,
- _("error: %s at end of format string"), scan);
- }
- else if (scan[1] == '%')
- {
- segmentp = make_segment (segmentp, format, scan - format + 1,
- KIND_PLAIN, 0, 0,
- our_pred);
- scan++;
- format = scan + 1;
- continue;
- }
- /* Scan past flags, width and precision, to verify kind. */
- for (scan2 = scan; *++scan2 && strchr ("-+ #", *scan2);)
- /* Do nothing. */ ;
- while (ISDIGIT (*scan2))
- scan2++;
- if (*scan2 == '.')
- for (scan2++; ISDIGIT (*scan2); scan2++)
- /* Do nothing. */ ;
- if (strchr ("abcdDfFgGhHiklmMnpPsStuUyYZ", *scan2))
- {
- segmentp = make_segment (segmentp, format, scan2 - format,
- KIND_FORMAT, *scan2, 0,
- our_pred);
- scan = scan2;
- format = scan + 1;
- }
- else if (strchr ("ABCT", *scan2) && scan2[1])
- {
- segmentp = make_segment (segmentp, format, scan2 - format,
- KIND_FORMAT, scan2[0], scan2[1],
- our_pred);
- scan = scan2 + 1;
- format = scan + 1;
- continue;
- }
- else
- {
- /* An unrecognized % escape. Print the char after the %. */
- error (0, 0, _("warning: unrecognized format directive `%%%c'"),
- *scan2);
- segmentp = make_segment (segmentp, format, scan - format,
- KIND_PLAIN, 0, 0,
- our_pred);
- format = scan + 1;
- continue;
- }
- }
- }
-
- if (scan > format)
- make_segment (segmentp, format, scan - format, KIND_PLAIN, 0, 0,
- our_pred);
- return true;
-}
-
-/* Create a new fprintf segment in *SEGMENT, with type KIND,
- from the text in FORMAT, which has length LEN.
- Return the address of the `next' pointer of the new segment. */
-
-static struct segment **
-make_segment (struct segment **segment,
- char *format,
- int len,
- int kind,
- char format_char,
- char aux_format_char,
- struct predicate *pred)
-{
- enum EvaluationCost mycost = NeedsNothing;
- char *fmt;
-
- *segment = xmalloc (sizeof (struct segment));
-
- (*segment)->segkind = kind;
- (*segment)->format_char[0] = format_char;
- (*segment)->format_char[1] = aux_format_char;
- (*segment)->next = NULL;
- (*segment)->text_len = len;
-
- fmt = (*segment)->text = xmalloc (len + sizeof "d");
- strncpy (fmt, format, len);
- fmt += len;
-
- if (kind == KIND_PLAIN /* Plain text string, no % conversion. */
- || kind == KIND_STOP) /* Terminate argument, no newline. */
- {
- assert (0 == format_char);
- assert (0 == aux_format_char);
- *fmt = '\0';
- if (mycost > pred->p_cost)
- pred->p_cost = NeedsNothing;
- return &(*segment)->next;
- }
-
- assert (kind == KIND_FORMAT);
- switch (format_char)
- {
- case 'l': /* object of symlink */
- pred->need_stat = true;
- mycost = NeedsLinkName;
- *fmt++ = 's';
- break;
-
- case 'y': /* file type */
- pred->need_type = true;
- mycost = NeedsType;
- *fmt++ = 's';
- break;
-
- case 'i': /* inode number */
- pred->need_inum = true;
- mycost = NeedsInodeNumber;
- *fmt++ = 's';
- break;
-
- case 'a': /* atime in `ctime' format */
- case 'A': /* atime in user-specified strftime format */
- case 'B': /* birth time in user-specified strftime format */
- case 'c': /* ctime in `ctime' format */
- case 'C': /* ctime in user-specified strftime format */
- case 'F': /* file system type */
- case 'g': /* group name */
- case 'M': /* mode in `ls -l' format (eg., "drwxr-xr-x") */
- case 's': /* size in bytes */
- case 't': /* mtime in `ctime' format */
- case 'T': /* mtime in user-specified strftime format */
- case 'u': /* user name */
- pred->need_stat = true;
- mycost = NeedsStatInfo;
- *fmt++ = 's';
- break;
-
- case 'S': /* sparseness */
- pred->need_stat = true;
- mycost = NeedsStatInfo;
- *fmt++ = 'g';
- break;
-
- case 'Y': /* symlink pointed file type */
- pred->need_stat = true;
- mycost = NeedsType; /* true for amortised effect */
- *fmt++ = 's';
- break;
-
- case 'f': /* basename of path */
- case 'h': /* leading directories part of path */
- case 'p': /* pathname */
- case 'P': /* pathname with ARGV element stripped */
- *fmt++ = 's';
- break;
-
- case 'Z': /* SELinux security context */
- mycost = NeedsAccessInfo;
- *fmt++ = 's';
- break;
-
- case 'H': /* ARGV element file was found under */
- *fmt++ = 's';
- break;
-
- /* Numeric items that one might expect to honour
- * #, 0, + flags but which do not.
- */
- case 'G': /* GID number */
- case 'U': /* UID number */
- case 'b': /* size in 512-byte blocks (NOT birthtime in ctime fmt)*/
- case 'D': /* Filesystem device on which the file exits */
- case 'k': /* size in 1K blocks */
- case 'n': /* number of links */
- pred->need_stat = true;
- mycost = NeedsStatInfo;
- *fmt++ = 's';
- break;
-
- /* Numeric items that DO honour #, 0, + flags.
- */
- case 'd': /* depth in search tree (0 = ARGV element) */
- *fmt++ = 'd';
- break;
-
- case 'm': /* mode as octal number (perms only) */
- *fmt++ = 'o';
- pred->need_stat = true;
- mycost = NeedsStatInfo;
- break;
-
- case '{':
- case '[':
- case '(':
- error (EXIT_FAILURE, 0,
- _("error: the format directive `%%%c' is reserved for future use"),
- (int)kind);
- /*NOTREACHED*/
- break;
- }
- *fmt = '\0';
-
- if (mycost > pred->p_cost)
- pred->p_cost = mycost;
- return &(*segment)->next;
-}
-
-
static void
diff --git a/find/print.c b/find/print.c
new file mode 100644
index 00000000..a605bcf8
--- /dev/null
+++ b/find/print.c
@@ -0,0 +1,346 @@
+/* print.c -- print/printf-related code.
+ Copyright (C) 1990, 1991, 1992, 1993, 1994, 2000, 2001, 2003, 2004,
+ 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
+ Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* We always include config.h first. */
+#include <config.h>
+
+/* system headers go here. */
+#include <assert.h>
+#include <ctype.h>
+#include <locale.h>
+
+/* gnulib headers. */
+#include "error.h"
+#include "xalloc.h"
+
+/* find-specific headers. */
+#include "defs.h"
+#include "print.h"
+
+#if ENABLE_NLS
+# include <libintl.h>
+# define _(Text) gettext (Text)
+#else
+# define _(Text) Text
+#endif
+#ifdef gettext_noop
+# define N_(String) gettext_noop (String)
+#else
+/* See locate.c for explanation as to why not use (String) */
+# define N_(String) String
+#endif
+
+#if defined STDC_HEADERS
+# define ISDIGIT(c) isdigit ((unsigned char)c)
+#else
+# define ISDIGIT(c) (isascii ((unsigned char)c) && isdigit ((unsigned char)c))
+#endif
+
+/* Create a new fprintf segment in *SEGMENT, with type KIND,
+ from the text in FORMAT, which has length LEN.
+ Return the address of the `next' pointer of the new segment. */
+struct segment **
+make_segment (struct segment **segment,
+ char *format,
+ int len,
+ int kind,
+ char format_char,
+ char aux_format_char,
+ struct predicate *pred)
+{
+ enum EvaluationCost mycost = NeedsNothing;
+ char *fmt;
+
+ *segment = xmalloc (sizeof (struct segment));
+
+ (*segment)->segkind = kind;
+ (*segment)->format_char[0] = format_char;
+ (*segment)->format_char[1] = aux_format_char;
+ (*segment)->next = NULL;
+ (*segment)->text_len = len;
+
+ fmt = (*segment)->text = xmalloc (len + sizeof "d");
+ strncpy (fmt, format, len);
+ fmt += len;
+
+ if (kind == KIND_PLAIN /* Plain text string, no % conversion. */
+ || kind == KIND_STOP) /* Terminate argument, no newline. */
+ {
+ assert (0 == format_char);
+ assert (0 == aux_format_char);
+ *fmt = '\0';
+ if (mycost > pred->p_cost)
+ pred->p_cost = NeedsNothing;
+ return &(*segment)->next;
+ }
+
+ assert (kind == KIND_FORMAT);
+ switch (format_char)
+ {
+ case 'l': /* object of symlink */
+ pred->need_stat = true;
+ mycost = NeedsLinkName;
+ *fmt++ = 's';
+ break;
+
+ case 'y': /* file type */
+ pred->need_type = true;
+ mycost = NeedsType;
+ *fmt++ = 's';
+ break;
+
+ case 'i': /* inode number */
+ pred->need_inum = true;
+ mycost = NeedsInodeNumber;
+ *fmt++ = 's';
+ break;
+
+ case 'a': /* atime in `ctime' format */
+ case 'A': /* atime in user-specified strftime format */
+ case 'B': /* birth time in user-specified strftime format */
+ case 'c': /* ctime in `ctime' format */
+ case 'C': /* ctime in user-specified strftime format */
+ case 'F': /* file system type */
+ case 'g': /* group name */
+ case 'M': /* mode in `ls -l' format (eg., "drwxr-xr-x") */
+ case 's': /* size in bytes */
+ case 't': /* mtime in `ctime' format */
+ case 'T': /* mtime in user-specified strftime format */
+ case 'u': /* user name */
+ pred->need_stat = true;
+ mycost = NeedsStatInfo;
+ *fmt++ = 's';
+ break;
+
+ case 'S': /* sparseness */
+ pred->need_stat = true;
+ mycost = NeedsStatInfo;
+ *fmt++ = 'g';
+ break;
+
+ case 'Y': /* symlink pointed file type */
+ pred->need_stat = true;
+ mycost = NeedsType; /* true for amortised effect */
+ *fmt++ = 's';
+ break;
+
+ case 'f': /* basename of path */
+ case 'h': /* leading directories part of path */
+ case 'p': /* pathname */
+ case 'P': /* pathname with ARGV element stripped */
+ *fmt++ = 's';
+ break;
+
+ case 'Z': /* SELinux security context */
+ mycost = NeedsAccessInfo;
+ *fmt++ = 's';
+ break;
+
+ case 'H': /* ARGV element file was found under */
+ *fmt++ = 's';
+ break;
+
+ /* Numeric items that one might expect to honour
+ * #, 0, + flags but which do not.
+ */
+ case 'G': /* GID number */
+ case 'U': /* UID number */
+ case 'b': /* size in 512-byte blocks (NOT birthtime in ctime fmt)*/
+ case 'D': /* Filesystem device on which the file exits */
+ case 'k': /* size in 1K blocks */
+ case 'n': /* number of links */
+ pred->need_stat = true;
+ mycost = NeedsStatInfo;
+ *fmt++ = 's';
+ break;
+
+ /* Numeric items that DO honour #, 0, + flags.
+ */
+ case 'd': /* depth in search tree (0 = ARGV element) */
+ *fmt++ = 'd';
+ break;
+
+ case 'm': /* mode as octal number (perms only) */
+ *fmt++ = 'o';
+ pred->need_stat = true;
+ mycost = NeedsStatInfo;
+ break;
+
+ case '{':
+ case '[':
+ case '(':
+ error (EXIT_FAILURE, 0,
+ _("error: the format directive `%%%c' is reserved for future use"),
+ (int)kind);
+ /*NOTREACHED*/
+ break;
+ }
+ *fmt = '\0';
+
+ if (mycost > pred->p_cost)
+ pred->p_cost = mycost;
+ return &(*segment)->next;
+}
+
+/* XXX: do we need to pass FUNC to this function? */
+bool
+insert_fprintf (struct format_val *vec,
+ const struct parser_table *entry, PRED_FUNC func,
+ const char *format_const)
+{
+ char *format = (char*)format_const; /* XXX: casting away constness */
+ register char *scan; /* Current address in scanning `format'. */
+ register char *scan2; /* Address inside of element being scanned. */
+ struct segment **segmentp; /* Address of current segment. */
+ struct predicate *our_pred;
+
+ our_pred = insert_primary_withpred (entry, func, format_const);
+ our_pred->side_effects = our_pred->no_default_print = true;
+ our_pred->args.printf_vec = *vec;
+ our_pred->need_type = false;
+ our_pred->need_stat = false;
+ our_pred->p_cost = NeedsNothing;
+
+ segmentp = &our_pred->args.printf_vec.segment;
+ *segmentp = NULL;
+
+ for (scan = format; *scan; scan++)
+ {
+ if (*scan == '\\')
+ {
+ scan2 = scan + 1;
+ if (*scan2 >= '0' && *scan2 <= '7')
+ {
+ register int n, i;
+
+ for (i = n = 0; i < 3 && (*scan2 >= '0' && *scan2 <= '7');
+ i++, scan2++)
+ n = 8 * n + *scan2 - '0';
+ scan2--;
+ *scan = n;
+ }
+ else
+ {
+ switch (*scan2)
+ {
+ case 'a':
+ *scan = 7;
+ break;
+ case 'b':
+ *scan = '\b';
+ break;
+ case 'c':
+ make_segment (segmentp, format, scan - format,
+ KIND_STOP, 0, 0,
+ our_pred);
+ if (our_pred->need_stat && (our_pred->p_cost < NeedsStatInfo))
+ our_pred->p_cost = NeedsStatInfo;
+ return true;
+ case 'f':
+ *scan = '\f';
+ break;
+ case 'n':
+ *scan = '\n';
+ break;
+ case 'r':
+ *scan = '\r';
+ break;
+ case 't':
+ *scan = '\t';
+ break;
+ case 'v':
+ *scan = '\v';
+ break;
+ case '\\':
+ /* *scan = '\\'; * it already is */
+ break;
+ default:
+ error (0, 0,
+ _("warning: unrecognized escape `\\%c'"), *scan2);
+ scan++;
+ continue;
+ }
+ }
+ segmentp = make_segment (segmentp, format, scan - format + 1,
+ KIND_PLAIN, 0, 0,
+ our_pred);
+ format = scan2 + 1; /* Move past the escape. */
+ scan = scan2; /* Incremented immediately by `for'. */
+ }
+ else if (*scan == '%')
+ {
+ if (scan[1] == 0)
+ {
+ /* Trailing %. We don't like those. */
+ error (EXIT_FAILURE, 0,
+ _("error: %s at end of format string"), scan);
+ }
+ else if (scan[1] == '%')
+ {
+ segmentp = make_segment (segmentp, format, scan - format + 1,
+ KIND_PLAIN, 0, 0,
+ our_pred);
+ scan++;
+ format = scan + 1;
+ continue;
+ }
+ /* Scan past flags, width and precision, to verify kind. */
+ for (scan2 = scan; *++scan2 && strchr ("-+ #", *scan2);)
+ /* Do nothing. */ ;
+ while (ISDIGIT (*scan2))
+ scan2++;
+ if (*scan2 == '.')
+ for (scan2++; ISDIGIT (*scan2); scan2++)
+ /* Do nothing. */ ;
+ if (strchr ("abcdDfFgGhHiklmMnpPsStuUyYZ", *scan2))
+ {
+ segmentp = make_segment (segmentp, format, scan2 - format,
+ KIND_FORMAT, *scan2, 0,
+ our_pred);
+ scan = scan2;
+ format = scan + 1;
+ }
+ else if (strchr ("ABCT", *scan2) && scan2[1])
+ {
+ segmentp = make_segment (segmentp, format, scan2 - format,
+ KIND_FORMAT, scan2[0], scan2[1],
+ our_pred);
+ scan = scan2 + 1;
+ format = scan + 1;
+ continue;
+ }
+ else
+ {
+ /* An unrecognized % escape. Print the char after the %. */
+ error (0, 0, _("warning: unrecognized format directive `%%%c'"),
+ *scan2);
+ segmentp = make_segment (segmentp, format, scan - format,
+ KIND_PLAIN, 0, 0,
+ our_pred);
+ format = scan + 1;
+ continue;
+ }
+ }
+ }
+
+ if (scan > format)
+ make_segment (segmentp, format, scan - format, KIND_PLAIN, 0, 0,
+ our_pred);
+ return true;
+}
diff --git a/find/print.h b/find/print.h
new file mode 100644
index 00000000..9408711c
--- /dev/null
+++ b/find/print.h
@@ -0,0 +1,16 @@
+#include "defs.h"
+
+struct format_val;
+struct parser_table;
+struct predicate;
+struct segment;
+
+struct segment **make_segment (struct segment **segment,
+ char *format, int len,
+ int kind, char format_char,
+ char aux_format_char,
+ struct predicate *pred);
+bool
+insert_fprintf (struct format_val *vec,
+ const struct parser_table *entry, PRED_FUNC func,
+ const char *format_const);
diff --git a/po/POTFILES.in b/po/POTFILES.in
index d4f8d7e7..26435333 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -12,6 +12,7 @@ find/fstype.c
find/ftsfind.c
find/parser.c
find/pred.c
+find/print.c
find/tree.c
find/util.c
lib/buildcmd.c