diff options
Diffstat (limited to 'find/parser.c')
-rw-r--r-- | find/parser.c | 312 |
1 files changed, 1 insertions, 311 deletions
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 |