From 333b605b2afd472b823aeda0adf0e8b1ea9843c0 Mon Sep 17 00:00:00 2001 From: fishsoupisgood Date: Mon, 27 May 2019 02:41:51 +0100 Subject: initial commit from asl-1.41r8.tar.gz --- chunks.c | 228 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 chunks.c (limited to 'chunks.c') diff --git a/chunks.c b/chunks.c new file mode 100644 index 0000000..e92a9dc --- /dev/null +++ b/chunks.c @@ -0,0 +1,228 @@ +/* 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 -- cgit v1.2.3