
/*
 * Hand-coded routines for BibTeX in C.
 *
 * A runtime memory configuration is provided for all internal array sizes.
 * This file is included in `bibtex.c' automatically.
 *
 * This code was written by Andreas Scherer, March 31, 1995.
 */

#ifndef _BIBTEX_MEMORY_H
#define _BIBTEX_MEMORY_H /* Don't include this file more than once. */

#ifdef VARMEM /* Complete file */

#ifdef _AMIGA
const unsigned char Version[] = "$VER: BibTeX 0.99c ("__DATE__", "__TIME__")\n";
#endif /* _AMIGA */

#define configname "bibtex.mcf"
#define CONFIGPATH BIBTEXCONFIGPATH

typedef struct {
   char * pname;
   long pval;
   } as_parameter;

enum {
   AS_BUFSIZE,     AS_MINPRINTLINE,  AS_MAXPRINTLINE, AS_AUXSTACKSIZE,
   AS_MAXBIBFILES, AS_POOLSIZE,      AS_MAXSTRINGS,   AS_MAXCITES,
   AS_WIZFNSPACE,  AS_SINGLEFNSPACE, AS_MAXENTINTS,   AS_MAXENTSTRS,
   AS_ENTSTRSIZE,  AS_GLOBSTRSIZE,   AS_MAXFIELDS,    AS_LITSTKSIZE,
   AS_HASHSIZE,    AS_HASHPRIME,     AS_NP
   };

as_parameter as_param[AS_NP] = {
   { "bufsize", 1000 },
   { "minprintline", 3 },
   { "maxprintline", 79 },
   { "auxstacksize", 20 },
   { "maxbibfiles", 20 },
   { "poolsize", 65000 },
   { "maxstrings", 4000 },
   { "maxcites", 750 },
   { "wizfnspace", 3000 },
   { "singlefnspace", 100 },
   { "maxentints", 3000 },
   { "maxentstrs", 3000 },
   { "entstrsize", 100 },
   { "globstrsize", 1000 },
   { "maxfields", 17250 },
   { "litstksize", 100 },
   { "hashsize", 5000 },
   { "hashprime", 4253 }
   };

void as_memerr(void)
{
  fprintf(stderr,"Insufficient memory for BibTeX - alter " configname "\n");
  uexit(error_message_issued);
}

#define Alloc_Object(object,size,type) \
  if (!(object=(type *)malloc((size)*sizeof(type)))) \
    as_memerr()

#define Free_Object(A) if(A) free(A), A=NULL

void as_getsizes(void)
{
  FILE *configfile;
  char cmd[256],parm[256];
  long val,index;

  Alloc_Object ( nameoffile, PATHMAX + 1, char ) ;

  vstrcpy ( nameoffile + 1 , configname ) ;
  nameoffile [ 0 ] = ' ' ;
  nameoffile [ strlen ( configname ) + 1 ] = ' ' ;
  namelength = strlen ( configname ) ;
  if ( aopenin ( configfile , CONFIGPATH ) )
  {
    while ( fgets(cmd, (size_t) 255, configfile) )
    {
      if ( strncmp(cmd, "set ", 4) == 0 )
      {
        if ( sscanf(cmd+4,"%s%d",parm,&val) == 2)
        {
	  index = 0;
	  while ( index < AS_NP && strcmp(parm,as_param[index].pname) ) index++;
          if ( index >= AS_NP ) 
	  {
	    fprintf(stderr,"Warning: unknown config option \"%s\" ignored\n",
              parm);
	  }
	  else
	  {
	    as_param[index].pval=val;
	  }
        }
      }
    }
  aclose (configfile);
  }

  Free_Object ( nameoffile ) ;

#ifdef DEBUG  
  for (index = 0 ; index < AS_NP ; index++ )
    fprintf(stderr, "%d\n", as_param[index].pval); 
#endif
}

