dect
/
asl
Archived
13
0
Fork 0
This repository has been archived on 2022-02-17. You can view files and clone it, but cannot push or open issues or pull requests.
asl/chunks.c

229 lines
6.5 KiB
C

/* 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; z<NChunk->RealLen; 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; z<NChunk->RealLen; 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; z<NChunk->RealLen; z++)
if (NChunk->Chunks[z].Start<t) t=NChunk->Chunks[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; z<NChunk->RealLen; 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; z<NChunk->RealLen; z++)
Sum+=NChunk->Chunks[z].Length;
return Sum;
END
void chunks_init(void)
BEGIN
END