@@ -41,16 +41,16 @@ public final class UnifiedDiffReader {
4141
4242private final InternalUnifiedDiffReader READER ;
4343private final UnifiedDiff data =new UnifiedDiff ();
44- private final UnifiedDiffLine [] MAIN_PARSER_RULES = new UnifiedDiffLine []{
45- new UnifiedDiffLine (true ,"^diff\\ s" ,this ::processDiff ),
46- new UnifiedDiffLine (true ,"^index\\ s[\\ da-zA-Z]+\\ .\\ .[\\ da-zA-Z]+(\\ s(\\ d+))?$" ,this ::processIndex ),
47- new UnifiedDiffLine (true ,"^---\\ s" ,this ::processFromFile ),
48- new UnifiedDiffLine (true ,"^\\ +\\ +\\ +\\ s" ,this ::processToFile ),
49- new UnifiedDiffLine ( false , UNIFIED_DIFF_CHUNK_REGEXP , this :: processChunk ),
50- new UnifiedDiffLine ("^ \\ s+" , this ::processNormalLine ),
51- new UnifiedDiffLine ("^- " ,this ::processDelLine ),
52- new UnifiedDiffLine ("^+ " ,this ::processAddLine )
53- } ;
44+
45+ private final UnifiedDiffLine DIFF_COMMAND = new UnifiedDiffLine (true ,"^diff\\ s" ,this ::processDiff );
46+ private final UnifiedDiffLine INDEX = new UnifiedDiffLine (true ,"^index\\ s[\\ da-zA-Z]+\\ .\\ .[\\ da-zA-Z]+(\\ s(\\ d+))?$" ,this ::processIndex );
47+ private final UnifiedDiffLine FROM_FILE = new UnifiedDiffLine (true ,"^---\\ s" ,this ::processFromFile );
48+ private final UnifiedDiffLine TO_FILE = new UnifiedDiffLine (true ,"^\\ +\\ +\\ +\\ s" ,this ::processToFile );
49+
50+ private final UnifiedDiffLine CHUNK = new UnifiedDiffLine (false , UNIFIED_DIFF_CHUNK_REGEXP , this ::processChunk );
51+ private final UnifiedDiffLine LINE_NORMAL = new UnifiedDiffLine ("^\\ s+ " ,this ::processNormalLine );
52+ private final UnifiedDiffLine LINE_DEL = new UnifiedDiffLine ("^- " ,this ::processDelLine );
53+ private final UnifiedDiffLine LINE_ADD = new UnifiedDiffLine ( "^+" , this :: processAddLine ) ;
5454
5555private UnifiedDiffFile actualFile ;
5656
@@ -63,32 +63,37 @@ public final class UnifiedDiffReader {
6363// [/^---\s/, from_file], [/^\+\+\+\s/, to_file], [/^@@\s+\-(\d+),?(\d+)?\s+\+(\d+),?(\d+)?\s@@/, chunk],
6464// [/^-/, del], [/^\+/, add], [/^\\ No newline at end of file$/, eof]];
6565private UnifiedDiff parse ()throws IOException ,UnifiedDiffParserException {
66- boolean header =true ;
6766String headerTxt ="" ;
68- String tailTxt ="" ;
67+ LOG .log (Level .INFO ,"header parsing" );
68+ String line =null ;
6969while (READER .ready ()) {
70- String line =READER .readLine ();
71- if (line .matches ("--\\ s*" )) {
70+ line =READER .readLine ();
71+ LOG .log (Level .INFO ,"parsing line {0}" ,line );
72+ if (DIFF_COMMAND .validLine (line ) ||INDEX .validLine (line )
73+ ||FROM_FILE .validLine (line ) ||TO_FILE .validLine (line )) {
7274break ;
7375 }else {
74- LOG .log (Level .INFO ,"parsing line {0}" ,line );
75- if (processLine (header ,line ) ==false ) {
76- if (header ) {
77- headerTxt +=line +"\n " ;
78- }else {
79- break ;
80- }
81- }else {
82- if (header ) {
83- header =false ;
84- data .setHeader (headerTxt );
85- }
76+ headerTxt +=line +"\n " ;
77+ }
78+ }
79+ data .setHeader (headerTxt );
80+
81+ while (line !=null ) {
82+ if (!CHUNK .validLine (line )) {
83+ if (processLine (line ,DIFF_COMMAND ,INDEX ,FROM_FILE ,TO_FILE ) ==false ) {
84+ throw new UnifiedDiffParserException ("parsing error at line " +line );
85+ }
86+ }else {
87+ if (processLine (line ,CHUNK ) ==false ) {
88+ throw new UnifiedDiffParserException ("parsing error at line " +line );
8689 }
8790 }
91+ line =READER .readLine ();
8892 }
8993
9094finalizeChunk ();
9195
96+ String tailTxt ="" ;
9297while (READER .ready ()) {
9398tailTxt +=READER .readLine () +"\n " ;
9499 }
@@ -112,13 +117,11 @@ public static UnifiedDiff parseUnifiedDiff(InputStream stream) throws IOExceptio
112117return parser .parse ();
113118 }
114119
115- private boolean processLine (boolean header ,String line )throws UnifiedDiffParserException {
116- for (UnifiedDiffLine rule :MAIN_PARSER_RULES ) {
117- if (header &&rule .isStopsHeaderParsing () || !header ) {
118- if (rule .processLine (line )) {
119- LOG .info (" >>> processed rule " +rule .toString ());
120- return true ;
121- }
120+ private boolean processLine (String line ,UnifiedDiffLine ...rules )throws UnifiedDiffParserException {
121+ for (UnifiedDiffLine rule :rules ) {
122+ if (rule .processLine (line )) {
123+ LOG .info (" >>> processed rule " +rule .toString ());
124+ return true ;
122125 }
123126 }
124127LOG .info (" >>> no rule matched " +line );
@@ -210,7 +213,7 @@ private String extractFileName(String line) {
210213return line .substring (4 ).replaceFirst ("^(a|b)\\ /" ,"" );
211214 }
212215
213- class UnifiedDiffLine {
216+ final class UnifiedDiffLine {
214217
215218private final Pattern pattern ;
216219private final BiConsumer <MatchResult ,String >command ;
@@ -232,6 +235,11 @@ public UnifiedDiffLine(boolean stopsHeaderParsing, Pattern pattern, BiConsumer<M
232235this .stopsHeaderParsing =stopsHeaderParsing ;
233236 }
234237
238+ public boolean validLine (String line ) {
239+ Matcher m =pattern .matcher (line );
240+ return m .find ();
241+ }
242+
235243public boolean processLine (String line )throws UnifiedDiffParserException {
236244Matcher m =pattern .matcher (line );
237245if (m .find ()) {