| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 | {$mode objfpc}{$h+}uses  sysutils,classes,dom,xmlread;procedure error(const s : string);  begin    writeln('Error: ',s);    halt(1);  end;var  doc : txmldocument;  root : TDomNode;  entry,  currentpath,  currentinfo : TDomNode;  hs,  dirprefix,  newlineprefix,  currentmsg,  currentauthor,  currentdate,  pathtemp,  currentrevision : string;  paths : tstringlist;  pathprefixes : tstringlist;  i,j,maxequal : integer;  firstpath : boolean;begin  paths:=tstringlist.create;  paths.sorted:=true;  pathprefixes:=tstringlist.create;  pathprefixes.sorted:=true;  ReadXMLFile(doc,paramstr(1));  root:=doc.DocumentElement;  if root.haschildnodes and    (root.NodeName='log') then    begin      entry:=root.firstchild;      while assigned(entry) do        begin          if entry.NodeName<>'logentry' then            error('Only log entry entries supported, but '+entry.NodeName+' found.');          currentmsg:='';          currentauthor:='';          currentdate:='';          { get revision }          with entry as tdomelement do            currentrevision:=AttribStrings['revision'];          if entry.haschildnodes then            begin              currentinfo:=entry.firstchild;              while assigned(currentinfo) do                begin                  if currentinfo.NodeName='author' then                    begin                      if currentinfo.haschildnodes and                        (currentinfo.firstchild is TDOMText) then                        currentauthor:=(currentinfo.firstchild as TDOMText).Data                      else                        error('Malformed author node');                    end                  else if currentinfo.NodeName='msg' then                    begin                      if currentinfo.haschildnodes then                        begin                          if (currentinfo.firstchild is TDOMText) then                            currentmsg:=(currentinfo.firstchild as TDOMText).Data                          else                            error('Malformed msg node');                        end                      else                        currentmsg:='<empty log message>';                    end                  else if currentinfo.NodeName='date' then                    begin                      if currentinfo.haschildnodes and                        (currentinfo.firstchild is TDOMText) then                        currentdate:=(currentinfo.firstchild as TDOMText).Data                      else                        error('Malformed date node');                    end                  else if currentinfo.NodeName='paths' then                    begin                      currentpath:=currentinfo.firstchild;                      paths.clear;                      pathprefixes.clear;                      while assigned(currentpath) do                        begin                          if currentpath.NodeName<>'path' then                            error('Path node expected');                          if currentpath.haschildnodes and                            (currentpath.firstchild is TDOMText) then                            begin                              paths.add((currentpath.firstchild as TDOMText).Data);                              hs:=ExtractFilePath((currentpath.firstchild as TDOMText).Data);                              if not pathprefixes.Find(hs,i) then                                pathprefixes.add(hs);                            end                          else                            error('Malformed date node');                          currentpath:=currentpath.NextSibling;                        end;                    end                  else                    error('Unknown logentry child '+currentinfo.NodeName+' found');                  currentinfo:=currentinfo.nextsibling;                end;              currentdate:=copy(currentdate,1,16);              { replaced T }              currentdate[11]:=' ';              write(currentdate,' ',currentauthor);              if currentrevision<>'' then                writeln(' r',currentrevision)              else                writeln;              writeln;              { search for common pathprefix }              if pathprefixes.Count>1 then                begin                  maxequal:=65535;                  for i:=1 to pathprefixes.Count-1 do                    begin                      j:=1;                      while (pathprefixes[0][j]=pathprefixes[i][j]) and (j<=maxequal) do                        inc(j);                      dec(j);                      if j<maxequal then                        maxequal:=j;                    end;                  { test/p1.pas test/p2.pas should use the prefix test/ instead of test/p }                  if maxequal<65535 then                    while (maxequal>0) and (pathprefixes[0][maxequal]<>'/') do                      dec(maxequal);                  Writeln('  '+Copy(pathprefixes[0],1,maxequal)+': ');                  dirprefix:='    ';                  newlineprefix:='      ';                end              else                begin                  maxequal:=0;                  dirprefix:='  ';                  newlineprefix:='    ';                end;              for i:=0 to pathprefixes.Count-1 do                begin                  pathtemp:=dirprefix;                  if maxequal+1<length(pathprefixes[i]) then                    pathtemp:=pathtemp+Copy(pathprefixes[i],maxequal+1,65535)+': ';                  firstpath:=true;                  j:=0;                  while (j<paths.Count) do                    begin                      if ExtractFilePath(paths[j])=pathprefixes[i] then                        begin                          hs:=copy(paths[j],length(pathprefixes[i])+1,65535);                          if (length(pathtemp)+length(hs)>=78) and                             (pathtemp<>newlineprefix) then                            begin                              writeln(pathtemp+',');                              pathtemp:=newlineprefix;                              firstpath:=true;                            end;                          { non empty path but not first? }                          if firstpath then                            firstpath:=false                          else                            pathtemp:=pathtemp+', ';                          pathtemp:=pathtemp+hs;                          { delete already processed paths for performance }                          paths.delete(j);                        end                      else                        inc(j);                    end;                  if pathtemp<>newlineprefix then                    writeln(pathtemp);                end;              { truncate trailing spaces and new lines from log message }              i:=length(currentmsg);              while (i>0) and (currentmsg[i] in [#13,#10,#9,' ']) do                dec(i);              delete(currentmsg,i+1,length(currentmsg)-i);              { Pretty print message starting with at least 2 spaces each line }              writeln;              i:=0;              hs:=currentmsg;              while (hs<>'') do                begin                  newlineprefix:='  ';                  i:=0;                  while (i<length(hs)) and not(hs[i+1] in [#13,#10]) do                    inc(i);                  j:=1;                  while (j<length(hs)) and                        (j<length(newlineprefix)) and                        (hs[j] in [' ']) do                    inc(j);                  writeln(newlineprefix,copy(hs,j,i-j+1));                  { remove eol and add additional empty lines }                  j:=0;                  while (i<length(hs)) and (hs[i+1] in [#13,#10]) do                    begin                      if hs[i+1]=#10 then                        begin                          inc(j);                          if j>2 then                            writeln;                        end;                      inc(i);                    end;                  delete(hs,1,i);                end;              writeln;            end          else            error('Empty log entry found');          entry:=entry.nextsibling;        end;    end  else    error('log element not found/wrong xml format');end.
 |