X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Ftransform.c;h=349a0d59e21c7394781a9d27b44c7df8f2a907ff;hb=e2b8c8fa9f6567ddf60634650dbb4f5ea3462642;hp=598caaccac79abc7119cb9fad8ef540094f14c3a;hpb=8b2f4ad6705f4a561a5751f58c1e0169f5fe0270;p=chaz%2Ftar diff --git a/src/transform.c b/src/transform.c index 598caac..349a0d5 100644 --- a/src/transform.c +++ b/src/transform.c @@ -1,9 +1,9 @@ /* This file is part of GNU tar. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2007 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 2, or (at your option) any later + Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, but @@ -19,13 +19,14 @@ #include #include "common.h" -enum transform_type +static enum transform_type { transform_none, transform_first, transform_global } transform_type = transform_none; +static unsigned match_number = 0; static regex_t regex; static struct obstack stk; @@ -63,7 +64,7 @@ struct replace_segm /* Compiled replacement expression */ static struct replace_segm *repl_head, *repl_tail; -static segm_count; /* Number of elements in the above list */ +static size_t segm_count; /* Number of elements in the above list */ static struct replace_segm * add_segment (void) @@ -102,7 +103,7 @@ add_char_segment (int chr) segm->v.literal.ptr = xmalloc (2); segm->v.literal.ptr[0] = chr; segm->v.literal.ptr[1] = 0; - segm->v.literal.size = 2; + segm->v.literal.size = 1; } static void @@ -176,6 +177,12 @@ set_transform_expr (const char *expr) cflags |= REG_EXTENDED; break; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + match_number = strtoul (p, (char**) &p, 0); + p--; + break; + default: USAGE_ERROR ((0, 0, _("Unknown flag in transform expression"))); } @@ -370,11 +377,11 @@ bool _transform_name_to_obstack (char *input) { regmatch_t *rmp; - char *p; int rc; + size_t nmatches = 0; enum case_ctl_type case_ctl = ctl_stop, /* Current case conversion op */ save_ctl = ctl_stop; /* Saved case_ctl for \u and \l */ - + /* Reset case conversion after a single-char operation */ #define CASE_CTL_RESET() if (case_ctl == ctl_upcase_next \ || case_ctl == ctl_locase_next) \ @@ -403,7 +410,15 @@ _transform_name_to_obstack (char *input) if (rmp[0].rm_so) obstack_grow (&stk, input, rmp[0].rm_so); - + + nmatches++; + if (match_number && nmatches < match_number) + { + obstack_grow (&stk, input, disp); + input += disp; + continue; + } + for (segm = repl_head; segm; segm = segm->next) { switch (segm->type) @@ -483,21 +498,21 @@ _transform_name_to_obstack (char *input) } bool -transform_name_fp (char **pinput, char *(*fun)(char *)) +transform_name_fp (char **pinput, char *(*fun)(char *, void *), void *dat) { - char *str, *p; + char *str; bool ret = _transform_name_to_obstack (*pinput); if (ret) { str = obstack_finish (&stk); - assign_string (pinput, fun ? fun (str) : str); + assign_string (pinput, fun ? fun (str, dat) : str); obstack_free (&stk, str); } else if (fun) { str = *pinput; *pinput = NULL; - assign_string (pinput, fun (str)); + assign_string (pinput, fun (str, dat)); free (str); ret = true; } @@ -507,23 +522,6 @@ transform_name_fp (char **pinput, char *(*fun)(char *)) bool transform_name (char **pinput) { - return transform_name_fp (pinput, NULL); + return transform_name_fp (pinput, NULL, NULL); } -#if 0 -void -read_and_transform_loop () -{ - char buf[512]; - while (fgets (buf, sizeof buf, stdin)) - { - char *p = buf + strlen (buf); - if (p[-1] == '\n') - p[-1] = 0; - if (transform_name (buf, &p)) - printf ("=> %s\n", p); - else - printf ("=\n"); - } -} -#endif