/******************************************************************************************** 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" #include /* * 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; /* printf("NewCrossCallEntry\n"); */ 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) { /* printf("FreeCrossCallEntry\n"); */ rfree (cce); } /* EmptyCrossCallProcedureTable creates an empty table. */ CrossCallProcedureTable EmptyCrossCallProcedureTable (void) { CrossCallProcedureTable ccpt; /* printf("EmptyCrossCallProcedureTable\n"); */ 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) { /* printf("GetCrossCallProcedureTableSize\n"); */ return ccpt->ccpt_size; } /* FreeCrossCallProcedureTable frees a CrossCallProcedureTable. */ void FreeCrossCallProcedureTable (CrossCallProcedureTable ccpt) { /* printf("FreeCrossCallProcedureTable\n"); */ 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) { /* printf("SearchCrossCallEntry\n"); */ 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; /* printf("AddCrossCallEntry\n"); */ 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; /* printf("AddCrossCallEntries\n"); */ 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) { /* printf("FindCrossCallEntry\n"); */ 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; } }