diff options
author | Erich Eckner <git@eckner.net> | 2018-02-20 08:59:05 +0100 |
---|---|---|
committer | Erich Eckner <git@eckner.net> | 2018-02-20 08:59:05 +0100 |
commit | 560518c1f1938f05197dcac2e077d078ecf838f0 (patch) | |
tree | cedd6cfe672279a24c12aea32d88ad8fe96785e0 | |
parent | 50beba711af9f13d51246d5413470cc5cb2fc123 (diff) | |
download | Make-560518c1f1938f05197dcac2e077d078ecf838f0.tar.xz |
tools.pas: tDateienMitDaten: sortierte Version automatisch verwalten
-rw-r--r-- | Make.lps | 107 | ||||
-rw-r--r-- | tools.pas | 160 |
2 files changed, 185 insertions, 82 deletions
@@ -21,10 +21,10 @@ <Unit2> <Filename Value="tools.pas"/> <IsPartOfProject Value="True"/> + <IsVisibleTab Value="True"/> <EditorIndex Value="5"/> - <TopLine Value="503"/> - <CursorPos X="25" Y="520"/> - <FoldState Value=" T3iL03B picjO064 pl5lL0D5w"/> + <TopLine Value="259"/> + <CursorPos X="15" Y="288"/> <UsageCount Value="95"/> <Loaded Value="True"/> </Unit2> @@ -41,11 +41,9 @@ <Filename Value="dateibeziehungen.pas"/> <IsPartOfProject Value="True"/> <UnitName Value="dateiBeziehungen"/> - <IsVisibleTab Value="True"/> <EditorIndex Value="1"/> <TopLine Value="793"/> <CursorPos X="44" Y="813"/> - <FoldState Value=" T3jb03C pjYkO0B4 pk5kQ0l3]I7kJ0!7]9AlH0F022]B0lf0G[944jQ033P"/> <UsageCount Value="84"/> <Loaded Value="True"/> </Unit4> @@ -143,122 +141,121 @@ <JumpHistory Count="30" HistoryIndex="29"> <Position1> <Filename Value="dateibeziehungen.pas"/> - <Caret Line="84" Column="23" TopLine="57"/> + <Caret Line="102" Column="33" TopLine="84"/> </Position1> <Position2> <Filename Value="dateibeziehungen.pas"/> - <Caret Line="105" Column="23" TopLine="76"/> + <Caret Line="765" Column="29" TopLine="737"/> </Position2> <Position3> <Filename Value="dateibeziehungen.pas"/> - <Caret Line="277" Column="44" TopLine="128"/> + <Caret Line="915" Column="56" TopLine="903"/> </Position3> <Position4> - <Filename Value="dateibeziehungen.pas"/> - <Caret Line="765" Column="16" TopLine="740"/> + <Filename Value="tools.pas"/> + <Caret Line="514" Column="17" TopLine="504"/> </Position4> <Position5> - <Filename Value="dateibeziehungen.pas"/> - <Caret Line="735" TopLine="685"/> + <Filename Value="tools.pas"/> + <Caret Line="527" Column="90" TopLine="498"/> </Position5> <Position6> - <Filename Value="dateibeziehungen.pas"/> + <Filename Value="tools.pas"/> + <Caret Line="517" Column="29" TopLine="510"/> </Position6> <Position7> - <Filename Value="dateibeziehungen.pas"/> - <Caret Line="102" Column="33" TopLine="73"/> + <Filename Value="tools.pas"/> + <Caret Line="519" Column="75" TopLine="502"/> </Position7> <Position8> <Filename Value="dateibeziehungen.pas"/> - <Caret Line="768" Column="14" TopLine="654"/> + <Caret Line="917" Column="43" TopLine="903"/> </Position8> <Position9> - <Filename Value="dateibeziehungen.pas"/> - <Caret Line="916" Column="24" TopLine="900"/> + <Filename Value="tools.pas"/> + <Caret Line="519" Column="35" TopLine="502"/> </Position9> <Position10> <Filename Value="tools.pas"/> - <Caret Line="55" Column="21" TopLine="38"/> + <Caret Line="513" Column="25" TopLine="499"/> </Position10> <Position11> - <Filename Value="Make.lpr"/> - <Caret Line="68" Column="61" TopLine="46"/> + <Filename Value="dateibeziehungen.pas"/> + <Caret Line="813" Column="94" TopLine="793"/> </Position11> <Position12> - <Filename Value="dateibeziehungen.pas"/> - <Caret Line="761" Column="75" TopLine="739"/> + <Filename Value="../units/mystringlistunit.pas"/> + <Caret Line="40" Column="26" TopLine="25"/> </Position12> <Position13> - <Filename Value="dateibeziehungen.pas"/> - <Caret Line="102" Column="33" TopLine="84"/> + <Filename Value="../units/systemunit.pas"/> + <Caret Line="18" Column="21"/> </Position13> <Position14> - <Filename Value="dateibeziehungen.pas"/> - <Caret Line="765" Column="29" TopLine="737"/> + <Filename Value="../units/systemunit.pas"/> + <Caret Line="19" Column="22"/> </Position14> <Position15> - <Filename Value="dateibeziehungen.pas"/> - <Caret Line="915" Column="56" TopLine="903"/> + <Filename Value="../units/systemunit.pas"/> + <Caret Line="20" Column="22"/> </Position15> <Position16> - <Filename Value="tools.pas"/> - <Caret Line="514" Column="17" TopLine="504"/> + <Filename Value="../units/lowlevelunit.pas"/> + <Caret Line="154" TopLine="121"/> </Position16> <Position17> - <Filename Value="tools.pas"/> - <Caret Line="527" Column="90" TopLine="498"/> + <Filename Value="../units/systemunit.pas"/> + <Caret Line="276" TopLine="254"/> </Position17> <Position18> <Filename Value="tools.pas"/> - <Caret Line="517" Column="29" TopLine="510"/> + <Caret Line="520" Column="25" TopLine="503"/> </Position18> <Position19> <Filename Value="tools.pas"/> - <Caret Line="519" Column="75" TopLine="502"/> + <Caret Line="276" Column="16" TopLine="258"/> </Position19> <Position20> - <Filename Value="dateibeziehungen.pas"/> - <Caret Line="917" Column="43" TopLine="903"/> + <Filename Value="tools.pas"/> + <Caret Line="315" Column="9" TopLine="287"/> </Position20> <Position21> <Filename Value="tools.pas"/> - <Caret Line="519" Column="35" TopLine="502"/> + <Caret Line="322" Column="9" TopLine="294"/> </Position21> <Position22> <Filename Value="tools.pas"/> - <Caret Line="513" Column="25" TopLine="499"/> + <Caret Line="330" Column="9" TopLine="302"/> </Position22> <Position23> - <Filename Value="dateibeziehungen.pas"/> - <Caret Line="813" Column="94" TopLine="793"/> + <Filename Value="tools.pas"/> + <Caret Line="356" Column="9" TopLine="328"/> </Position23> <Position24> - <Filename Value="../units/mystringlistunit.pas"/> - <Caret Line="40" Column="26" TopLine="25"/> + <Filename Value="tools.pas"/> + <Caret Line="367" Column="10" TopLine="339"/> </Position24> <Position25> - <Filename Value="../units/mystringlistunit.pas"/> - <Caret Line="377" Column="36" TopLine="459"/> + <Filename Value="tools.pas"/> + <Caret Line="382" Column="21" TopLine="348"/> </Position25> <Position26> - <Filename Value="../units/systemunit.pas"/> - <Caret Line="18" Column="21"/> + <Filename Value="tools.pas"/> + <Caret Line="385" Column="20" TopLine="357"/> </Position26> <Position27> - <Filename Value="../units/systemunit.pas"/> - <Caret Line="19" Column="22"/> + <Filename Value="tools.pas"/> + <Caret Line="196" Column="28" TopLine="179"/> </Position27> <Position28> - <Filename Value="../units/systemunit.pas"/> - <Caret Line="20" Column="22"/> + <Filename Value="tools.pas"/> </Position28> <Position29> - <Filename Value="../units/lowlevelunit.pas"/> - <Caret Line="154" TopLine="121"/> + <Filename Value="tools.pas"/> + <Caret Line="304" TopLine="275"/> </Position29> <Position30> - <Filename Value="../units/systemunit.pas"/> - <Caret Line="276" TopLine="254"/> + <Filename Value="tools.pas"/> </Position30> </JumpHistory> </ProjectSession> @@ -5,7 +5,7 @@ unit tools; interface uses - classes, sysUtils, process, mystringlistunit, regExpr; + classes, sysUtils, process, mystringlistunit, regExpr, lowlevelunit; type tAktualitaet = (aNichtVorhanden,aVeraltet,aAktuell,aWirdErneuert); @@ -25,14 +25,22 @@ type constructor create(nam: ansiString; ak: tAktualitaet); end; tDateienMitDaten = class(tFPList) + private + sortiert: tLongintArray; istSortiert: boolean; + procedure sortiereNachNamen; inline; + procedure quickSort(li,re,ungeradheit: longint); function rItem(idx: longint): tDateiMitDatum; inline; procedure wItem(idx: longint; neu: tDateiMitDatum); inline; + function rSItem(idx: longint): tDateiMitDatum; inline; public property items[idx: longint]: tDateiMitDatum read rItem write wItem; default; + property sItems[idx: longint]: tDateiMitDatum + read rSItem; constructor create; + destructor destroy; override; procedure mrProper; function add(neu: tDateiMitDatum): longint; function gleicheNamenWie(dmd: tDateienMitDaten): boolean; @@ -41,7 +49,9 @@ type function toMyStringList: tMyStringList; function finde(name: string; wirdAktualitaet: tAktualitaet = aNichtVorhanden): tDateiMitDatum; overload; inline; function finde(name: string; out istNeu: boolean; wirdAktualitaet: tAktualitaet = aNichtVorhanden): tDateiMitDatum; overload; inline; - procedure sortiereNachNamen; + function findeIndex(name: string): longint; inline; + procedure matchAll(regEx: string; out indizes: tLongintArray; istRegex: boolean); + procedure delete(idx: longint); end; function min(a1,a2: tAktualitaet): tAktualitaet; inline; overload; @@ -66,7 +76,7 @@ function dateienMitGueltigerSumme(sumNam: string): tMyStringList; implementation uses - lowlevelunit, math; + math; // tDateiMitDatum ************************************************************** @@ -82,9 +92,65 @@ end; constructor tDateienMitDaten.create; begin inherited create; + setLength(sortiert,0); istSortiert:=true; end; +destructor tDateienMitDaten.destroy; +begin + setLength(sortiert,0); + inherited destroy; +end; + +procedure tDateienMitDaten.sortiereNachNamen; +var + i: longint; +begin + if istSortiert then + exit; + setLength(sortiert,count); + for i:=0 to length(sortiert)-1 do + sortiert[i]:=i; + quickSort(0,count-1,0); + istSortiert:=true; +end; + +procedure tDateienMitDaten.quickSort(li,re,ungeradheit: longint); +var + pivot: string; + l,r,tmp: longint; +begin + if li>=re then + exit; + r:=0; + for l:=li+1 to re do + if items[sortiert[l]].name<>items[sortiert[li]].name then begin + r:=1; + break; + end; + if r=0 then // nur gleiche Namen + exit; + pivot:=items[sortiert[(li+re) div 2]].name; + l:=li; + r:=re; + while l<=r do begin + while (l<length(sortiert)) and (vergleicheStrings(items[sortiert[l]].name,pivot)<ungeradheit) do + inc(l); + while (r>=0) and (vergleicheStrings(items[sortiert[r]].name,pivot)>ungeradheit-1) do + dec(r); + if l<r then begin + tmp:=sortiert[l]; + sortiert[l]:=sortiert[r]; + sortiert[r]:=tmp; + inc(l); + dec(r); + end; + end; + assert(l=r+1,'Fehler in Quicksort: '+intToStr(l)+'<>'+intToStr(r)+'+1!'); + quickSort(li,r,1-ungeradheit); + quickSort(l,re,1-ungeradheit); +end; + function tDateienMitDaten.rItem(idx: longint): tDateiMitDatum; begin result:=tDateiMitDatum(get(idx)); @@ -92,10 +158,17 @@ end; procedure tDateienMitDaten.wItem(idx: longint; neu: tDateiMitDatum); begin + assert(neu.name<>'','wItem: Dateiname darf nicht leer sein!'); put(idx,neu); istSortiert:=false; end; +function tDateienMitDaten.rSItem(idx: longint): tDateiMitDatum; inline; +begin + sortiereNachNamen; + result:=items[sortiert[idx]]; +end; + procedure tDateienMitDaten.mrProper; var i: longint; @@ -103,12 +176,14 @@ begin for i:=0 to count-1 do items[i].free; clear; + setLength(sortiert,0); + istSortiert:=true; end; function tDateienMitDaten.add(neu: tDateiMitDatum): longint; begin + assert(neu.name<>'','add: Dateiname darf nicht leer sein!'); result:=inherited add(neu); - assert(neu.name<>'','Dateiname darf nicht leer sein!'); istSortiert:=false; end; @@ -119,11 +194,9 @@ begin result:=count=dmd.count; if not result then exit; - sortiereNachNamen; - dmd.sortiereNachNamen; result:=false; for i:=0 to count-1 do - if items[i].name <> dmd[i].name then + if sItems[i].name <> dmd.sItems[i].name then exit; result:=true; end; @@ -139,15 +212,15 @@ end; procedure tDateienMitDaten.append(dmd: tDateienMitDaten); var - i,j: longint; - found: boolean; + i,j: longint; begin + j:=0; for i:=0 to dmd.count-1 do begin - found:=false; - for j:=0 to count-1 do - found:=found or (items[j].name = dmd[i].name); - if not found then - add(dmd[i]); + while (j<length(sortiert)) and (vergleicheStrings(dmd.sItems[i].name,sItems[j].name)<0) do + inc(j); + if (j<length(sortiert)) and (vergleicheStrings(dmd.sItems[i].name,sItems[j].name)=0) then + continue; + add(dmd[i]); end; end; @@ -169,15 +242,29 @@ end; function tDateienMitDaten.finde(name: string; out istNeu: boolean; wirdAktualitaet: tAktualitaet = aNichtVorhanden): tDateiMitDatum; var + i: longint; +begin + i:=findeIndex(name); + if (i>=0) and (i<count) and (sItems[i].name = name) then begin + result:=sItems[i]; + istNeu:=false; + exit; + end; + add(tDateiMitDatum.create(name,wirdAktualitaet)); + istNeu:=true; + result:=tDateiMitDatum(last); +end; + +function tDateienMitDaten.findeIndex(name: string): longint; +var li,re,i: longint; begin sortiereNachNamen; - istNeu:=false; li:=0; re:=count-1; while li<=re do begin i:=(li+re) div 2; - case vergleicheStrings(items[i].name,name) of + case vergleicheStrings(sItems[i].name,name) of -1: li:=i+1; 1: re:=i-1; 0: begin @@ -188,23 +275,42 @@ begin end{of case}; end; if li=re then begin - assert(items[li].name=name,'Fehler in Bisektion: '''+items[li].name+'''<>'''+name+'''!'); - result:=items[li]; + assert(sItems[li].name=name,'Fehler in Bisektion: '''+sItems[li].name+'''<>'''+name+'''!'); + result:=li; exit; end; assert(li=re+1,'Fehler in Bisektion: '+intToStr(li)+'<>'+intToStr(re)+'+1!'); - insert(li,tDateiMitDatum.create); - istNeu:=true; - result:=last; - last.name:=name; - last.aktuell:=wirdAktualitaet; + result:=li; end; -procedure tDateienMitDaten.sortiereNachNamen; +procedure tDateienMitDaten.matchAll(regEx: string; out indizes: tLongintArray; istRegex: boolean); +var + re: tRegExpr; + i: longint; begin - if not istSortiert then - sort(@vergleicheNamenVonDateienMitDaten); - istSortiert:=true; + setLength(indizes,0); + if istRegex then begin + re:=tRegExpr.create; + re.expression:=regEx; + for i:=0 to count-1 do + if re.exec(items[i].name) then begin + setLength(indizes,length(indizes)+1); + indizes[length(indizes)-1]:=i; + end; + end + else begin + i:=findeIndex(regEx); + if (i>=0) and (i<count) and (sItems[i].name=regEx) then begin + setLength(indizes,1); + indizes[0]:=longint(sortiert[i]); + end; + end; +end; + +procedure tDateienMitDaten.delete(idx: longint); +begin + inherited delete(idx); + istSortiert:=false; end; // allgemeine Funktionen ******************************************************* |