home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / CSAPE32.ARJ / SOURCE / OWLSCR / OSLIST.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-07  |  7.5 KB  |  330 lines

  1. /*
  2.     oslist.c
  3.  
  4.     % symbol list functions
  5.  
  6.     OWL 1.2
  7.     Copyright (c) 1988 - 1990, by Oakland Group, Inc.
  8.     ALL RIGHTS RESERVED.
  9.  
  10.     Revision History:
  11.     -----------------
  12.     11/30/88 jmd    Added omalloc
  13.     12/23/88 jmd    Put ofree in oslist close
  14.     02/04/89 jdc    fixed loop in oslist_DelSym()
  15.      2/08/89 jmd    added _arg macro for alpha_find
  16.      3/03/89 jdc    rewrote without class functions
  17.      4/16/89 jmd    replaced iarray with jarray, 
  18.                     preened return of alpha_find, oslist_DelSym
  19.      4/28/89 jmd    fixed `strncpy' bug
  20.      8/07/89 jdc    preened
  21.      8/09/89 jdc    changed oslist_GetSym to oslist_Get
  22.  
  23.     11/29/89 jmd    added casts for DG
  24.     12/11/89 jmd    renamed this file, preened
  25.     01/20/89 jdc    speeded data retrieval
  26.      3/28/90 jmd    ansi-fied
  27.      6/18/90 jdc    added -1 check for handle in AlphaHandle
  28.                     made alpha_find public, now FindAlpha
  29.      7/31/90 jdc    now reuses deleted slots, preened
  30.      8/07/90 jdc    fixed delete bug
  31.      9/07/90 jmd    changed some names around
  32.     10/22/90 pmcm    added NULL data check (for memcpy) in SetSym and SetData
  33.     12/07/90 pmcm    fixed sym-too-large bug in oslist_SetSym
  34. */
  35.  
  36. #include "oakhead.h"
  37.  
  38. /* -------------------------------------------------------------------------- */
  39. oslist_type oslist_Open(int size, int data_size)
  40. /*
  41.     create an Oakland Symbol List.
  42.     'size' is the starting size.
  43.     'data_size' is the size of the data associated with each symbol.
  44. */
  45. {
  46.     oslist_type oslist;
  47.  
  48.     if ((oslist = (oslist_type) omalloc(OA_LIST, sizeof(struct oslist_struct))) == NULL) {
  49.         goto QUIT3;
  50.     }
  51.     if ((oslist->seqnt = xa_Open(size)) == NULL) {
  52.         goto QUIT2;
  53.     }
  54.     if ((oslist->alpha = ia_Open(size)) == NULL) {
  55.         goto QUIT1;
  56.     }
  57.     oslist->size = 0;
  58.     oslist->dsize = data_size;
  59.  
  60.     return(oslist);
  61.  
  62. QUIT1:
  63.     xa_Close(oslist->seqnt);
  64. QUIT2:
  65.     ofree(OA_LIST, oslist);
  66. QUIT3:
  67.     return(NULL);
  68. }
  69.  
  70. /* -------------------------------------------------------------------------- */
  71. int oslist_SetSym(oslist_type oslist, char *symbol, VOID *data)
  72. /*
  73.     copies 'symbol' and 'data' into the oslist xarray.
  74.     if 'symbol' already is saved then 'data' is recopied.
  75.     an iarray of xarray handles is kept that indexes symbol alphabetically.
  76.  
  77.     deleted symbol xarray handles are kept at the bottom of the alpha iarray.
  78.  
  79.     returns: the xarray handle for 'symbol'.
  80. */
  81. {
  82.     VOID *sym;
  83.     int i, index, alpha, len, temp;
  84.  
  85.     if (oslist == NULL || symbol == NULL || *symbol == '\0') {
  86.         return(OSLIST_BADNAME);
  87.     }
  88.  
  89.     if (oslist_FindAlpha(oslist, symbol, &alpha) == FALSE) {
  90.  
  91.         if ((len = strlen(symbol) + 1) > OSLIST_SYMMAXLEN) {
  92.             len = OSLIST_SYMMAXLEN;
  93.         }
  94.         if ((sym = (VOID *)omalloc(OA_LSYM, len + oslist->dsize)) == NULL) {
  95.             goto QUIT3;
  96.         }
  97.  
  98.         strncpy((char *)sym + oslist->dsize, symbol, len);    /* symbol */
  99.         if (len >= OSLIST_SYMMAXLEN) {
  100.             *((char *)sym + (OSLIST_SYMMAXLEN - 1) + oslist->dsize) = '\0';
  101.         }
  102.  
  103.         /* check for empty slot in the xarray (from deletion) */
  104.         if ((index = ia_Get(oslist->alpha, oslist->size) - 1) < 0) {
  105.             index = oslist->size;
  106.         }
  107.         if (!xa_Put(oslist->seqnt, index, sym)) {
  108.             goto QUIT2;
  109.         }
  110.  
  111.         /* expand alpha iarray */
  112.         for (i = oslist->size; i > alpha; i--) {
  113.  
  114.             temp = ia_Get(oslist->alpha, i - 1);
  115.             if (!ia_Put(oslist->alpha, i, temp)) {
  116.                 goto QUIT1;
  117.             }
  118.         }
  119.         ia_Put(oslist->alpha, alpha, index);
  120.         oslist->size++;
  121.     }
  122.     else {
  123.         index = ia_Get(oslist->alpha, alpha);
  124.         sym = xa_Get(oslist->seqnt, index);
  125.     }
  126.  
  127.     if (oslist->dsize > 0 && data != NULL) {
  128.         memcpy(sym, data, oslist->dsize);            /* data */
  129.     }
  130.  
  131.     return(index);
  132.  
  133. QUIT1:
  134.     xa_Put(oslist->seqnt, index, NULL);
  135. QUIT2:
  136.     ofree(OA_LSYM, sym);
  137. QUIT3:
  138.     return(OSLIST_BADNAME);
  139. }
  140.  
  141. /* -------------------------------------------------------------------------- */
  142. boolean oslist_FindAlpha(oslist_type oslist, char *name, int *alpha)
  143. /*
  144.     returns TRUE if found, FALSE if not.
  145.     *alpha contains proper spot in alpha iarray.
  146. */
  147. {
  148.     int cmp, flag;
  149.     int guess, size;
  150.     char *s;
  151.  
  152.     if (oslist->size == 0) {
  153.         *alpha = 0;
  154.         return(FALSE);
  155.     }
  156.  
  157.     size = oslist->size / 2;
  158.     guess = size;
  159.     flag = 0;
  160.  
  161.      while (1) {
  162.  
  163.         s = (char *)xa_Get(oslist->seqnt, ia_Get(oslist->alpha, guess)) + oslist->dsize;
  164.  
  165.         if ((cmp = strcmp(name, s)) == 0) {
  166.             break;
  167.         }
  168.  
  169.         cmp = (cmp < 0) ? -1 : 1;
  170.  
  171.         if (flag == -cmp) {    /* repeating */
  172.             if (cmp > 0) {    /* name greater than guess */
  173.                 guess += 1;
  174.             }
  175.             break;
  176.         }
  177.         if (size <= 1) {
  178.             size = 1;
  179.             flag = cmp;
  180.         }
  181.         else {
  182.             size /= 2;
  183.         }
  184.         guess += cmp * size;
  185.         if (guess < 0) {
  186.             guess = 0;
  187.             break;
  188.         }
  189.         else if (guess >= oslist->size) {
  190.             guess = oslist->size;
  191.             break;
  192.         }
  193.     }                        
  194.     *alpha = guess;
  195.  
  196.     return(cmp == 0);
  197. }        
  198.  
  199. /* -------------------------------------------------------------------------- */
  200. char *oslist_GetSym(oslist_type oslist, int h)
  201. /*
  202. */
  203. {
  204.     VOID *mem;
  205.  
  206.     if (oslist == NULL || h < 0 
  207.     || (mem = xa_Get(oslist->seqnt, h)) == NULL) {
  208.  
  209.         return(NULL);
  210.     }
  211.  
  212.     return((char *)mem + oslist->dsize);
  213. }
  214.  
  215. /* -------------------------------------------------------------------------- */
  216. VOID *oslist_GetData(oslist_type oslist, int h)
  217. {    
  218.     if (oslist == NULL || h < 0) {
  219.         return(NULL);
  220.     }
  221.  
  222.     return(xa_Get(oslist->seqnt, h));
  223. }
  224.  
  225. /* -------------------------------------------------------------------------- */
  226. void oslist_SetData(oslist_type oslist, int h, VOID *data)
  227. {
  228.     VOID *sym;
  229.     
  230.     if (oslist != NULL && data != NULL && h >= 0 
  231.     && (sym = xa_Get(oslist->seqnt, h)) != NULL) {
  232.  
  233.         memcpy(sym, data, oslist->dsize);
  234.     }
  235. }
  236.  
  237. /* -------------------------------------------------------------------------- */
  238. int oslist_GetAlphaHandle(oslist_type oslist, int a)
  239. /*
  240. */
  241. {
  242.     if (oslist == NULL || a < 0) {
  243.         return(OSLIST_BADNAME);
  244.     }
  245.  
  246.     return(ia_Get(oslist->alpha, a));
  247. }
  248.  
  249. /* -------------------------------------------------------------------------- */
  250. int oslist_GetSize(oslist_type oslist)
  251. /*
  252. */
  253. {
  254.     return((oslist == NULL) ? OSLIST_BADNAME : oslist->size);
  255. }
  256.  
  257. /* -------------------------------------------------------------------------- */
  258. int oslist_FindHandle(oslist_type oslist, char *symbol)
  259. /*
  260. */
  261. {
  262.     int alpha;
  263.  
  264.     if (oslist == NULL || !oslist_FindAlpha(oslist, symbol, &alpha)) {
  265.         return(OSLIST_BADNAME);
  266.     }
  267.     else {
  268.         return(ia_Get(oslist->alpha, alpha));
  269.     }
  270. }
  271.  
  272. /* -------------------------------------------------------------------------- */
  273. boolean oslist_Delete(oslist_type oslist, int h)
  274. /*
  275.     deleted symbol xarray handles are kept at the bottom of the alpha iarray.
  276.  
  277.     returns: TRUE if the list still has some symbols, FALSE otherwise.
  278. */
  279. {
  280.     VOID *mem;
  281.     int alpha, i, temp;
  282.  
  283.     if (oslist == NULL || h == OSLIST_BADNAME
  284.     || (mem = xa_Get(oslist->seqnt, h)) == NULL) {
  285.  
  286.         return(TRUE);
  287.     }
  288.  
  289.     oslist_FindAlpha(oslist, (char *)mem + oslist->dsize, &alpha);
  290.  
  291.     ofree(OA_LSYM, mem);
  292.     xa_Put(oslist->seqnt, h, NULL);
  293.  
  294.     oslist->size--;
  295.  
  296.     /* close up alpha oslist */
  297.     for (i = alpha; i < oslist->size; i++) {
  298.         temp = ia_Get(oslist->alpha, i + 1);
  299.         ia_Put(oslist->alpha, i, temp);
  300.     }
  301.  
  302.     /* set newly empty slot handle + 1 at end of alpha iarray */
  303.     h++;
  304.     ia_Put(oslist->alpha, oslist->size, h);
  305.  
  306.     return(oslist->size > 0);
  307. }
  308.  
  309. /* -------------------------------------------------------------------------- */
  310. void oslist_Close(oslist_type oslist)
  311. /*
  312.     deallocate all symbol list memory.
  313. */
  314. {
  315.     VOID *mem;
  316.     int i;
  317.     
  318.     if (oslist != NULL) {
  319.         for (i = 0; i < oslist->size; i++) {
  320.             if ((mem = xa_Get(oslist->seqnt, i)) != NULL) {
  321.                 ofree(OA_LSYM, mem);
  322.             }
  323.         }
  324.         xa_Close(oslist->seqnt);
  325.         ia_Close(oslist->alpha);
  326.      
  327.         ofree(OA_LIST, (VOID *) oslist);
  328.     }
  329. }
  330.