diff -u gawk-3.1.6/awk.h gawk-3.1.6-inplace-edit/awk.h --- gawk-3.1.6/awk.h 2007-10-01 04:50:43.000000000 +0900 +++ gawk-3.1.6-inplace-edit/awk.h 2009-01-09 16:37:23.047625000 +0900 @@ -801,6 +801,10 @@ extern char casetable[]; /* for case-independent regexp matching */ +#if 2 +extern int do_inplace_edit; +#endif + /* ------------------------- Pseudo-functions ------------------------- */ #define is_identchar(c) (isalnum(c) || (c) == '_') diff -u gawk-3.1.6/builtin.c gawk-3.1.6-inplace-edit/builtin.c --- gawk-3.1.6/builtin.c 2007-10-01 04:57:05.000000000 +0900 +++ gawk-3.1.6-inplace-edit/builtin.c 2009-01-09 16:37:23.047625000 +0900 @@ -1315,6 +1315,77 @@ return r; } +#if 2 +/* + * + */ +static FILE* current_tmpfile_fp = NULL; +static char current_tmpfile_name[1024] = ""; +static const char *current_file_name = NULL; + +/* + * close_tmpfile + */ + +int +close_tmpfile() +{ + char backupfilename[1024]; + + if (!current_tmpfile_fp) + return 0; + + //fprintf(stderr, "copy %s -> %s\n", current_file_name, current_tmpfile_name); + fclose(current_tmpfile_fp); + snprintf(backupfilename, sizeof backupfilename, "%s.~", current_file_name); +#if _WIN32 + /* In Windows, rename() fail when already exists backupfile. + * Then we have to delete the file before call of rename() + */ + unlink(backupfilename); +#endif + rename(current_file_name, backupfilename); /* make backup */ + rename(current_tmpfile_name, current_file_name); /* update */ + + current_tmpfile_fp = NULL; + return 0; +} + +/* + * get_current_tmp --- + */ + +FILE* +get_current_tmp() +{ + return current_tmpfile_fp; +} + +/* + * create_filen_for_inplace_edit --- + */ +FILE* +create_file_for_inplace_edit(const char* filename) +{ + char *p; + + if (current_tmpfile_fp) { + close_tmpfile(); + } + + current_file_name = strdup(filename); +#ifndef _WIN32 + snprintf(current_tmpfile_name, sizeof current_tmpfile_name, "%sXXXXXX", filename); + p = mkstemp(current_tmpfile_name); +#else + p = tmpnam(current_tmpfile_name); +#endif + current_tmpfile_fp = fopen(p, "wb+"); + + return current_tmpfile_fp; +} +#endif + /* * redirect_to_fp --- return fp for redirection, NULL on failure * or stdout if no redirection, used by all print routines diff -u gawk-3.1.6/io.c gawk-3.1.6-inplace-edit/io.c --- gawk-3.1.6/io.c 2007-08-12 04:39:49.000000000 +0900 +++ gawk-3.1.6-inplace-edit/io.c 2009-01-09 16:37:23.094500000 +0900 @@ -279,17 +279,31 @@ static IOBUF *curfile = NULL; static IOBUF mybuf; const char *fname; +#if 2 + extern int create_file_for_inplace_edit(const char*); + extern int close_tmpfile(); +#endif if (skipping) { if (curfile != NULL) iop_close(curfile); curfile = NULL; +#if 2 + if (do_inplace_edit) { + close_tmpfile(); + } +#endif return NULL; } if (curfile != NULL) { if (at_eof(curfile)) { (void) iop_close(curfile); curfile = NULL; +#if 2 + if (do_inplace_edit) { + close_tmpfile(); + } +#endif } else return curfile; } @@ -324,6 +338,11 @@ FILENAME_node->var_value = dupnode(arg); FNR = 0; i++; +#if 2 + if (do_inplace_edit) { + create_file_for_inplace_edit(fname); + } +#endif break; } } diff -u gawk-3.1.6/main.c gawk-3.1.6-inplace-edit/main.c --- gawk-3.1.6/main.c 2007-10-01 04:55:18.000000000 +0900 +++ gawk-3.1.6-inplace-edit/main.c 2009-01-09 16:42:49.907000000 +0900 @@ -196,6 +196,9 @@ #if defined(YYDEBUG) || defined(GAWKDEBUG) { "parsedebug", no_argument, NULL, 'D' }, #endif +#if 2 + { "inplace-edit", optional_argument, NULL, 'i' }, +#endif { NULL, 0, NULL, '\0' } }; @@ -432,6 +435,12 @@ #endif /* if not debugging, fall through */ +#if 2 + case 'i': + do_inplace_edit = TRUE; + break; +#endif + case '?': default: /*