File: cCrossCallProcedureTable_121.c

package info (click to toggle)
ghc-cvs 20040725-2
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 68,484 kB
  • ctags: 19,658
  • sloc: haskell: 251,945; ansic: 109,709; asm: 24,961; sh: 12,825; perl: 5,786; makefile: 5,334; xml: 3,884; python: 682; yacc: 650; lisp: 477; cpp: 337; ml: 76; fortran: 24; csh: 18
file content (159 lines) | stat: -rw-r--r-- 5,276 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/********************************************************************************************
	Clean OS Windows library module version 1.2.1.
	This module is part of the Clean Object I/O library, version 1.2.1,
	for the Windows platform.
********************************************************************************************/

/********************************************************************************************
	About this module:
	Implementation of cross call procedure table.
	In this table a linked list of cross call entries is kept.
	A cross call entry is a pair of a cross call code (CcRq...) number (see intrface_121.h)
	and a pointer to a cross call procedure.
	Routines related to printer handling.
********************************************************************************************/
#include "cCrossCallProcedureTable_121.h"

//	A CrossCallEntry contains a CcRq number and a pointer to a CrossCallProcedure.
struct _crosscallentry
{	int					cce_code;		// CcRq... number
	CrossCallProcedure	cce_proc;		// The procedure to be called in case of cce_code
	CrossCallEntry		cce_next;		// The next entry in the list
};
//	A CrossCallProcedureTable contains a linked list of CrossCallEntries.
struct _crosscallproceduretable
{	int                 ccpt_size;		// nr of entries
	CrossCallEntry		ccpt_first;		// first entry
	CrossCallEntry		ccpt_last;		// last entry
};


//	NewCrossCallEntry creates a CrossCallEntry with cce_next field NULL.
CrossCallEntry NewCrossCallEntry (int cce_code, CrossCallProcedure cce_proc)
{
	CrossCallEntry cce = rmalloc (sizeof (struct _crosscallentry));

	cce->cce_code = cce_code;
	cce->cce_proc = cce_proc;
	cce->cce_next = NULL;

	return cce;
}

//	FreeCrossCallEntry frees a CrossCallEntry.
void FreeCrossCallEntry (CrossCallEntry cce)
{
	rfree (cce);
}

//	EmptyCrossCallProcedureTable creates an empty table.
CrossCallProcedureTable EmptyCrossCallProcedureTable (void)
{
	CrossCallProcedureTable ccpt = rmalloc (sizeof (struct _crosscallproceduretable));

	ccpt->ccpt_size  = 0;
	ccpt->ccpt_first = NULL;
	ccpt->ccpt_last  = NULL;

	return ccpt;
}

//	GetCrossCallProcedureTableSize returns the current number of installed cross call procedures.
int GetCrossCallProcedureTableSize (CrossCallProcedureTable ccpt)
{
	return ccpt->ccpt_size;
}

//	FreeCrossCallProcedureTable frees a CrossCallProcedureTable.
void FreeCrossCallProcedureTable (CrossCallProcedureTable ccpt)
{
	rfree (ccpt);
}

/*	SearchCrossCallEntry (nr,entry) returns the first CrossCallEntry
	following/including entry that either:
		matches nr, or
		is the entry after which a new entry with nr should be added, or
		NULL in case nr should be placed before entry.
*/
static CrossCallEntry SearchCrossCallEntry (int nr,CrossCallEntry entry)
{
	if (nr == entry->cce_code)
		return entry;				// entry found
	if (nr < entry->cce_code)
		return NULL;				// no entry found
	if (entry->cce_next == NULL)
		return entry;				// last entry; should insert new entry after this one
	if (nr < entry->cce_next->cce_code)
		return entry;				// next entry exceeds nr; should insert new entry after this one
	return SearchCrossCallEntry (nr,entry->cce_next);
}

//	AddCrossCallEntry (table,nr,proc) adds a new entry (nr,proc) if an entry with nr is not already present.
void AddCrossCallEntry (CrossCallProcedureTable ccpt, int cce_code, CrossCallProcedure cce_proc)
{
	CrossCallEntry entry = NewCrossCallEntry (cce_code,cce_proc);

	if (ccpt->ccpt_size == 0)
	{	// table is empty; create entry and add it
		ccpt->ccpt_size  = 1;
		ccpt->ccpt_first = entry;
		ccpt->ccpt_last  = entry;
	}
	else if (cce_code < ccpt->ccpt_first->cce_code)
	{	// entry should be inserted before first entry
		ccpt->ccpt_size += 1;
		entry->cce_next = ccpt->ccpt_first;
		ccpt->ccpt_first= entry;
	}
	else if (cce_code > ccpt->ccpt_first->cce_code)
	{	// entry could be in table; look for it and add it if not present
		CrossCallEntry searchCCE;
		searchCCE = SearchCrossCallEntry (cce_code,ccpt->ccpt_first);

		if (searchCCE == NULL)
		{
			printf("\'AddCrossCallEntry\' SearchCrossCallEntry returned NULL CrossCallEntry");
			exit(1);
		}
		if (searchCCE->cce_code != cce_code)
		{	// entry not in table but should be linked after searchCCE
			gboolean appendLast = (ccpt->ccpt_last == searchCCE);
			ccpt->ccpt_size     += 1;
			entry->cce_next     = searchCCE->cce_next;
			searchCCE->cce_next = entry;

			if (appendLast)
				ccpt->ccpt_last  = entry;	// adjust last if entry is appended at end
		}
	}
}

//	AddCrossCallEntries (table,entries) adds the entries to table
void AddCrossCallEntries (CrossCallProcedureTable theTable, CrossCallProcedureTable entries)
{
	CrossCallEntry cce = entries->ccpt_first;

	while (cce != NULL)
	{
		AddCrossCallEntry (theTable, cce->cce_code, cce->cce_proc);
		cce = cce->cce_next;
	}
}

//	FindCrossCallEntry returns the found CrossCallProcedure or NULL if not found.
CrossCallProcedure FindCrossCallEntry (CrossCallProcedureTable ccpt, int cce_code)
{
	if (ccpt->ccpt_size == 0)	// table is empty, return NULL
		return NULL;
	else
	{
		CrossCallEntry searchCCE;
		searchCCE = SearchCrossCallEntry (cce_code,ccpt->ccpt_first);
		if (searchCCE && searchCCE->cce_code == cce_code)
			return searchCCE->cce_proc;
		else
			return NULL;
	}
}