[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [bug-gnu-libiconv] Add -i inplace option for iconv.
From: |
Heikki Orsila |
Subject: |
Re: [bug-gnu-libiconv] Add -i inplace option for iconv. |
Date: |
Tue, 31 Jul 2018 17:00:36 +0300 |
User-agent: |
Mutt/1.5.23 (2014-03-12) |
On Tue, Jul 31, 2018 at 12:55:56AM +0200, Bruno Haible wrote:
> Heikki Orsila wrote:
> > so why not just create it for iconv tool like "sed -i" does?
>
> As I said: it violates the Unix philosophy. Read about it in [1][2].
The philosophy is shades of grey.
>
> > So I thought of writing a suitable shell script that would use
> >
> > $(tempfile -d "$(dirname "$f")") || error_check
> >
> > and realized everyone who needs this use-case is just doing redundant work,
>
> That's true. The logic for creating a temp file is something needed
> frequently in various places.
>
> So why don't you create a program named, say, 'inplace', with the property
> that
>
> inplace PROGRAM ARGUMENTS... FILE
>
> does essentially (but with more correct placement and handling of
> the temporary file and symlinks):
>
> mv FILE FILE'~' && PROGRAM ARGUMENTS... < FILE'~' > FILE && rm -f FILE'~'
>
> Such a program would fit well with the Unix philosophy. You could even
> propose it for inclusion in the 'coreutils'.
That's an interesting idea and could certainly be useful for some tools.
I thought maybe there is a middle way here that alleviates the problem of
code complexity. I imagine the problem with 60 lines of code was mainly
that it added complexity to the control structures of the main function.
However, this change could be done with significantly less complexity
for the control structures in main by doing the following:
struct inplace_file { ... }
/* Enables inplace mode if outfile == NULL and infilename != NULL. */
int inplace_file_open(struct inplace_file* inplacefile,
FILE* infile, const char* infilename, FILE* outfile);
int inplace_file_input_fileno(struct inplace_file* inplacefile);
int inplace_file_close(struct inplace_file* inplacefile);
Now, that change in the main loop control structure would only be more or
less the following:
status |= convert(cd,fileno(infile),infilename);
fclose(infile);
=>
if (inplace_file_open(&inplacefile, infile, infilename,
do_inplace ? NULL : stdout)) {
error(...);
status = 1;
} else {
status |= convert(cd, inplace_file_input_fileno(&inplacefile),
infilename,
inplace_file_get_outfile(&inplacefile));
inplace_file_close(inplacefile);
}
This tool could also be reused across tools if put into separate module/headers.
Then it would be pretty easy to implement inplace semantics for many tools
that rely on FILE* stream semantics.
--
Heikki Orsila
address@hidden
http://www.iki.fi/shd