mirror of
https://https.git.savannah.gnu.org/git/tar.git
synced 2026-01-26 16:09:29 +00:00
* NEWS, configure.ac: Version 1.20.91
* doc/tar.texi: Document transformation scope flags. * src/common.h (transform_symlinks_option): Remove in favor of transformation scope flags. (XFORM_REGFILE, XFORM_LINK, XFORM_SYMLINK, XFORM_ALL): New macros. (transform_name, transform_member_name, transform_name_fp): Take an additional argument, specifying scope flags. * src/create.c: Reflect changes to transform_name. * src/extract.c (extract_link, extract_symlink): Remove calls to transform_member_name. It is done in read_header. * src/list.c (decode_xform): Reflect change in data type of 2nd argument. (transform_member_name): 2nd arg is int. (decode_header): Transform file name and link target names. * src/tar.c: Remove --transform-symlinks. * src/transform.c (struct transform): New member `flags'. (transform_flags): New variable. (parse_transform_expr): Parse transformation scope flags. Allow to set global flags using `flags=' syntax. (_transform_name_to_obstack, transform_name_fp) (transform_name): Take an additional argument, specifying scope flags.
This commit is contained in:
parent
5354888e40
commit
b4ec8aedf9
25
ChangeLog
25
ChangeLog
@ -1,3 +1,28 @@
|
||||
2008-10-30 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||
|
||||
* NEWS, configure.ac: Version 1.20.91
|
||||
* doc/tar.texi: Document transformation scope flags.
|
||||
* src/common.h (transform_symlinks_option): Remove in favor of
|
||||
transformation scope flags.
|
||||
(XFORM_REGFILE, XFORM_LINK, XFORM_SYMLINK, XFORM_ALL): New macros.
|
||||
(transform_name, transform_member_name, transform_name_fp): Take
|
||||
an additional argument, specifying scope flags.
|
||||
* src/create.c: Reflect changes to transform_name.
|
||||
* src/extract.c (extract_link, extract_symlink): Remove calls to
|
||||
transform_member_name. It is done in read_header.
|
||||
* src/list.c (decode_xform): Reflect change in data type of 2nd
|
||||
argument.
|
||||
(transform_member_name): 2nd arg is int.
|
||||
(decode_header): Transform file name and link target names.
|
||||
* src/tar.c: Remove --transform-symlinks.
|
||||
* src/transform.c (struct transform): New member `flags'.
|
||||
(transform_flags): New variable.
|
||||
(parse_transform_expr): Parse transformation scope flags. Allow to
|
||||
set global flags using `flags=' syntax.
|
||||
(_transform_name_to_obstack, transform_name_fp)
|
||||
(transform_name): Take an additional argument, specifying scope
|
||||
flags.
|
||||
|
||||
2008-10-19 Sergey Poznyakoff <gray@gnu.org.ua>
|
||||
|
||||
* THANKS: Add Ed Leaver.
|
||||
|
||||
41
NEWS
41
NEWS
@ -1,8 +1,8 @@
|
||||
GNU tar NEWS - User visible changes. 2008-10-22
|
||||
GNU tar NEWS - User visible changes. 2008-10-30
|
||||
Please send GNU tar bug reports to <bug-tar@gnu.org>
|
||||
|
||||
|
||||
version 1.20.90 (CVS)
|
||||
version 1.20.91 (CVS)
|
||||
|
||||
* New short option -J
|
||||
|
||||
@ -28,21 +28,40 @@ back to using archive suffix to determine it.
|
||||
Using --exclude-vcs handles also files used internally by Bazaar,
|
||||
Mercurial and Darcs.
|
||||
|
||||
* The --transform-symlink option.
|
||||
* Transformation scope flags
|
||||
|
||||
The effect of the --transform option on the symbolic links targets is
|
||||
controlled by --transform-symlink and --no-transform-symlink options.
|
||||
By default, transformations do not apply to symlink targets,
|
||||
which corresponds to the behavior of version 1.19. To apply
|
||||
transformations to symlink targets as well, use --transform-symlink
|
||||
option. The --no-transform-symlink option cancels the effect of any
|
||||
prior --transform-symlink.
|
||||
Name transformation expressions understand additional flags that
|
||||
control type of archive members affected by them. The flags are:
|
||||
|
||||
- r
|
||||
Apply transformation to regular archive members.
|
||||
|
||||
- s
|
||||
Apply transformation to symbolic link targets.
|
||||
|
||||
- h
|
||||
Apply transformation to hard link targets.
|
||||
|
||||
Corresponding upper-case letters negate the flag meaning, so that
|
||||
`H' means ``do not apply transformation to hard link targets.''
|
||||
|
||||
The scope flags are listed in the third part of an `s' expression,
|
||||
e.g.:
|
||||
|
||||
tar --transform 's|^|/usr/local/|S'
|
||||
|
||||
Default is `rsh', which means that transformations are applied to
|
||||
both regular archive members and to the targets of symbolic and hard
|
||||
links. If several transform expressions are used, the default flags
|
||||
can be changed using `flags=' statement before the expressions, e.g.:
|
||||
|
||||
tar --transform 'flags=S;s|^|/usr/local/|S'
|
||||
|
||||
* Bugfixes
|
||||
|
||||
** The --null option disabled handling of tar options in list files. This
|
||||
is fixed.
|
||||
** Fixed record size autodetection. If the detected record size differs from
|
||||
** Fixed record size autodetection. If detected record size differs from
|
||||
the expected value (either default, or set on the command line), tar
|
||||
always prints a warning if verbosity level is set to 1 or greater,
|
||||
i.e. if either -t or -v option is given.
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
|
||||
AC_INIT([GNU tar], [1.20.90], [bug-tar@gnu.org])
|
||||
AC_INIT([GNU tar], [1.20.91], [bug-tar@gnu.org])
|
||||
AC_CONFIG_SRCDIR([src/tar.c])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_HEADERS([config.h:config.hin])
|
||||
|
||||
139
doc/tar.texi
139
doc/tar.texi
@ -2905,13 +2905,6 @@ characters set by the previous @option{--quote-chars} option
|
||||
With this option, @command{tar} will not recurse into directories.
|
||||
@xref{recurse}.
|
||||
|
||||
@opsummary{no-transform-symlinks}
|
||||
@item --no-transform-symlinks
|
||||
Cancel the effect of any prior @command{--transform-symlinks} option
|
||||
(see below) and return to the default behavior of applying name
|
||||
transformation expression only to the names of files (archive
|
||||
members), not to target of symbolic links.
|
||||
|
||||
@opsummary{no-same-owner}
|
||||
@item --no-same-owner
|
||||
@itemx -o
|
||||
@ -3292,11 +3285,6 @@ To see transformed member names in verbose listings, use
|
||||
@option{--show-transformed-names} option
|
||||
(@pxref{show-transformed-names}).
|
||||
|
||||
@opsummary{transform-symlinks}
|
||||
@item --transform-symlinks
|
||||
Apply @command{--transform} option to symbolic link targets
|
||||
(@pxref{transform}).
|
||||
|
||||
@opsummary{uncompress}
|
||||
@item --uncompress
|
||||
|
||||
@ -7605,8 +7593,8 @@ The option @option{--strip=2} instructs @command{tar} to strip the
|
||||
two leading components (@file{usr/} and @file{include/}) off the file
|
||||
name.
|
||||
|
||||
If you add to the above invocation @option{--verbose} (@option{-v})
|
||||
option, you will note that the verbose listing still contains the
|
||||
If you add the @option{--verbose} (@option{-v}) option to the invocation
|
||||
above, you will note that the verbose listing still contains the
|
||||
full file name, with the two removed components still in place. This
|
||||
can be inconvenient, so @command{tar} provides a special option for
|
||||
altering this behavior:
|
||||
@ -7631,7 +7619,7 @@ stdlib.h
|
||||
@end group
|
||||
@end smallexample
|
||||
|
||||
Notice that in both cases the file is @file{stdlib.h} extracted to the
|
||||
Notice that in both cases the file @file{stdlib.h} is extracted to the
|
||||
current working directory, @option{--show-transformed-names} affects
|
||||
only the way its name is displayed.
|
||||
|
||||
@ -7677,6 +7665,21 @@ replacement for each file name part that matches @var{regexp}. Both
|
||||
@var{regexp} and @var{replace} are described in detail in
|
||||
@ref{The "s" Command, The "s" Command, The `s' Command, sed, GNU sed}.
|
||||
|
||||
Any delimiter can be used in lieue of @samp{/}, the only requirement being
|
||||
that it be used consistently throughout the expression. For example,
|
||||
the following two expressions are equivalent:
|
||||
|
||||
@smallexample
|
||||
@group
|
||||
s/one/two/
|
||||
s,one,two,
|
||||
@end group
|
||||
@end smallexample
|
||||
|
||||
Changing delimiters is often useful when the @var{regex} contains
|
||||
slashes. For example, it is more convenient to write @code{s,/,-,} than
|
||||
@code{s/\//-/}.
|
||||
|
||||
As in @command{sed}, you can give several replace expressions,
|
||||
separated by a semicolon.
|
||||
|
||||
@ -7707,21 +7710,41 @@ the interaction is defined to be: ignore matches before the
|
||||
|
||||
@end table
|
||||
|
||||
Any delimiter can be used in lieue of @samp{/}, the only requirement being
|
||||
that it be used consistently throughout the expression. For example,
|
||||
the following two expressions are equivalent:
|
||||
In addition, several @dfn{transformation scope} flags are supported,
|
||||
that control to what files transformations apply. These are:
|
||||
|
||||
@table @samp
|
||||
@item r
|
||||
Apply transformation to regular archive members.
|
||||
|
||||
@item R
|
||||
Do not apply transformation to regular archive members.
|
||||
|
||||
@item s
|
||||
Apply transformation to symbolic link targets.
|
||||
|
||||
@item S
|
||||
Do not apply transformation to symbolic link targets.
|
||||
|
||||
@item h
|
||||
Apply transformation to hard link targets.
|
||||
|
||||
@item H
|
||||
Do not apply transformation to hard link targets.
|
||||
@end table
|
||||
|
||||
Default is @samp{rsh}, which means to apply tranformations to both archive
|
||||
members and targets of symbolic and hard links.
|
||||
|
||||
Default scope flags can also be changed using @samp{flags=} statement
|
||||
in the transform expression. The flags set this way remain in force
|
||||
until next @samp{flags=} statement or end of expression, whichever
|
||||
occurs first. For example:
|
||||
|
||||
@smallexample
|
||||
@group
|
||||
s/one/two/
|
||||
s,one,two,
|
||||
@end group
|
||||
--transform 'flags=S;s|^|/usr/local/|'
|
||||
@end smallexample
|
||||
|
||||
Changing delimiters is often useful when the @var{regex} contains
|
||||
slashes. For example, it is more convenient to write @code{s,/,-,} than
|
||||
@code{s/\//-/}.
|
||||
|
||||
Here are several examples of @option{--transform} usage:
|
||||
|
||||
@enumerate
|
||||
@ -7738,61 +7761,59 @@ $ @kbd{tar --transform='s,usr/,usr/local/,' -x -f arch.tar}
|
||||
$ @kbd{tar --transform='s,/*[^/]*/[^/]*/,,' -x -f arch.tar}
|
||||
@end smallexample
|
||||
|
||||
@item Prepend @file{/prefix/} to each file name:
|
||||
|
||||
@smallexample
|
||||
$ @kbd{tar --transform 's,^,/prefix/,' -x -f arch.tar}
|
||||
@end smallexample
|
||||
|
||||
@item Convert each file name to lower case:
|
||||
|
||||
@smallexample
|
||||
$ @kbd{tar --transform 's/.*/\L&/' -x -f arch.tar}
|
||||
@end smallexample
|
||||
|
||||
@end enumerate
|
||||
|
||||
The @option{--transform} option applies only to member names. It does
|
||||
not apply to symbolic link targets. In many cases, this is the
|
||||
desired behavior. Consider for example, archiving the @file{/lib}
|
||||
directory:
|
||||
@item Prepend @file{/prefix/} to each file name:
|
||||
|
||||
@smallexample
|
||||
$ @kbd{tar -vv -c -f archive /lib}
|
||||
tar: Removing leading `/' from member names
|
||||
$ @kbd{tar --transform 's,^,/prefix/,' -x -f arch.tar}
|
||||
@end smallexample
|
||||
|
||||
@item Archive the @file{/lib} directory, prepending @samp{/usr/local}
|
||||
to each archive member:
|
||||
|
||||
@smallexample
|
||||
$ @kbd{tar --transform 's,^,/usr/local/,S' -c -f arch.tar /lib}
|
||||
@end smallexample
|
||||
@end enumerate
|
||||
|
||||
Notice the use of flags in the last example. The @file{/lib}
|
||||
directory often contains many symbolic links to files within it.
|
||||
It may look, for example, like this:
|
||||
|
||||
@smallexample
|
||||
$ @kbd{ls -l}
|
||||
drwxr-xr-x root/root 0 2008-07-08 16:20 /lib/
|
||||
-rwxr-xr-x root/root 1250840 2008-05-25 07:44 /lib/libc-2.3.2.so
|
||||
lrwxrwxrwx root/root 0 2008-06-24 17:12 /lib/libc.so.6 -> libc-2.3.2.so
|
||||
...
|
||||
@end smallexample
|
||||
|
||||
Now, you can use our example above to extract it into @file{/usr/local}:
|
||||
Using the expression @samp{s,^,/usr/local/,} would mean adding
|
||||
@samp{/usr/local} to both regular archive members and to link
|
||||
targets. In this case, @file{/lib/libc.so.6} would become:
|
||||
|
||||
@smallexample
|
||||
$ @kbd{tar --transform 's,^,/usr/local/,' \
|
||||
--show-transformed -v -x -f archive}
|
||||
/usr/local/lib/libc.so.6 -> /usr/local/libc-2.3.2.so
|
||||
@end smallexample
|
||||
|
||||
This is definitely not desired. To avoid this, the @samp{S} flag
|
||||
are used, which excludes symbolic link targets from filename
|
||||
transformations. The result is:
|
||||
|
||||
@smallexample
|
||||
$ @kbd{tar --transform 's,^,/usr/local/,S', -c -v -f arch.tar \
|
||||
--show-transformed /lib}
|
||||
drwxr-xr-x root/root 0 2008-07-08 16:20 /usr/local/lib/
|
||||
-rwxr-xr-x root/root 1250840 2008-05-25 07:44 /usr/local/lib/libc-2.3.2.so
|
||||
lrwxrwxrwx root/root 0 2008-06-24 17:12 /usr/local/lib/libc.so.6 ->
|
||||
libc-2.3.2.so
|
||||
@end smallexample
|
||||
|
||||
As you see, it correctly extracts @file{libc.so.6} as a symbolic link
|
||||
to @file{libc-2.3.2.so}.
|
||||
|
||||
However, sometimes you may need to transform symbolic link targets as
|
||||
well. To do so, @GNUTAR provides an additional option:
|
||||
|
||||
@table @option
|
||||
@opindex transform-symlinks
|
||||
@item --transform-symlinks
|
||||
Apply @command{--transform} option to symbolic link targets.
|
||||
|
||||
@opindex no-transform-symlinks
|
||||
@itemx --no-transform-symlinks
|
||||
Cancel the effect of the previous @option{--transform-symlinks} option.
|
||||
@end table
|
||||
|
||||
Unlike @option{--strip-components}, @option{--transform} can be used
|
||||
in any @GNUTAR{} operation mode. For example, the following command
|
||||
adds files to the archive while replacing the leading @file{usr/}
|
||||
|
||||
@ -35,6 +35,7 @@ chdir-long.h
|
||||
chown.c
|
||||
close-stream.c
|
||||
close-stream.h
|
||||
close.c
|
||||
closeout.c
|
||||
closeout.h
|
||||
config.charset
|
||||
@ -59,6 +60,7 @@ fchdir.c
|
||||
fchmodat.c
|
||||
fchown-stub.c
|
||||
fchownat.c
|
||||
fclose.c
|
||||
fcntl--.h
|
||||
fcntl-safer.h
|
||||
fcntl.h
|
||||
|
||||
20
src/common.h
20
src/common.h
@ -346,9 +346,6 @@ GLOBAL bool unquote_option;
|
||||
|
||||
GLOBAL bool test_label_option; /* Test archive volume label and exit */
|
||||
|
||||
/* Apply transformations to symlink targets as well. */
|
||||
GLOBAL bool transform_symlinks_option;
|
||||
|
||||
/* Show file or archive names after transformation.
|
||||
In particular, when creating archive in verbose mode, list member names
|
||||
as stored in the archive */
|
||||
@ -738,17 +735,16 @@ bool string_ascii_p (const char *str);
|
||||
bool utf8_convert (bool to_utf, char const *input, char **output);
|
||||
|
||||
/* Module transform.c */
|
||||
typedef enum
|
||||
{
|
||||
xform_regfile,
|
||||
xform_link,
|
||||
xform_symlink
|
||||
} xform_type;
|
||||
#define XFORM_REGFILE 0x01
|
||||
#define XFORM_LINK 0x02
|
||||
#define XFORM_SYMLINK 0x04
|
||||
#define XFORM_ALL (XFORM_REGFILE|XFORM_LINK|XFORM_SYMLINK)
|
||||
|
||||
void set_transform_expr (const char *expr);
|
||||
bool transform_name (char **pinput);
|
||||
bool transform_member_name (char **pinput, xform_type type);
|
||||
bool transform_name_fp (char **pinput, char *(*fun)(char *, void *), void *);
|
||||
bool transform_name (char **pinput, int type);
|
||||
bool transform_member_name (char **pinput, int type);
|
||||
bool transform_name_fp (char **pinput, int type,
|
||||
char *(*fun)(char *, void *), void *);
|
||||
|
||||
/* Module suffix.c */
|
||||
void set_comression_program_by_suffix (const char *name, const char *defprog);
|
||||
|
||||
@ -1495,7 +1495,7 @@ dump_file0 (struct tar_stat_info *st, const char *p,
|
||||
assign_string (&st->file_name,
|
||||
safer_name_suffix (p, false, absolute_names_option));
|
||||
|
||||
transform_name (&st->file_name);
|
||||
transform_name (&st->file_name, XFORM_REGFILE);
|
||||
|
||||
if (deref_stat (dereference_option, p, &st->stat) != 0)
|
||||
{
|
||||
@ -1705,8 +1705,7 @@ dump_file0 (struct tar_stat_info *st, const char *p,
|
||||
}
|
||||
buffer[size] = '\0';
|
||||
assign_string (&st->link_name, buffer);
|
||||
if (transform_symlinks_option)
|
||||
transform_name (&st->link_name);
|
||||
transform_name (&st->link_name, XFORM_SYMLINK);
|
||||
if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT) < size)
|
||||
write_long_link (st);
|
||||
|
||||
|
||||
@ -917,7 +917,6 @@ extract_link (char *file_name, int typeflag)
|
||||
int interdir_made = 0;
|
||||
char const *link_name;
|
||||
|
||||
transform_member_name (¤t_stat_info.link_name, xform_link);
|
||||
link_name = current_stat_info.link_name;
|
||||
|
||||
if (! absolute_names_option && contains_dot_dot (link_name))
|
||||
@ -974,8 +973,6 @@ extract_symlink (char *file_name, int typeflag)
|
||||
int status;
|
||||
int interdir_made = 0;
|
||||
|
||||
transform_member_name (¤t_stat_info.link_name, xform_symlink);
|
||||
|
||||
if (! absolute_names_option
|
||||
&& (IS_ABSOLUTE_FILE_NAME (current_stat_info.link_name)
|
||||
|| contains_dot_dot (current_stat_info.link_name)))
|
||||
|
||||
23
src/list.c
23
src/list.c
@ -472,11 +472,11 @@ read_header (bool raw_extended_headers)
|
||||
static char *
|
||||
decode_xform (char *file_name, void *data)
|
||||
{
|
||||
xform_type type = *(xform_type*)data;
|
||||
int type = *(int*)data;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case xform_symlink:
|
||||
case XFORM_SYMLINK:
|
||||
/* FIXME: It is not quite clear how and to which extent are the symbolic
|
||||
links subject to filename transformation. In the absence of another
|
||||
solution, symbolic links are exempt from component stripping and
|
||||
@ -484,11 +484,11 @@ decode_xform (char *file_name, void *data)
|
||||
proper. */
|
||||
return file_name;
|
||||
|
||||
case xform_link:
|
||||
case XFORM_LINK:
|
||||
file_name = safer_name_suffix (file_name, true, absolute_names_option);
|
||||
break;
|
||||
|
||||
case xform_regfile:
|
||||
case XFORM_REGFILE:
|
||||
file_name = safer_name_suffix (file_name, false, absolute_names_option);
|
||||
break;
|
||||
}
|
||||
@ -505,9 +505,9 @@ decode_xform (char *file_name, void *data)
|
||||
}
|
||||
|
||||
bool
|
||||
transform_member_name (char **pinput, xform_type type)
|
||||
transform_member_name (char **pinput, int type)
|
||||
{
|
||||
return transform_name_fp (pinput, decode_xform, &type);
|
||||
return transform_name_fp (pinput, type, decode_xform, &type);
|
||||
}
|
||||
|
||||
#define ISOCTAL(c) ((c)>='0'&&(c)<='7')
|
||||
@ -628,7 +628,16 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
|
||||
stat_info->is_dumpdir = true;
|
||||
}
|
||||
|
||||
transform_member_name (&stat_info->file_name, xform_regfile);
|
||||
transform_member_name (&stat_info->file_name, XFORM_REGFILE);
|
||||
switch (header->header.typeflag)
|
||||
{
|
||||
case SYMTYPE:
|
||||
transform_member_name (&stat_info->link_name, XFORM_SYMLINK);
|
||||
break;
|
||||
|
||||
case LNKTYPE:
|
||||
transform_member_name (&stat_info->link_name, XFORM_LINK);
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert buffer at WHERE0 of size DIGS from external format to
|
||||
|
||||
14
src/tar.c
14
src/tar.c
@ -287,7 +287,6 @@ enum
|
||||
NO_RECURSION_OPTION,
|
||||
NO_SAME_OWNER_OPTION,
|
||||
NO_SAME_PERMISSIONS_OPTION,
|
||||
NO_TRANSFORM_SYMLINKS_OPTION,
|
||||
NO_UNQUOTE_OPTION,
|
||||
NO_WILDCARDS_MATCH_SLASH_OPTION,
|
||||
NO_WILDCARDS_OPTION,
|
||||
@ -322,7 +321,6 @@ enum
|
||||
TOTALS_OPTION,
|
||||
TO_COMMAND_OPTION,
|
||||
TRANSFORM_OPTION,
|
||||
TRANSFORM_SYMLINKS_OPTION,
|
||||
UNQUOTE_OPTION,
|
||||
USAGE_OPTION,
|
||||
USE_COMPRESS_PROGRAM_OPTION,
|
||||
@ -689,10 +687,6 @@ static struct argp_option options[] = {
|
||||
{"transform", TRANSFORM_OPTION, N_("EXPRESSION"), 0,
|
||||
N_("use sed replace EXPRESSION to transform file names"), GRID+1 },
|
||||
{"xform", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
|
||||
{"transform-symlinks", TRANSFORM_SYMLINKS_OPTION, NULL, 0,
|
||||
N_("apply transformations to symlink targets"), GRID+1 },
|
||||
{"no-transform-symlinks", NO_TRANSFORM_SYMLINKS_OPTION, NULL, 0,
|
||||
N_("cancel effect of the previous --transform-symlinks option"), GRID+1 },
|
||||
#undef GRID
|
||||
|
||||
#define GRID 120
|
||||
@ -1911,14 +1905,6 @@ parse_opt (int key, char *arg, struct argp_state *state)
|
||||
set_transform_expr (arg);
|
||||
break;
|
||||
|
||||
case TRANSFORM_SYMLINKS_OPTION:
|
||||
transform_symlinks_option = true;
|
||||
break;
|
||||
|
||||
case NO_TRANSFORM_SYMLINKS_OPTION:
|
||||
transform_symlinks_option = false;
|
||||
break;
|
||||
|
||||
case USE_COMPRESS_PROGRAM_OPTION:
|
||||
set_use_compress_program_option (arg);
|
||||
break;
|
||||
|
||||
@ -61,6 +61,7 @@ struct transform
|
||||
{
|
||||
struct transform *next;
|
||||
enum transform_type transform_type;
|
||||
int flags;
|
||||
unsigned match_number;
|
||||
regex_t regex;
|
||||
/* Compiled replacement expression */
|
||||
@ -69,6 +70,8 @@ struct transform
|
||||
};
|
||||
|
||||
|
||||
|
||||
int transform_flags = XFORM_ALL;
|
||||
static struct transform *transform_head, *transform_tail;
|
||||
|
||||
static struct transform *
|
||||
@ -131,6 +134,41 @@ add_backref_segment (struct transform *tf, size_t ref)
|
||||
segm->v.ref = ref;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_xform_flags (int *pflags, int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'r':
|
||||
*pflags |= XFORM_REGFILE;
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
*pflags &= ~XFORM_REGFILE;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
*pflags |= XFORM_LINK;
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
*pflags &= ~XFORM_LINK;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
*pflags |= XFORM_SYMLINK;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
*pflags &= ~XFORM_SYMLINK;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
add_case_ctl_segment (struct transform *tf, enum case_ctl_type ctl)
|
||||
{
|
||||
@ -150,8 +188,26 @@ parse_transform_expr (const char *expr)
|
||||
struct transform *tf = new_transform ();
|
||||
|
||||
if (expr[0] != 's')
|
||||
USAGE_ERROR ((0, 0, _("Invalid transform expression")));
|
||||
|
||||
{
|
||||
if (strncmp (expr, "flags=", 6) == 0)
|
||||
{
|
||||
transform_flags = 0;
|
||||
for (expr += 6; *expr; expr++)
|
||||
{
|
||||
if (*expr == ';')
|
||||
{
|
||||
expr++;
|
||||
break;
|
||||
}
|
||||
if (parse_xform_flags (&transform_flags, *expr))
|
||||
USAGE_ERROR ((0, 0, _("Unknown transform flag: %c"),
|
||||
*expr));
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
USAGE_ERROR ((0, 0, _("Invalid transform expression")));
|
||||
}
|
||||
|
||||
delim = expr[1];
|
||||
|
||||
/* Scan regular expression */
|
||||
@ -172,6 +228,7 @@ parse_transform_expr (const char *expr)
|
||||
|
||||
/* Check flags */
|
||||
tf->transform_type = transform_first;
|
||||
tf->flags = transform_flags;
|
||||
for (p = expr + j + 1; *p && *p != ';'; p++)
|
||||
switch (*p)
|
||||
{
|
||||
@ -186,7 +243,7 @@ parse_transform_expr (const char *expr)
|
||||
case 'x':
|
||||
cflags |= REG_EXTENDED;
|
||||
break;
|
||||
|
||||
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
tf->match_number = strtoul (p, (char**) &p, 0);
|
||||
@ -194,8 +251,9 @@ parse_transform_expr (const char *expr)
|
||||
break;
|
||||
|
||||
default:
|
||||
USAGE_ERROR ((0, 0, _("Unknown flag in transform expression: %c"),
|
||||
*p));
|
||||
if (parse_xform_flags (&tf->flags, *p))
|
||||
USAGE_ERROR ((0, 0, _("Unknown flag in transform expression: %c"),
|
||||
*p));
|
||||
}
|
||||
|
||||
if (*p == ';')
|
||||
@ -520,10 +578,11 @@ _single_transform_name_to_obstack (struct transform *tf, char *input)
|
||||
}
|
||||
|
||||
bool
|
||||
_transform_name_to_obstack (char *input, char **output)
|
||||
_transform_name_to_obstack (int flags, char *input, char **output)
|
||||
{
|
||||
struct transform *tf;
|
||||
|
||||
bool alloced = false;
|
||||
|
||||
if (!stk_init)
|
||||
{
|
||||
obstack_init (&stk);
|
||||
@ -532,18 +591,23 @@ _transform_name_to_obstack (char *input, char **output)
|
||||
|
||||
for (tf = transform_head; tf; tf = tf->next)
|
||||
{
|
||||
_single_transform_name_to_obstack (tf, input);
|
||||
input = obstack_finish (&stk);
|
||||
if (tf->flags & flags)
|
||||
{
|
||||
_single_transform_name_to_obstack (tf, input);
|
||||
input = obstack_finish (&stk);
|
||||
alloced = true;
|
||||
}
|
||||
}
|
||||
*output = input;
|
||||
return transform_head != NULL;
|
||||
return alloced;
|
||||
}
|
||||
|
||||
bool
|
||||
transform_name_fp (char **pinput, char *(*fun)(char *, void *), void *dat)
|
||||
transform_name_fp (char **pinput, int flags,
|
||||
char *(*fun)(char *, void *), void *dat)
|
||||
{
|
||||
char *str;
|
||||
bool ret = _transform_name_to_obstack (*pinput, &str);
|
||||
bool ret = _transform_name_to_obstack (flags, *pinput, &str);
|
||||
if (ret)
|
||||
{
|
||||
assign_string (pinput, fun ? fun (str, dat) : str);
|
||||
@ -560,8 +624,8 @@ transform_name_fp (char **pinput, char *(*fun)(char *, void *), void *dat)
|
||||
}
|
||||
|
||||
bool
|
||||
transform_name (char **pinput)
|
||||
transform_name (char **pinput, int type)
|
||||
{
|
||||
return transform_name_fp (pinput, NULL, NULL);
|
||||
return transform_name_fp (pinput, type, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user