/* intlist.c - Linked list of integers. */ /* * * Although this file was originally written to be used in Modoc, * it is written to have a general interface so that it could be used * in other applications. * * Author & Maintainer: Fumiaki Okushi (okushi@cs.csubak.edu) * SIMPLIFIED --AVG */ #ifndef lint static char vcid[] = "$Id: $"; #endif /* lint */ /* To maintain independence of this package, this file should NOT * include any user-defined header files other than the accompanying * header file. This implies that this module should not access any * global variables in other files. */ #ifdef linux /* ASSUME OBSOLTE --AVG #include "linuxassertfix.h" */ #include "assert.h" #else /* !linux */ #include #endif /* !linux */ #include #include #include #if 0 #include #endif #include "intlist.h" /*****************************************************************************/ /* Functions for ``sticky'' nodes (SNodes). */ /* SBLOCK_NODES should be chosen so that sizeof(struct sblock) is some multiple of page size. */ #ifndef SBLOCK_NODES #define SBLOCK_NODES 8192 #endif /* !SBLOCK_NODES */ struct sblock { struct IL_node nodes[SBLOCK_NODES]; }; static intlist free_snodes = IL_EMPTYLIST; /* Linked list of free nodes. */ /* ok */ static void free_snode(intlist node) { IL_REST(node) = free_snodes; free_snodes = node; } /* ok */ int IL_first(const intlist list) { return IL_FIRST(list); } /* ok */ intlist IL_rest(const intlist list) { return IL_REST(list); } /* ok */ intlist IL_emptylist(void) { return IL_EMPTYLIST; } /* ok */ intlist IL_cons(int newData, const intlist list) { register intlist node; if (IL_ISEMPTY(free_snodes)) { struct sblock* new_sblock = (struct sblock*)malloc(sizeof(struct sblock)); register int i; register intlist p, q; if (!new_sblock) { perror("(intlist)"); exit(1); } free_snodes = &new_sblock->nodes[0]; for (p = free_snodes, q = p+1, i = 0; i < SBLOCK_NODES-1; i++, p = q, q++) p->next = q; p->next = 0; } node = free_snodes; free_snodes = IL_REST(free_snodes); IL_FIRST(node) = newData; IL_REST(node) = list; return node; } /* ok */ void IL_free(intlist list) { register intlist p; if (IL_ISEMPTY(list)) return; p = list; while (!IL_ISEMPTY(IL_REST(p))) p = IL_REST(p); IL_REST(p) = free_snodes; free_snodes = list; } /****************************************************************************/ /* The following functions provide some utilities. */ /* ok */ int IL_member(int number, const intlist list) { register intlist p; for (p = list; !IL_ISEMPTY(p); p = IL_REST(p)) if (IL_FIRST(p) == number) return 1; return 0; } /* ok */ int IL_max(const intlist list) { register intlist p; register int max_so_far = INT_MIN; for (p = list; !IL_ISEMPTY(p); p = IL_REST(p)) { const int data = IL_FIRST(p); if (data > max_so_far) max_so_far = data; } return max_so_far; } /* ok */ void IL_print(const intlist list) { register intlist p; for (p = list; !IL_ISEMPTY(p); p = IL_REST(p)) { printf("%d ", IL_FIRST(p)); } printf("\n"); } /* ok */ int IL_length(const intlist list) { register intlist p; register int len = 0; for (p = list; !IL_ISEMPTY(p); p = IL_REST(p)) len++; return len; } /* ok */ intlist IL_nthcdr(int n, const intlist list) { register intlist result = list; register int i; for (i = 0; i < n; i++) { if (IL_ISEMPTY(result)) break; else result = IL_REST(result); } return result; } int IL_test_range(const intlist L, int lb, int ub, int *error) { register intlist rem; for (rem = L; !IL_ISEMPTY(rem); rem = IL_REST(rem)) { const int n = IL_FIRST(rem); if ((n < lb) || (n > ub)) { if (error) *error = n; return 0; } } return 1; } /**********************************************************************/ /* eof */