void as_alloc_memory(void)
{
   register long i;

   Alloc_Object(xord, 256, ASCIIcode);
   Alloc_Object(xchr, 256, ASCIIcode);
   Alloc_Object(lexclass, 256, lextype);
   Alloc_Object(idclass, 256, idtype);
   Alloc_Object(charwidth, 256, integer);
   Alloc_Object(nameoffile, PATHMAX + 1, char);
   Alloc_Object(strpool, poolsize + 1, ASCIIcode);
   Alloc_Object(strstart, maxstrings + 1, poolpointer);
   Alloc_Object(hashnext, hashsize + 1, hashpointer); /* See bibtexmemory.ch */
   Alloc_Object(hashtext, hashsize + 1, strnumber); /* See bibtexmemory.ch */
   Alloc_Object(hashilk, hashsize + 1, strilk); /* See bibtexmemory.ch */
   Alloc_Object(ilkinfo, hashsize + 1, integer); /* See bibtexmemory.ch */
   Alloc_Object(auxfile, auxstacksize + 1, alphafile);
   Alloc_Object(auxlist, auxstacksize + 1, strnumber);
   Alloc_Object(auxlnstack, auxstacksize + 1, integer);
   Alloc_Object(biblist, maxbibfiles + 1, strnumber);
   Alloc_Object(bibfile, maxbibfiles + 1, alphafile);
   Alloc_Object(citelist, maxcites + 1, strnumber);
   Alloc_Object(fntype, hashsize + 1, fnclass); /* See bibtexmemory.ch */
   Alloc_Object(wizfunctions, wizfnspace + 1, hashptr2);
   Alloc_Object(entryints, maxentints + 1, integer);
   Alloc_Object(entrystrs, maxentstrs + 1, ASCIIcode *);
   for ( i=0; i<maxentstrs+1; i++ )
      Alloc_Object(entrystrs[i], entstrsize + 1, ASCIIcode);
   Alloc_Object(glbstrptr, 10, strnumber);
   Alloc_Object(globalstrs, 10, ASCIIcode *);
   for ( i=0; i<10; i++ )
      Alloc_Object(globalstrs[i], globstrsize + 1, ASCIIcode);
   Alloc_Object(glbstrend, 10, integer);
   Alloc_Object(fieldinfo, maxfields + 1, strnumber);
   Alloc_Object(typelist, maxcites + 1, hashptr2);
   Alloc_Object(entryexists, maxcites + 1, boolean);
   Alloc_Object(citeinfo, maxcites + 1, strnumber);
   Alloc_Object(litstack, litstksize + 1, integer);
   Alloc_Object(litstktype, litstksize + 1, stktype);
#ifdef STAT
   Alloc_Object(bltinloc, numbltinfns + 1, hashloc);
   Alloc_Object(executioncount, numbltinfns + 1, integer);
#endif /* STAT */
   Alloc_Object(spreamble, maxbibfiles + 1, strnumber);
   Alloc_Object(nametok, bufsize + 1, bufpointer);
   Alloc_Object(namesepchar, bufsize + 1, ASCIIcode);
/*
 * Don't forget the `hidden' array types.
 */
   Alloc_Object(buffer, bufsize + 1, ASCIIcode);
   Alloc_Object(svbuffer, bufsize + 1, ASCIIcode);
   Alloc_Object(exbuf, bufsize + 1, ASCIIcode);
   Alloc_Object(outbuf, bufsize + 1, ASCIIcode);
}

void as_free_memory(void)
{
   register long i;

   Free_Object(outbuf);
   Free_Object(exbuf);
   Free_Object(svbuffer);
   Free_Object(buffer);

   Free_Object(namesepchar);
   Free_Object(nametok);
   Free_Object(spreamble);
#ifdef STAT
   Free_Object(executioncount);
   Free_Object(bltinloc);
#endif /* STAT */
   Free_Object(litstktype);
   Free_Object(litstack);
   Free_Object(citeinfo);
   Free_Object(entryexists);
   Free_Object(typelist);
   Free_Object(fieldinfo);
   Free_Object(glbstrend);
   for ( i=0; i<10; i++ )
      Free_Object(globalstrs[i]);
   Free_Object(globalstrs);
   Free_Object(glbstrptr);
   for ( i=0; i<maxentstrs+1; i++ )
      Free_Object(entrystrs[i]);
   Free_Object(entrystrs);
   Free_Object(entryints);
   Free_Object(wizfunctions);
   Free_Object(fntype);
   Free_Object(citelist);
   Free_Object(bibfile);
   Free_Object(biblist);
   Free_Object(auxlnstack);
   Free_Object(auxlist);
   Free_Object(auxfile);
   Free_Object(ilkinfo);
   Free_Object(hashilk);
   Free_Object(hashtext);
   Free_Object(hashnext);
   Free_Object(strstart);
   Free_Object(strpool);
   Free_Object(nameoffile);
   Free_Object(charwidth);
   Free_Object(idclass);
   Free_Object(lexclass);
   Free_Object(xchr);
   Free_Object(xord);
}

void mem_initialize(void)
   {
   setpaths ( BIBINPUTPATHBIT + BSTINPUTPATHBIT + BIBTEXCONFIGPATHBIT ) ; 

   as_getsizes();
   as_alloc_memory();

   if(atexit(&as_free_memory)) { /* Can't happen. */
      fprintf(stderr, "Exit trap failure! (as_free_memory)\n");
      uexit(error_message_issued);
      }

   initialize(); /* We have to do this somewhere */
   }

#endif /* VARMEM */

#endif /* _BIBTEX_MEMORY_H */
