2
2
#include "string-list.h"
3
3
#include "run-command.h"
4
4
#include "commit.h"
5
+ #include "tempfile.h"
5
6
#include "trailer.h"
6
7
/*
7
8
* Copyright (c) 2013, 2014 Christian Couder <[email protected] >
@@ -108,23 +109,23 @@ static char last_non_space_char(const char *s)
108
109
return '\0' ;
109
110
}
110
111
111
- static void print_tok_val (const char * tok , const char * val )
112
+ static void print_tok_val (FILE * outfile , const char * tok , const char * val )
112
113
{
113
114
char c = last_non_space_char (tok );
114
115
if (!c )
115
116
return ;
116
117
if (strchr (separators , c ))
117
- printf ( "%s%s\n" , tok , val );
118
+ fprintf ( outfile , "%s%s\n" , tok , val );
118
119
else
119
- printf ( "%s%c %s\n" , tok , separators [0 ], val );
120
+ fprintf ( outfile , "%s%c %s\n" , tok , separators [0 ], val );
120
121
}
121
122
122
- static void print_all (struct trailer_item * first , int trim_empty )
123
+ static void print_all (FILE * outfile , struct trailer_item * first , int trim_empty )
123
124
{
124
125
struct trailer_item * item ;
125
126
for (item = first ; item ; item = item -> next ) {
126
127
if (!trim_empty || strlen (item -> value ) > 0 )
127
- print_tok_val (item -> token , item -> value );
128
+ print_tok_val (outfile , item -> token , item -> value );
128
129
}
129
130
}
130
131
@@ -795,14 +796,15 @@ static int has_blank_line_before(struct strbuf **lines, int start)
795
796
return 0 ;
796
797
}
797
798
798
- static void print_lines (struct strbuf * * lines , int start , int end )
799
+ static void print_lines (FILE * outfile , struct strbuf * * lines , int start , int end )
799
800
{
800
801
int i ;
801
802
for (i = start ; lines [i ] && i < end ; i ++ )
802
- printf ( "%s" , lines [i ]-> buf );
803
+ fprintf ( outfile , "%s" , lines [i ]-> buf );
803
804
}
804
805
805
- static int process_input_file (struct strbuf * * lines ,
806
+ static int process_input_file (FILE * outfile ,
807
+ struct strbuf * * lines ,
806
808
struct trailer_item * * in_tok_first ,
807
809
struct trailer_item * * in_tok_last )
808
810
{
@@ -818,10 +820,10 @@ static int process_input_file(struct strbuf **lines,
818
820
trailer_start = find_trailer_start (lines , trailer_end );
819
821
820
822
/* Print lines before the trailers as is */
821
- print_lines (lines , 0 , trailer_start );
823
+ print_lines (outfile , lines , 0 , trailer_start );
822
824
823
825
if (!has_blank_line_before (lines , trailer_start - 1 ))
824
- printf ( "\n" );
826
+ fprintf ( outfile , "\n" );
825
827
826
828
/* Parse trailer lines */
827
829
for (i = trailer_start ; i < trailer_end ; i ++ ) {
@@ -842,33 +844,72 @@ static void free_all(struct trailer_item **first)
842
844
}
843
845
}
844
846
845
- void process_trailers (const char * file , int trim_empty , struct string_list * trailers )
847
+ static struct tempfile trailers_tempfile ;
848
+
849
+ static FILE * create_in_place_tempfile (const char * file )
850
+ {
851
+ struct stat st ;
852
+ struct strbuf template = STRBUF_INIT ;
853
+ const char * tail ;
854
+ FILE * outfile ;
855
+
856
+ if (stat (file , & st ))
857
+ die_errno (_ ("could not stat %s" ), file );
858
+ if (!S_ISREG (st .st_mode ))
859
+ die (_ ("file %s is not a regular file" ), file );
860
+ if (!(st .st_mode & S_IWUSR ))
861
+ die (_ ("file %s is not writable by user" ), file );
862
+
863
+ /* Create temporary file in the same directory as the original */
864
+ tail = strrchr (file , '/' );
865
+ if (tail != NULL )
866
+ strbuf_add (& template , file , tail - file + 1 );
867
+ strbuf_addstr (& template , "git-interpret-trailers-XXXXXX" );
868
+
869
+ xmks_tempfile_m (& trailers_tempfile , template .buf , st .st_mode );
870
+ strbuf_release (& template );
871
+ outfile = fdopen_tempfile (& trailers_tempfile , "w" );
872
+ if (!outfile )
873
+ die_errno (_ ("could not open temporary file" ));
874
+
875
+ return outfile ;
876
+ }
877
+
878
+ void process_trailers (const char * file , int in_place , int trim_empty , struct string_list * trailers )
846
879
{
847
880
struct trailer_item * in_tok_first = NULL ;
848
881
struct trailer_item * in_tok_last = NULL ;
849
882
struct trailer_item * arg_tok_first ;
850
883
struct strbuf * * lines ;
851
884
int trailer_end ;
885
+ FILE * outfile = stdout ;
852
886
853
887
/* Default config must be setup first */
854
888
git_config (git_trailer_default_config , NULL );
855
889
git_config (git_trailer_config , NULL );
856
890
857
891
lines = read_input_file (file );
858
892
893
+ if (in_place )
894
+ outfile = create_in_place_tempfile (file );
895
+
859
896
/* Print the lines before the trailers */
860
- trailer_end = process_input_file (lines , & in_tok_first , & in_tok_last );
897
+ trailer_end = process_input_file (outfile , lines , & in_tok_first , & in_tok_last );
861
898
862
899
arg_tok_first = process_command_line_args (trailers );
863
900
864
901
process_trailers_lists (& in_tok_first , & in_tok_last , & arg_tok_first );
865
902
866
- print_all (in_tok_first , trim_empty );
903
+ print_all (outfile , in_tok_first , trim_empty );
867
904
868
905
free_all (& in_tok_first );
869
906
870
907
/* Print the lines after the trailers as is */
871
- print_lines (lines , trailer_end , INT_MAX );
908
+ print_lines (outfile , lines , trailer_end , INT_MAX );
909
+
910
+ if (in_place )
911
+ if (rename_tempfile (& trailers_tempfile , file ))
912
+ die_errno (_ ("could not rename temporary file to %s" ), file );
872
913
873
914
strbuf_list_free (lines );
874
915
}
0 commit comments