home *** CD-ROM | disk | FTP | other *** search
- /*
- oslist.c
-
- % symbol list functions
-
- OWL 1.2
- Copyright (c) 1988 - 1990, by Oakland Group, Inc.
- ALL RIGHTS RESERVED.
-
- Revision History:
- -----------------
- 11/30/88 jmd Added omalloc
- 12/23/88 jmd Put ofree in oslist close
- 02/04/89 jdc fixed loop in oslist_DelSym()
- 2/08/89 jmd added _arg macro for alpha_find
- 3/03/89 jdc rewrote without class functions
- 4/16/89 jmd replaced iarray with jarray,
- preened return of alpha_find, oslist_DelSym
- 4/28/89 jmd fixed `strncpy' bug
- 8/07/89 jdc preened
- 8/09/89 jdc changed oslist_GetSym to oslist_Get
-
- 11/29/89 jmd added casts for DG
- 12/11/89 jmd renamed this file, preened
- 01/20/89 jdc speeded data retrieval
- 3/28/90 jmd ansi-fied
- 6/18/90 jdc added -1 check for handle in AlphaHandle
- made alpha_find public, now FindAlpha
- 7/31/90 jdc now reuses deleted slots, preened
- 8/07/90 jdc fixed delete bug
- 9/07/90 jmd changed some names around
- 10/22/90 pmcm added NULL data check (for memcpy) in SetSym and SetData
- 12/07/90 pmcm fixed sym-too-large bug in oslist_SetSym
- */
-
- #include "oakhead.h"
-
- /* -------------------------------------------------------------------------- */
- oslist_type oslist_Open(int size, int data_size)
- /*
- create an Oakland Symbol List.
- 'size' is the starting size.
- 'data_size' is the size of the data associated with each symbol.
- */
- {
- oslist_type oslist;
-
- if ((oslist = (oslist_type) omalloc(OA_LIST, sizeof(struct oslist_struct))) == NULL) {
- goto QUIT3;
- }
- if ((oslist->seqnt = xa_Open(size)) == NULL) {
- goto QUIT2;
- }
- if ((oslist->alpha = ia_Open(size)) == NULL) {
- goto QUIT1;
- }
- oslist->size = 0;
- oslist->dsize = data_size;
-
- return(oslist);
-
- QUIT1:
- xa_Close(oslist->seqnt);
- QUIT2:
- ofree(OA_LIST, oslist);
- QUIT3:
- return(NULL);
- }
-
- /* -------------------------------------------------------------------------- */
- int oslist_SetSym(oslist_type oslist, char *symbol, VOID *data)
- /*
- copies 'symbol' and 'data' into the oslist xarray.
- if 'symbol' already is saved then 'data' is recopied.
- an iarray of xarray handles is kept that indexes symbol alphabetically.
-
- deleted symbol xarray handles are kept at the bottom of the alpha iarray.
-
- returns: the xarray handle for 'symbol'.
- */
- {
- VOID *sym;
- int i, index, alpha, len, temp;
-
- if (oslist == NULL || symbol == NULL || *symbol == '\0') {
- return(OSLIST_BADNAME);
- }
-
- if (oslist_FindAlpha(oslist, symbol, &alpha) == FALSE) {
-
- if ((len = strlen(symbol) + 1) > OSLIST_SYMMAXLEN) {
- len = OSLIST_SYMMAXLEN;
- }
- if ((sym = (VOID *)omalloc(OA_LSYM, len + oslist->dsize)) == NULL) {
- goto QUIT3;
- }
-
- strncpy((char *)sym + oslist->dsize, symbol, len); /* symbol */
- if (len >= OSLIST_SYMMAXLEN) {
- *((char *)sym + (OSLIST_SYMMAXLEN - 1) + oslist->dsize) = '\0';
- }
-
- /* check for empty slot in the xarray (from deletion) */
- if ((index = ia_Get(oslist->alpha, oslist->size) - 1) < 0) {
- index = oslist->size;
- }
- if (!xa_Put(oslist->seqnt, index, sym)) {
- goto QUIT2;
- }
-
- /* expand alpha iarray */
- for (i = oslist->size; i > alpha; i--) {
-
- temp = ia_Get(oslist->alpha, i - 1);
- if (!ia_Put(oslist->alpha, i, temp)) {
- goto QUIT1;
- }
- }
- ia_Put(oslist->alpha, alpha, index);
- oslist->size++;
- }
- else {
- index = ia_Get(oslist->alpha, alpha);
- sym = xa_Get(oslist->seqnt, index);
- }
-
- if (oslist->dsize > 0 && data != NULL) {
- memcpy(sym, data, oslist->dsize); /* data */
- }
-
- return(index);
-
- QUIT1:
- xa_Put(oslist->seqnt, index, NULL);
- QUIT2:
- ofree(OA_LSYM, sym);
- QUIT3:
- return(OSLIST_BADNAME);
- }
-
- /* -------------------------------------------------------------------------- */
- boolean oslist_FindAlpha(oslist_type oslist, char *name, int *alpha)
- /*
- returns TRUE if found, FALSE if not.
- *alpha contains proper spot in alpha iarray.
- */
- {
- int cmp, flag;
- int guess, size;
- char *s;
-
- if (oslist->size == 0) {
- *alpha = 0;
- return(FALSE);
- }
-
- size = oslist->size / 2;
- guess = size;
- flag = 0;
-
- while (1) {
-
- s = (char *)xa_Get(oslist->seqnt, ia_Get(oslist->alpha, guess)) + oslist->dsize;
-
- if ((cmp = strcmp(name, s)) == 0) {
- break;
- }
-
- cmp = (cmp < 0) ? -1 : 1;
-
- if (flag == -cmp) { /* repeating */
- if (cmp > 0) { /* name greater than guess */
- guess += 1;
- }
- break;
- }
- if (size <= 1) {
- size = 1;
- flag = cmp;
- }
- else {
- size /= 2;
- }
- guess += cmp * size;
- if (guess < 0) {
- guess = 0;
- break;
- }
- else if (guess >= oslist->size) {
- guess = oslist->size;
- break;
- }
- }
- *alpha = guess;
-
- return(cmp == 0);
- }
-
- /* -------------------------------------------------------------------------- */
- char *oslist_GetSym(oslist_type oslist, int h)
- /*
- */
- {
- VOID *mem;
-
- if (oslist == NULL || h < 0
- || (mem = xa_Get(oslist->seqnt, h)) == NULL) {
-
- return(NULL);
- }
-
- return((char *)mem + oslist->dsize);
- }
-
- /* -------------------------------------------------------------------------- */
- VOID *oslist_GetData(oslist_type oslist, int h)
- {
- if (oslist == NULL || h < 0) {
- return(NULL);
- }
-
- return(xa_Get(oslist->seqnt, h));
- }
-
- /* -------------------------------------------------------------------------- */
- void oslist_SetData(oslist_type oslist, int h, VOID *data)
- {
- VOID *sym;
-
- if (oslist != NULL && data != NULL && h >= 0
- && (sym = xa_Get(oslist->seqnt, h)) != NULL) {
-
- memcpy(sym, data, oslist->dsize);
- }
- }
-
- /* -------------------------------------------------------------------------- */
- int oslist_GetAlphaHandle(oslist_type oslist, int a)
- /*
- */
- {
- if (oslist == NULL || a < 0) {
- return(OSLIST_BADNAME);
- }
-
- return(ia_Get(oslist->alpha, a));
- }
-
- /* -------------------------------------------------------------------------- */
- int oslist_GetSize(oslist_type oslist)
- /*
- */
- {
- return((oslist == NULL) ? OSLIST_BADNAME : oslist->size);
- }
-
- /* -------------------------------------------------------------------------- */
- int oslist_FindHandle(oslist_type oslist, char *symbol)
- /*
- */
- {
- int alpha;
-
- if (oslist == NULL || !oslist_FindAlpha(oslist, symbol, &alpha)) {
- return(OSLIST_BADNAME);
- }
- else {
- return(ia_Get(oslist->alpha, alpha));
- }
- }
-
- /* -------------------------------------------------------------------------- */
- boolean oslist_Delete(oslist_type oslist, int h)
- /*
- deleted symbol xarray handles are kept at the bottom of the alpha iarray.
-
- returns: TRUE if the list still has some symbols, FALSE otherwise.
- */
- {
- VOID *mem;
- int alpha, i, temp;
-
- if (oslist == NULL || h == OSLIST_BADNAME
- || (mem = xa_Get(oslist->seqnt, h)) == NULL) {
-
- return(TRUE);
- }
-
- oslist_FindAlpha(oslist, (char *)mem + oslist->dsize, &alpha);
-
- ofree(OA_LSYM, mem);
- xa_Put(oslist->seqnt, h, NULL);
-
- oslist->size--;
-
- /* close up alpha oslist */
- for (i = alpha; i < oslist->size; i++) {
- temp = ia_Get(oslist->alpha, i + 1);
- ia_Put(oslist->alpha, i, temp);
- }
-
- /* set newly empty slot handle + 1 at end of alpha iarray */
- h++;
- ia_Put(oslist->alpha, oslist->size, h);
-
- return(oslist->size > 0);
- }
-
- /* -------------------------------------------------------------------------- */
- void oslist_Close(oslist_type oslist)
- /*
- deallocate all symbol list memory.
- */
- {
- VOID *mem;
- int i;
-
- if (oslist != NULL) {
- for (i = 0; i < oslist->size; i++) {
- if ((mem = xa_Get(oslist->seqnt, i)) != NULL) {
- ofree(OA_LSYM, mem);
- }
- }
- xa_Close(oslist->seqnt);
- ia_Close(oslist->alpha);
-
- ofree(OA_LIST, (VOID *) oslist);
- }
- }
-