/*******************************************************************************
* YORKTOWN ADVANCED SGML PARSER (YASP)                                         *
*         An SGML Parser conforming to International Standard ISO 8879 --      *
*         Standard Generalized Markup Language                                 *
*------------------------------------------------------------------------------*
* Written 1987 - 1993 by                                                       *
*         Pierre G. Richard                                                    *
*         IBM T.J. Watson Research Center                                      *
*         Yorktown Heights, New York                                           *
*         petrus@watson.ibm.com                                                *
*------------------------------------------------------------------------------*
* FUNCTION NAME    = YASP / CSD compiler                                       *
* STATUS           = Version 0, Release 1, Level 33 and up                     *
* COMPONENT NAME   = ocsqnty.c                                                 *
* DESCRIPTIVE NAME = SGML declaration syntax/quantity parameter                *
* DATE_WR          = 02/14/1989                                                *
* AUTHOR           = Pierre G. Richard - PETRUS at YKTVMX                      *
*                                                                              *
* FUNCTIONAL DESCRIPTION =                                                     *
*                                                                              *
* Set up the quantity values.                                                  *
*                                                                              *
* IMPLEMENTATION NOTE =                                                        *
*                                                                              *
* DEPENDENCIES =  (see Include list)                                           *
*                                                                              *
* IMPORT=                                                                      *
*                                                                              *
* EXPORT=                                                                      *
*                                                                              *
* CHANGE HISTORY =                                                             *
* Number Date     Inits    Change & Reason (brief)                             *
*      1 11/12/91 PETRUS   Make GRPGTCNT customizable                          *
*******************************************************************************/

/*-------------+
|Include Files |
+-------------*/
#include "machine.h"
#include "portable.h"
#include "yaspapi.h"
#include "global.h"
#include "usrlib.h"
#include "sgml.h"
#include "ocs.h"

/*---------------------------------------------------------------------qty_bld-+
| Fill a QUANTITY Table -- copy default values from the current QNTYTAB        |
| QUANTITY has already been decoded by name_bld (OCSNAME)                      |
|                                                                              |
| [194] quantity set = "QUANTITY", ps+, "SGMLREF", (ps+, name, ps+, number)*   |
|                                                                              |
+-----------------------------------------------------------------------------*/
void P_FCT qty_bld(GA_P gbla_p, QNTY *new_qntytab)
{
   ulong value;
   uint i, min, max;
   uchar  const **c_pp;
   int     ix, cond, num, low;
   uchar   name_p[NAMELEN_MAX+1];
   QNTY *qnty_p, *qnty_pS;


   /*--------------------+
   |Check where we are.. |
   +--------------------*/
   skip_Wps(gbla_p);
   chk_gnam(gbla_p,GA(alwdtab_p)->SGMLREF.s.p);

   /*----------------------------------+
   |Enter the variant quantity values  |
   |Binary Search of the quantity name |
   +----------------------------------*/
   memset((void *)new_qntytab,0,sizeof(QNTYTAB));
   qnty_pS = GA(qntytab);
   c_pp = GA(qnty_names);
   for (;;) {
      skip_Wps(gbla_p);
      if ((GA(curr_token) != NOT_FOUND_TK)||(GA(curr_char) == Ee)) break;
      get_name(gbla_p,name_p);      /* get quantity name */
      num = sizeof(QNTYTAB)/sizeof(QNTY) - 1;
      low = 0;                      /* low bound */
      while (low <= num) {
         cond = strcmp(name_p, *(c_pp + (ix=((uint)low+(uint)num)/2)));
         if (cond < 0) {
            num = ix - 1;           /* set low range */
         }else if (cond > 0) {
            low = ix + 1;
         }else {                    /* found */
            break;
         }
      }
      if (cond) {                                /* not found */
         em_unrd(gbla_p,strlen(name_p));         /* unread FEATURES */
         break;
      }
      /*----------------------+
      |limit each capacity to |
      |a specific min/max     |
      +----------------------*/
      min = 1;
      switch (ix) {
      case ATTSPLEN_ix:
         max = ATTSPLEN_MAX;
         break;
      case ATTCNT_ix:
         max = ATTCNT_MAX;
         break;
      case LITLEN_ix:     /* Warning: see BUFSIZE in GLOBAL.H */
         min = NAMELEN_MAX;
         max = LITLEN_MAX;
         break;
      case NAMELEN_ix:
         max = NAMELEN_MAX;
         break;
      case NORMSEP_ix:
         max = NORMSEP_MAX;
         break;
      case PILEN_ix:
         max = PILEN_MAX;
         break;
      case TAGLEN_ix:
         max = TAGLEN_MAX;
         break;
      case GRPCNT_ix:
         max = GRPCNT_MAX;
         break;
      case ENTLVL_ix:
         max = ENTLVL_MAX;
         break;
      case GRPGTCNT_ix:
         max = GRPGTCNT_MAX;
         break;
      case TAGLVL_ix:
         max = TAGLVL_MAX;
         break;
#ifdef RESERVED_FOR_FUTUR_USE
      case BSEQLEN_ix:    /* Warning: see BUFSIZE in GLOBAL.H */
      case DTAGLEN_ix:    /* Warning: see ODBF in global.h */
      case DTEMPLEN_ix:
      case GRPLVL_ix:
#endif
      default:
         min = max = (qnty_pS + ix)->value;
         break;
      }
      qnty_p = new_qntytab + ix;
      skip_Wps(gbla_p);
      value = get_num(gbla_p);
      if (qnty_p->value) {
         errorh(gbla_p,DUPDEF,ERH_W_SEV+ERH_LOCATE,name_p);
      }else if ((value < min) || (value > max)) {
         errorh(gbla_p,INVQNTY,ERH_W_SEV+ERH_LOCATE);
      }else {
         qnty_p->value = (uint)value;
      }
   }
   /*------------------------------+
   |Default the unspecified values |
   |to the Ref Concrete Syntax ones|
   +------------------------------*/
   qnty_p  = new_qntytab;
   for (i=sizeof(QNTYTAB)/sizeof(QNTY); i--; ++qnty_p, ++qnty_pS) {
      if (!qnty_p->value) qnty_p->value = qnty_pS->value;
   }
}
/******************************************************************************/
