/* chunks.c */ /*****************************************************************************/ /* AS-Portierung */ /* */ /* Verwaltung von Adressbereichslisten */ /* */ /* Historie: 16. 5.1996 Grundsteinlegung */ /* 16. 8.1998 Min/Max-Ausgabe */ /* */ /*****************************************************************************/ #include "stdinc.h" #include "strutil.h" #include "chunks.h" /*--------------------------------------------------------------------------*/ /* eine Chunkliste initialisieren */ void InitChunk(ChunkList *NChunk) BEGIN NChunk->RealLen=0; NChunk->AllocLen=0; NChunk->Chunks=Nil; END void ClearChunk(ChunkList *NChunk) BEGIN if (NChunk->AllocLen>0) free(NChunk->Chunks); InitChunk(NChunk); END /*--------------------------------------------------------------------------*/ /* eine Chunkliste um einen Eintrag erweitern */ static Boolean Overlap(LargeWord Start1, LargeWord Len1, LargeWord Start2, LargeWord Len2) BEGIN return ((Start1==Start2) OR ((Start2>Start1) AND (Start1+Len1>=Start2)) OR ((Start1>Start2) AND (Start2+Len2>=Start1))); END static void SetChunk(OneChunk *NChunk, LargeWord Start1, LargeWord Len1, LargeWord Start2, LargeWord Len2) BEGIN NChunk->Start =min(Start1,Start2); NChunk->Length=max(Start1+Len1-1,Start2+Len2-1)-NChunk->Start+1; END static void IncChunk(ChunkList *NChunk) BEGIN if (NChunk->RealLen+1>NChunk->AllocLen) BEGIN if (NChunk->RealLen==0) NChunk->Chunks=(OneChunk *) malloc(sizeof(OneChunk)); else NChunk->Chunks=(OneChunk *) realloc(NChunk->Chunks,sizeof(OneChunk)*(NChunk->RealLen+1)); NChunk->AllocLen=NChunk->RealLen+1; END END Boolean AddChunk(ChunkList *NChunk, LargeWord NewStart, LargeWord NewLen, Boolean Warn) BEGIN Word z,f1=0,f2=0; Boolean Found; LongInt PartSum; Boolean Result; Result=False; if (NewLen==0) return Result; /* herausfinden, ob sich das neue Teil irgendwo mitanhaengen laesst */ Found=False; for (z=0; zRealLen; z++) if (Overlap(NewStart,NewLen,NChunk->Chunks[z].Start,NChunk->Chunks[z].Length)) BEGIN Found=True; f1=z; break; END /* Fall 1: etwas gefunden : */ if (Found) BEGIN /* gefundene Chunk erweitern */ PartSum=NChunk->Chunks[f1].Length+NewLen; SetChunk(NChunk->Chunks+f1,NewStart,NewLen,NChunk->Chunks[f1].Start,NChunk->Chunks[f1].Length); if (Warn) if (PartSum!=NChunk->Chunks[f1].Length) Result=True; /* schauen, ob sukzessiv neue Chunks angebunden werden koennen */ do BEGIN Found=False; for (z=1; zRealLen; z++) if (z!=f1) if (Overlap(NChunk->Chunks[z].Start,NChunk->Chunks[z].Length,NChunk->Chunks[f1].Start,NChunk->Chunks[f1].Length)) BEGIN Found=True; f2=z; break; END if (Found) BEGIN SetChunk(NChunk->Chunks+f1,NChunk->Chunks[f1].Start,NChunk->Chunks[f1].Length,NChunk->Chunks[f2].Start,NChunk->Chunks[f2].Length); NChunk->Chunks[f2]=NChunk->Chunks[--NChunk->RealLen]; END END while (Found); END /* ansonsten Feld erweitern und einschreiben */ else BEGIN IncChunk(NChunk); NChunk->Chunks[NChunk->RealLen].Length=NewLen; NChunk->Chunks[NChunk->RealLen].Start=NewStart; NChunk->RealLen++; END return Result; END /*--------------------------------------------------------------------------*/ /* Ein Stueck wieder austragen */ void DeleteChunk(ChunkList *NChunk, LargeWord DelStart, LargeWord DelLen) BEGIN Word z; LargeWord OStart; if (DelLen==0) return; z=0; while (z<=NChunk->RealLen) BEGIN if (Overlap(DelStart,DelLen,NChunk->Chunks[z].Start,NChunk->Chunks[z].Length)) BEGIN if (NChunk->Chunks[z].Start>=DelStart) if (DelStart+DelLen>=NChunk->Chunks[z].Start+NChunk->Chunks[z].Length) BEGIN /* ganz loeschen */ NChunk->Chunks[z]=NChunk->Chunks[--NChunk->RealLen]; END else BEGIN /* unten abschneiden */ OStart=NChunk->Chunks[z].Start; NChunk->Chunks[z].Start=DelStart+DelLen; NChunk->Chunks[z].Start-=NChunk->Chunks[z].Start-OStart; END else if (DelStart+DelLen>=NChunk->Chunks[z].Start+NChunk->Chunks[z].Length) BEGIN /* oben abschneiden */ NChunk->Chunks[z].Length=DelStart-NChunk->Chunks[z].Start; /* wenn Laenge 0, ganz loeschen */ if (NChunk->Chunks[z].Length==0) BEGIN NChunk->Chunks[z]=NChunk->Chunks[--NChunk->RealLen]; END END else BEGIN /* teilen */ IncChunk(NChunk); NChunk->Chunks[NChunk->RealLen].Start=DelStart+DelLen; NChunk->Chunks[NChunk->RealLen].Length=NChunk->Chunks[z].Start+NChunk->Chunks[z].Length-NChunk->Chunks[NChunk->RealLen].Start; NChunk->Chunks[z].Length=DelStart-NChunk->Chunks[z].Start; END END z++; END END /*--------------------------------------------------------------------------*/ /* Minimaladresse holen */ LargeWord ChunkMin(ChunkList *NChunk) BEGIN LongInt z; LargeWord t=(LargeWord) -1; if (NChunk->RealLen==0) return 0; for (z=0; zRealLen; z++) if (NChunk->Chunks[z].StartChunks[z].Start; return t; END /*--------------------------------------------------------------------------*/ /* Maximaladresse holen */ LargeWord ChunkMax(ChunkList *NChunk) BEGIN LongInt z; LargeWord t=(LargeWord) 0; if (NChunk->RealLen==0) return 0; for (z=0; zRealLen; z++) if (NChunk->Chunks[z].Start+NChunk->Chunks[z].Length-1>t) t=NChunk->Chunks[z].Start+NChunk->Chunks[z].Length-1; return t; END /*--------------------------------------------------------------------------*/ /* Menge holen */ LargeWord ChunkSum(ChunkList *NChunk) BEGIN LongInt z; LargeWord Sum=0; for (z=0; zRealLen; z++) Sum+=NChunk->Chunks[z].Length; return Sum; END void chunks_init(void) BEGIN END