@@ -37,8 +37,11 @@ static const char apply_usage[] =
3737static enum whitespace_eol {
3838 nowarn ,
3939 warn_on_whitespace ,
40- error_on_whitespace
40+ error_on_whitespace ,
41+ strip_and_apply ,
4142} new_whitespace = nowarn ;
43+ static int whitespace_error = 0 ;
44+ static const char * patch_input_file = NULL ;
4245
4346/*
4447 * For "diff-stat" like behaviour, we keep track of the biggest change
@@ -823,19 +826,17 @@ static int parse_fragment(char *line, unsigned long size, struct patch *patch, s
823826 case '+' :
824827 /*
825828 * We know len is at least two, since we have a '+' and
826- * we checked that the last character was a '\n' above
829+ * we checked that the last character was a '\n' above.
830+ * That is, an addition of an empty line would check
831+ * the '+' here. Sneaky...
827832 */
828- if (isspace (line [len - 2 ])) {
829- switch (new_whitespace ) {
830- case nowarn :
831- break ;
832- case warn_on_whitespace :
833- new_whitespace = nowarn ; /* Just once */
834- error ("Added whitespace at end of line at line %d" , linenr );
835- break ;
836- case error_on_whitespace :
837- die ("Added whitespace at end of line at line %d" , linenr );
838- }
833+ if ((new_whitespace != nowarn ) &&
834+ isspace (line [len - 2 ])) {
835+ fprintf (stderr , "Added whitespace\n" );
836+ fprintf (stderr , "%s:%d:%.*s\n" ,
837+ patch_input_file ,
838+ linenr , len - 2 , line + 1 );
839+ whitespace_error = 1 ;
839840 }
840841 added ++ ;
841842 newlines -- ;
@@ -1114,6 +1115,27 @@ struct buffer_desc {
11141115 unsigned long alloc ;
11151116};
11161117
1118+ static int apply_line (char * output , const char * patch , int plen )
1119+ {
1120+ /* plen is number of bytes to be copied from patch,
1121+ * starting at patch+1 (patch[0] is '+'). Typically
1122+ * patch[plen] is '\n'.
1123+ */
1124+ int add_nl_to_tail = 0 ;
1125+ if ((new_whitespace == strip_and_apply ) &&
1126+ 1 < plen && isspace (patch [plen - 1 ])) {
1127+ if (patch [plen ] == '\n' )
1128+ add_nl_to_tail = 1 ;
1129+ plen -- ;
1130+ while (0 < plen && isspace (patch [plen ]))
1131+ plen -- ;
1132+ }
1133+ memcpy (output , patch + 1 , plen );
1134+ if (add_nl_to_tail )
1135+ output [plen ++ ] = '\n' ;
1136+ return plen ;
1137+ }
1138+
11171139static int apply_one_fragment (struct buffer_desc * desc , struct fragment * frag )
11181140{
11191141 char * buf = desc -> buffer ;
@@ -1149,10 +1171,9 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag)
11491171 break ;
11501172 /* Fall-through for ' ' */
11511173 case '+' :
1152- if (* patch != '+' || !no_add ) {
1153- memcpy (new + newsize , patch + 1 , plen );
1154- newsize += plen ;
1155- }
1174+ if (* patch != '+' || !no_add )
1175+ newsize += apply_line (new + newsize , patch ,
1176+ plen );
11561177 break ;
11571178 case '@' : case '\\' :
11581179 /* Ignore it, we already handled it */
@@ -1721,14 +1742,15 @@ static int use_patch(struct patch *p)
17211742 return 1 ;
17221743}
17231744
1724- static int apply_patch (int fd )
1745+ static int apply_patch (int fd , const char * filename )
17251746{
17261747 int newfd ;
17271748 unsigned long offset , size ;
17281749 char * buffer = read_patch_file (fd , & size );
17291750 struct patch * list = NULL , * * listp = & list ;
17301751 int skipped_patch = 0 ;
17311752
1753+ patch_input_file = filename ;
17321754 if (!buffer )
17331755 return -1 ;
17341756 offset = 0 ;
@@ -1755,6 +1777,9 @@ static int apply_patch(int fd)
17551777 }
17561778
17571779 newfd = -1 ;
1780+ if (whitespace_error && (new_whitespace == error_on_whitespace ))
1781+ apply = 0 ;
1782+
17581783 write_index = check_index && apply ;
17591784 if (write_index )
17601785 newfd = hold_index_file_for_update (& cache_file , get_index_file ());
@@ -1801,7 +1826,7 @@ int main(int argc, char **argv)
18011826 int fd ;
18021827
18031828 if (!strcmp (arg , "-" )) {
1804- apply_patch (0 );
1829+ apply_patch (0 , "<stdin>" );
18051830 read_stdin = 0 ;
18061831 continue ;
18071832 }
@@ -1862,14 +1887,18 @@ int main(int argc, char **argv)
18621887 continue ;
18631888 }
18641889 if (!strncmp (arg , "--whitespace=" , 13 )) {
1865- if (strcmp (arg + 13 , "warn" )) {
1890+ if (! strcmp (arg + 13 , "warn" )) {
18661891 new_whitespace = warn_on_whitespace ;
18671892 continue ;
18681893 }
1869- if (strcmp (arg + 13 , "error" )) {
1894+ if (! strcmp (arg + 13 , "error" )) {
18701895 new_whitespace = error_on_whitespace ;
18711896 continue ;
18721897 }
1898+ if (!strcmp (arg + 13 , "strip" )) {
1899+ new_whitespace = strip_and_apply ;
1900+ continue ;
1901+ }
18731902 die ("unrecognixed whitespace option '%s'" , arg + 13 );
18741903 }
18751904
@@ -1885,10 +1914,12 @@ int main(int argc, char **argv)
18851914 if (fd < 0 )
18861915 usage (apply_usage );
18871916 read_stdin = 0 ;
1888- apply_patch (fd );
1917+ apply_patch (fd , arg );
18891918 close (fd );
18901919 }
18911920 if (read_stdin )
1892- apply_patch (0 );
1921+ apply_patch (0 , "<stdin>" );
1922+ if (whitespace_error && new_whitespace == error_on_whitespace )
1923+ return 1 ;
18931924 return 0 ;
18941925}
0 commit comments