/* National Institute of Standards and Technology (NIST)
/* National Computer System Laboratory (NCSL)
/* Office Systems Engineering (OSE) Group
/* ********************************************************************
/*                            D I S C L A I M E R
/*                              (March 8, 1989)
/*  
/* There is no warranty for the NIST NCSL OSE SGML parser and/or the NIST
/* NCSL OSE SGML parser validation suite.  If the SGML parser and/or
/* validation suite is modified by someone else and passed on, NIST wants
/* the parser's recipients to know that what they have is not what NIST
/* distributed, so that any problems introduced by others will not
/* reflect on our reputation.
/* 
/* Policies
/* 
/* 1. Anyone may copy and distribute verbatim copies of the SGML source
/* code as received in any medium.
/* 
/* 2. Anyone may modify your copy or copies of SGML parser source code or
/* any portion of it, and copy and distribute such modifications provided
/* that all modifications are clearly associated with the entity that
/* performs the modifications.
/* 
/* NO WARRANTY
/* ===========
/* 
/* NIST PROVIDES ABSOLUTELY NO WARRANTY.  THE SGML PARSER AND VALIDATION
/* SUITE ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
/* EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
/* THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS
/* WITH YOU.  SHOULD THE SGML PARSER OR VALIDATION SUITE PROVE DEFECTIVE,
/* YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
/* 
/* IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL NIST BE LIABLE FOR
/* DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL,
/* INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
/* INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
/* BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A
/* FAILURE OF THE PROGRAM TO OPERATE WITH PROGRAMS NOT DISTRIBUTED BY
/* NIST) THE PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF
/* SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
*/

/************************************************************************/
/*   TITLE:          SGML PARSER                                        */
/*   SYSTEM:         DTD PROCESSOR                                      */
/*   SUBSYSTEM:                                                         */
/*   SOURCE FILE:    DTDNOTAT.C                                         */
/*   AUTHOR:         Jim Heath                                          */
/*                                                                      */
/*   DATE CREATED:                                                      */
/*   LAST MODIFIED:                                                     */
/*                                                                      */
/*                  REVISIONS                                           */
/*   WHEN      WHO            WHY                                       */
/************************************************************************/
#include <stdio.h>
#include <setjmp.h>
#include <memory.h>
#include "qntyset.h"
#include "dtd.h"
#include "dtdfncs.h"
#include "dtdglbl.h"
#include "dtddefs.h"
#define MAXNOTAT 10
static char notatenames [MAXNOTAT][NAMELEN + 1];
static int count = 0;
/* ============================================================ */
int donotation()
{
   int j;
   char *nptr;
   if ((j = INPPS()) == EOF)
      terminate(1, "EOF found in ATTLIST declaration");
   if (j < 1)
      syntxerr("Expected PS+ at this point");
   ADDCHAR(SPACE);
   if (count >= MAXNOTAT)
      terminate(1, "internal overflow of notation names");
   nptr = notatenames[count];
   if((j = INPNAME(&nptr, NAMELEN, TOUPPER)) == EOF)
      terminate(1, "EOF found in NOTATION declaration");
   ADDSTRING(notatenames[count++]);
   for (j = 0; j < (count - 1); j++)  {
      if (count == 1)
         break;
      if (strcmp(notatenames[count-1], notatenames[j]) == 0)
         syntxerr("notation name can be specified only once in DTD");
   }
   if ((j = INPPS()) == EOF)
      terminate(1, "EOF found in ATTLIST declaration");
   if (j < 1)
      syntxerr("Expected PS+ at this point");
   ADDCHAR(SPACE);
   inpextrnlID();
}
/* ============================================================ */
void inpextrnlID()
{
   char idtype[NAMELEN + 1], *nptr = idtype;
   if( INPNAME(&nptr, NAMELEN, TOUPPER) == EOF)
      terminate(1, "EOF found while processing external identifier");
   ADDSTRING(idtype);
   if (strcmp(idtype, "SYSTEM") == 0)
      dosystem(NO);
   else if (strcmp(idtype, "PUBLIC") == 0)
      dopublic(NO);
   else syntxerr("Expected 'PUBLIC' or 'SYSTEM'");
}
/* ============================================================ */
void dosystem(eflag)
int eflag;
{
   int j, flag, len = 0;

   if ((j = INPPS()) == EOF)
      terminate(1, "EOF found in NOTATION declaration");
   ADDCHAR(SPACE);
   if ((j = jgetc()) == EOF)
      terminate(1, "EOF found in NOTATION declaration");
   ADDCHAR(j);
   if (j == MDC) {
      if (eflag)
         jungetc(j);
      return;
   }
   if ((j == LIT) || (j == LITA))
      flag = j;
   else {
      if (eflag == YES) {
         jungetc(j);
         return;
      }
      syntxerr("expected LIT or LITA");
   }
   while((j = jgetc()) != flag) {
      if (++len > LITLEN)
         syntxerr("system identifier exceeds LITLEN");
      if (j == EOF)
         terminate(1, "EOF found while inputting minimum literal");
      ADDCHAR(j);
   }
   ADDCHAR(j);
   if ((j = INPPS()) == EOF)
      terminate(1, "EOF found in NOTATION declaration");
   if (eflag == YES)
      return;
   j = jgetc();
   ADDCHAR(j);
   if (j != MDC)
      syntxerr("Expected MDC following system identifier");
}
/* ============================================================ */
void dopublic(eflag)
int eflag;
{
   int j, flag;
   char pubidentifier[LITLEN + 1];

   if ((j = INPPS()) == EOF)
      terminate(1, "EOF found in NOTATION declaration");
   ADDCHAR(SPACE);
   if ((j = jgetc()) == EOF)
      terminate(1, "EOF found in NOTATION declaration");

   ADDCHAR(j);
   if ((j == LIT) || (j == LITA))
      flag = j;
   else
      syntxerr("expected LIT or LITA");

   memset(pubidentifier, '\0', sizeof(pubidentifier));
   getminimumliteral(flag, pubidentifier, LITLEN );
   dosystem(eflag);
}
/* ============================================================ */
void getminimumliteral(flag, buffer, len)
int flag;
char *buffer;
int len;
{
   int j, compress = OFF, jlen = 0;

   while (1) {
      j = jgetc();
      if (j == EOF)
         terminate(1, "EOF found while inputting minimum literal");
      if (j == flag){
         ADDCHAR(j);
         return;
      }
      if (j == RS)
         continue;
      if ((j == SPACE) || (j == RE)) {
         if (compress == ON)
            continue;
         compress = ON;
         if (++jlen > len)
            syntxerr("LITLEN has been exceeded in minimum literal");
         *buffer++ = j;
         ADDCHAR(j);
         continue;
      }
      compress = OFF;
      if (++jlen > len)
         syntxerr("LITLEN has been exceeded in minimum literal");
      *buffer++ = j;
      ADDCHAR(j);
      if (ISALNUM(j))
         continue;
      if (isspcl(j))
         continue;
      syntxerr("illegal character in minimum literal");
   }
}
/* ============================================================ */
void cknotation(name)
char *name;
{
   int j;
   for (j = 0; j < count; j++) {
      if (strcmp(name, notatenames[j]) == 0)
         return;
   }
   printf("\n\nERROR:\n\n");
   printf("\'%s\' was used as notation name in an ATTLIST but -\n", name);
   printf("no notation declaration for \'%s\' was found\n", name);
   errflag = 1;
}
/* ============================================================ */
/* ============================================================ */
/* ============================================================ */
/* ============================================================ */
/* ============================================================ */
/* ============================================================ */
