Initial import of the CDE 2.1.30 sources from the Open Group.

This commit is contained in:
Peter Howkins
2012-03-10 18:21:40 +00:00
commit 83b6996daa
18978 changed files with 3945623 additions and 0 deletions

View File

@@ -0,0 +1,75 @@
XCOMM $XConsortium: Imakefile /main/3 1995/11/08 10:41:11 rswiston $
/* build Imakefile */
HTAG2 = ..
HTAG2SRC = $(HTAG2)/htag2
SDLPARSERSRC = $(HTAG2)/parser
SDLELTDEFSRC = $(HTAG2)/eltdef
SDLDTDFILE = $(HTAG2SRC)/sdl.dtd
SDLUTILSRC = $(HTAG2)/util
SDLBUILDSRC = $(HTAG2)/build
SDLUTILLIB = $(HTAG2)/util/libutil.a
INCLUDES = -I. -I$(SDLUTILSRC)
SRCS = \
build.c buildutl.c eltree.c except.c fsa.c out.c param.c \
scan.c sref.c tree.c
OBJS = \
build.o buildutl.o eltree.o except.o fsa.o out.o param.o \
scan.o sref.o tree.o
CHPRODS = context.h delim.h
CCPRODS = case.c
BHPRODS = dtd.h entity.h arc.h
BCPRODS =
CTRASH = error delim.dat
BTRASH = error template
CPRODS = $(CHPRODS) $(CCPRODS)
BPRODS = $(BHPRODS) $(BCPRODS)
TRASH = error delim.dat template
PRODUCTS = $(CPRODS) $(BPRODS)
LOCAL_LIBRARIES = $(SDLUTILLIB)
/* Don't use shared libs for hp */
#ifdef HPArchitecture
#if OSMajorVersion > 7
EXTRA_LOAD_FLAGS = -Wl,-a archive
#endif
#endif
#ifdef SunArchitecture
.NO_PARALLEL:
#endif
all:: $(PRODUCTS)
$(BPRODS): build $(SDLDTDFILE)
$(RM) $(BPRODS) $(BTRASH)
./build < $(SDLDTDFILE)
NormalLibraryObjectRule()
NormalProgramTarget(build,$(OBJS),delim.h $(LOCAL_LIBRARIES),$(LOCAL_LIBRARIES),)
$(CPRODS): $(SDLUTILSRC)/context $(HTAG2SRC)/delim.bld context.dat
$(RM) $(CPRODS) $(CTRASH)
/* get application-specific delim.dat */
$(CP) $(HTAG2SRC)/delim.bld delim.dat
$(SDLUTILSRC)/context sparse
$(SDLUTILSRC)/context:
cd $(SDLUTILSRC); make context
clean::
$(RM) $(PRODUCTS) $(TRASH)
depend:: $(SRCS)
DependTarget()
includes:: $(PRODUCTS)

View File

@@ -0,0 +1,52 @@
/* $XConsortium: build.c /main/3 1995/11/08 10:41:26 rswiston $ */
/*
Copyright 1986 Tandem Computers Incorporated.
This product and information is proprietary of Tandem Computers Incorporated.
Copyright (c) 1986, 1987, 1988, 1989 Hewlett-Packard Co.
*/
/* Build.c contains the main procedure for program BUILD */
#include <string.h>
#include <malloc.h>
#if defined(MSDOS)
#include <process.h>
#endif
#include "context.h"
#define BUILDEF
#include "build.h"
#include "delim.h"
#include "entdef.h"
/* Main procedure */
void main(argc, argv)
int argc ;
char **argv ;
{
int m_prevcon ;
if (argc > 1)
{
if (strchr(argv[1], 'a')) m_malftrace = TRUE ;
if (strchr(argv[1], 'A')) m_malftrace = TRUE ;
if (strchr(argv[1], 'a')) m_malftrace = TRUE ;
if (strchr(argv[1], 'H')) m_heapchk = TRUE ;
if (strchr(argv[1], 'm')) standard = TRUE ;
if (strchr(argv[1], 'M')) standard = TRUE ;
if (strchr(argv[1], 's')) scantrace = TRUE ;
if (strchr(argv[1], 'S')) scantrace = TRUE ;
}
initialize() ;
while (TRUE)
{
m_token = scan() ;
m_prevcon = curcon ;
curcon = m_newcon(m_prevcon - 1, m_token - 1) ;
if (scantrace)
printf(
"m_prevcon=%d, m_token=%d, curcon=%d, scanval = %c (%d), line=%d\n",
m_prevcon, m_token, curcon, scanval, scanval, m_line) ;
#include "case.c"
if (m_token == ENDFILE) exit(FALSE) ;
}
}

View File

@@ -0,0 +1,406 @@
/* $XConsortium: build.h /main/3 1995/11/08 10:41:43 rswiston $ */
/*
Copyright 1986 Tandem Computers Incorporated.
This product and information is proprietary of Tandem Computers Incorporated.
Copyright (c) 1986, 1987, 1988, 1989 Hewlett-Packard Co.
*/
/* Build.h is the primary include file for allocation of global variables
for program BUILD. */
#if defined(BUILDEF)
#define BUILDEXTERN
#define BUILDINIT(a) = a
#else
#define BUILDEXTERN extern
#define BUILDINIT(a)
#endif
#include <stdio.h>
#include "basic.h"
#include "trie.h"
#include "common.h"
/* Defined types */
typedef struct arc ARC ;
typedef struct state STATE ;
typedef struct tree TREE ;
typedef struct statelist STATELIST ;
typedef struct parameter PARAMETER ;
typedef struct exception EXCEPTION ;
typedef struct ptype PTYPE ;
typedef struct eltstruct ELTSTRUCT ;
typedef struct lhsstruct LHS ;
typedef struct stack STACK ;
typedef struct srefstruct SREFSTRUCT ;
typedef struct srefdata SREFDATA ;
typedef struct mapstruct MAP ;
typedef struct andgroup ANDGROUP ;
/* Each item in a list of states contains value, a pointer to a state;
next, a pointer to the next item in the list; and level, which
indicates the level of nested subexpressions within the regular expression
when the state was added to the FSA. */
BUILDEXTERN struct statelist {
STATE *value ;
STATELIST *next ;
int level ;
} ;
struct stack {
STACK *oldtop ;
STATELIST *starts ;
STATELIST *finals ;
STATELIST *allfinal ;
STATELIST *newfinal ;
ARC *starta ;
} ;
BUILDEXTERN STACK bot
#if defined(BUILDEF)
= {
NULL, NULL, NULL, NULL, NULL, NULL
}
#endif
;
BUILDEXTERN STACK *top BUILDINIT(&bot) ;
BUILDEXTERN int stacklevels BUILDINIT(0) ;
/* Used to report nondeterminism in and groups */
#define ANDCONFLICT 1
#define DATACONFLICT 2
#define ELTCONFLICT 3
/* Name of an element, and of the first element on the left-hand side of
the current rule */
#define thisrule lhs->elt->enptr
/* Set declared entity type */
#define SETETYPE(p,t) adddefent(p) ; entity->type = t
/* Definitions for entities */
#define EMPTYMAP 1
#define ERREXIT 1
/* Prefix for default short reference map and entities */
#define M_PREFIX "M-"
/* State transition network generated by CONTEXT */
#define sparse
#include "sparse.h"
/* Function prototypes */
#include "proto.h"
/* Frequently output strings */
#define ndif "}\n#endif\n ;\n\n"
#define SUBONE else fputs("[1] ;\n\n", dtd) ;
/* An array used to indicate which characters can appear within
element names */
#if defined(BUILDEF)
#include "chartype.h"
#else
extern M_CHARTYPE m_ctarray[M_CHARSETLEN] ;
#endif
/* Current state of the finite-state machine which controls BUILD */
BUILDEXTERN int curcon BUILDINIT(RULE) ;
BUILDEXTERN int m_token ;
BUILDEXTERN M_WCHAR scanval ;
/* Used to pass names and literals from the scanner */
BUILDEXTERN M_WCHAR name[M_NAMELEN + 1] ;
BUILDEXTERN M_WCHAR literal[M_LITLEN + 1] ;
/* Scanner buffer for read-ahead */
BUILDEXTERN int toundo BUILDINIT(0) ;
BUILDEXTERN int maxundo BUILDINIT(0) ;
/* Size of scanner buffer for read-ahead */
#define SAVECHAR 50
BUILDEXTERN int savechar[SAVECHAR] ;
/* Whether errors have occurred */
BUILDEXTERN LOGICAL errexit BUILDINIT(FALSE) ;
/* FSA storage */
/* Each state in an FSA is represented by a flag indicating whether it is
a final state, a pointer to a list of transitions from the state,
and a flag that indicates whether parsed character data is possible
from the state */
BUILDEXTERN struct state {
LOGICAL final ;
LOGICAL datacontent ;
LOGICAL frompcdata ;
ARC *first ;
int count ;
STATE *next ;
} ;
BUILDEXTERN STATE *firststate BUILDINIT(NULL) ;
BUILDEXTERN STATE **nextstate BUILDINIT(&firststate) ;
BUILDEXTERN STATE *startstate ;
/* Each arc in an FSA is an element in the arc list emanating from a
particular state. Associated fields include label, a pointer to
the name of the element labelling the arc (garbage if the label is an
and group); optional, a flag indicating whether or not the label is
contextually required; minim, a flag indicating whether or not the arc
corresponds to an element selected by explicit minimization;
and group, a pointer to the list of FSA's making
up the andgroup if the arc's label is an andgroup; to, a pointer to the
state entered by the arc; next, a pointer to the next arc
in the current arc list; and finally, id, a pointer to the node in the
tree representation of the model corresponding to the arc (id is used
in the detection of ambiguity to differentiate between arcs with the same
label corresponding to one model token and those with the same label
corresponding to more than one model token).
*/
BUILDEXTERN struct arc {
ELTSTRUCT *label ;
LOGICAL optional ;
LOGICAL minim ;
ANDGROUP *group ;
STATE *to ;
ARC *next ;
int id ;
} ;
/* Andgroups are elements in a list of the FSA's corresponding to the
content submodels in an andgroup. Each list element contains a pointer
to the start state of the FSA and a pointer to the next element in the
list */
BUILDEXTERN struct andgroup{
STATE *start ;
ANDGROUP *nextptr ;
ANDGROUP *next ;
int count ;
} ;
BUILDEXTERN ANDGROUP *firstand BUILDINIT(NULL) ;
BUILDEXTERN ANDGROUP **nextand BUILDINIT(&firstand) ;
/* Tree representation of a rule */
/* Each node in the tree representation corresponds to a submodel.
Associated with the node is the submodel's connector and occurrence
indicator; terminal, a flag indicating whether the submodel in turn
has submodels; value, the element of which a terminal submodel consists;
pointers first and last to the first and last submodel of the node;
and right pointing to the node's next sibling in the tree. */
struct tree {
int connector, occurrence ;
ELTSTRUCT *value ;
LOGICAL terminal ;
LOGICAL minim ;
TREE *first, *right, *parent ;
int eltid ;
} ;
BUILDEXTERN TREE *ruletree BUILDINIT(NULL) ;
BUILDEXTERN TREE *curtree ;
/* Various counters */
BUILDEXTERN int eltsinrule BUILDINIT(0) ;
BUILDEXTERN int stateused BUILDINIT(0) ;
BUILDEXTERN int andused BUILDINIT(0) ;
/* Element names on the left-hand side of the current rule */
struct lhsstruct {
ELTSTRUCT *elt ;
LHS *next ;
} ;
BUILDEXTERN LHS *lhs BUILDINIT(NULL) ;
BUILDEXTERN LHS **nextlhs BUILDINIT(&lhs) ;
/* Content type (regular expression, ANY, NONE, CDATA, RCDATA) of the
current rule. */
BUILDEXTERN int contype ;
/* Indicates whether <PARAM>, <USEMAP>, or <MIN> fields have occurred in
current rule */
BUILDEXTERN LOGICAL poccur, uoccur, moccur ;
/* Indicates whether an ID parameter for this rule has occurred */
BUILDEXTERN LOGICAL idoccur ;
/* Short reference map for this rule */
BUILDEXTERN int srefp ;
BUILDEXTERN LOGICAL useoradd ;
/* Whether start- and end-tag minimization are permitted for the current
rule */
BUILDEXTERN LOGICAL smin, emin ;
/* Suffix for generated entity names */
BUILDEXTERN int egensuf ;
/* Storage for exceptions */
BUILDEXTERN int excount BUILDINIT(0) ;
struct exception {
int element ;
EXCEPTION *next ;
EXCEPTION *nextptr ;
} ;
BUILDEXTERN EXCEPTION *firstex BUILDINIT(NULL) ;
BUILDEXTERN EXCEPTION **nextex BUILDINIT(&firstex) ;
BUILDEXTERN EXCEPTION *exlist ;
/* Total number of parameters for all elements */
BUILDEXTERN int parcount BUILDINIT(0) ;
/* Primary representation of parameters */
struct parameter {
M_WCHAR *paramname ;
int type ;
int kwlist ;
PTYPE *ptypep ;
int deftype ;
int defval ;
M_WCHAR *defstring ;
/* Next parameter for this element */
PARAMETER *next ;
/* Link for list of all parameters for all elements */
PARAMETER *nextptr ;
} ;
BUILDEXTERN PARAMETER *newpar BUILDINIT(NULL) ;
BUILDEXTERN PARAMETER *plist BUILDINIT(NULL) ;
BUILDEXTERN PARAMETER *firstpar BUILDINIT(NULL) ;
BUILDEXTERN PARAMETER **nextpar BUILDINIT(&firstpar) ;
/* Storage for parameter names */
BUILDEXTERN int pnamelen BUILDINIT(0) ;
/* Storage for parameter values that are named keywords */
BUILDEXTERN int ptypelen BUILDINIT(0) ;
struct ptype {
M_WCHAR *keyword ;
int next ;
PTYPE *nextptr ;
} ;
BUILDEXTERN PTYPE *firstptype BUILDINIT(NULL) ;
BUILDEXTERN PTYPE *thisptype ;
BUILDEXTERN PTYPE **nextptype BUILDINIT(&firstptype) ;
BUILDEXTERN int kwlen BUILDINIT(0) ;
/* Storage for parameter default values */
BUILDEXTERN int deflen BUILDINIT(0) ;
/* Characters needed for element names */
BUILDEXTERN int enamelen BUILDINIT(0) ;
/* Description of an element: */
struct eltstruct {
/* Pointer to element name */
M_WCHAR *enptr ;
/* Start state of element's content model's FSA */
STATE *model ;
/* Type of element's content (Regular expression, ANY, RCDATA, etc) */
int content ;
/* Pointer to element's inclusion list */
int inptr ;
/* Pointer to element's exclusion list */
int exptr ;
/* Pointer to element's parameter list */
PARAMETER *parptr ;
/* Index in output of first item in element's parameter list */
int parindex ;
/* Number of element's parameters */
int paramcount ;
/* Whether start- and end-tag minimization are permitted */
LOGICAL stmin, etmin ;
/* Pointer to short reference map, if any */
int srefptr ;
/* TRUE for USEMAP, FALSE for ADDMAP */
LOGICAL useoradd ;
ELTSTRUCT *next ;
int eltno ;
} ;
BUILDEXTERN ELTSTRUCT *firstelt BUILDINIT(NULL) ;
BUILDEXTERN ELTSTRUCT **nextelt BUILDINIT(&firstelt) ;
/* Most number of parameters had by a single element */
BUILDEXTERN int maxpar BUILDINIT(0) ;
/* Number of parameters current element has */
BUILDEXTERN int pcount ;
BUILDEXTERN FILE *dtd ;
BUILDEXTERN FILE *m_errfile ;
/* Line number in input file */
BUILDEXTERN int m_line BUILDINIT(1) ;
/* Options */
/* Scan trace */
BUILDEXTERN LOGICAL scantrace BUILDINIT(FALSE) ;
/* Trace calls to malloc/free */
BUILDEXTERN LOGICAL m_malftrace BUILDINIT(FALSE) ;
/* Test validity of heap in calls to malloc/free */
BUILDEXTERN LOGICAL m_heapchk BUILDINIT(FALSE) ;
/* Flag set if strictly conforming to ISO 8879 */
BUILDEXTERN LOGICAL standard BUILDINIT(FALSE) ;
/* File pointer used by utilities in ..\util\scanutil for input file */
BUILDEXTERN FILE *ifile ;
/* Element names are stored in a trie. */
BUILDEXTERN M_TRIE eltree ;
/* Count of elements */
BUILDEXTERN int ecount BUILDINIT(0) ;
/* Storage for short reference map names and definitions */
BUILDEXTERN M_TRIE maptree ;
BUILDEXTERN M_TRIE sreftree ;
BUILDEXTERN int mapcnt BUILDINIT(0) ;
BUILDEXTERN int curmap ;
struct srefstruct {
int srefcnt ;
SREFDATA *data ;
SREFSTRUCT *next ;
} ;
BUILDEXTERN SREFSTRUCT *firstsref BUILDINIT(NULL) ;
BUILDEXTERN SREFSTRUCT **nextsref BUILDINIT(&firstsref) ;
struct srefdata {
int map ;
int entidx ;
SREFDATA *next ;
} ;
BUILDEXTERN SREFDATA *thissref ;
BUILDEXTERN int sreflen BUILDINIT(0) ;
BUILDEXTERN M_WCHAR mapname[M_NAMELEN + 1] ;
BUILDEXTERN int maxsr ;
BUILDEXTERN int maxseq ;
struct mapstruct {
int map ;
M_WCHAR *mapname ;
LOGICAL defined ;
MAP *nextptr ;
} ;
BUILDEXTERN MAP *firstmap BUILDINIT(NULL) ;
BUILDEXTERN MAP **nextmap BUILDINIT(&firstmap) ;
/* Storage for entities */
BUILDEXTERN M_TRIE m_enttrie[1] ;
BUILDEXTERN M_ENTITY *entity ;
BUILDEXTERN M_ENTITY *lastent BUILDINIT(NULL) ;
BUILDEXTERN M_ENTITY *firstent BUILDINIT(NULL) ;
BUILDEXTERN M_WCHAR entcontent[M_LITLEN + 1] ;
BUILDEXTERN int entclen ;
BUILDEXTERN int m_entcnt BUILDINIT(0) ;
BUILDEXTERN FILE *entfile ;
BUILDEXTERN LOGICAL entrule BUILDINIT(FALSE) ;
BUILDEXTERN M_WCHAR genname[M_NAMELEN + sizeof(M_PREFIX)] ;
M_WCHAR *MakeWideCharString(
#if defined(M_PROTO)
const char *from
#endif
);

View File

@@ -0,0 +1,148 @@
/* $XConsortium: buildutl.c /main/3 1995/11/08 10:41:58 rswiston $ */
/*
Copyright 1986 Tandem Computers Incorporated.
This product and information is proprietary of Tandem Computers Incorporated.
Copyright (c) 1986, 1987, 1988, 1989 Hewlett-Packard Co.
*/
/* Buildult.c contains the main supporting utilities for program BUILD */
#include <malloc.h>
#include "context.h"
#include "build.h"
#include "delim.h"
#include "version.h"
/* Verify that <PARAM>, <MIN> or <USEMAP> has not previously occurred in
this rule */
void found(flag, delim)
LOGICAL *flag;
char *delim;
{
M_WCHAR wcbuff[129];
size_t length;
wcbuff[128] = 0;
length = mbstowcs(wcbuff,delim,128);
if (length < 0)
{
m_error("An invalid multibyte character was seen");
wcbuff[0] = 0;
}
if (*flag)
{
m_err1("A rule can contain only one %s clause", wcbuff) ;
return ;
}
*flag = TRUE ;
}
/* Program initialization */
void initialize(M_NOPAR)
{
char **mb_delims;
M_WCHAR **wc_delims;
ifile = stdin ;
m_openchk(&m_errfile, "error", "w") ;
fprintf(stderr, "MARKUP System - BUILD %s\n", M_VERSION) ;
fprintf(stderr, "Copyright (c) 1986, 1987, 1988, 1989 Hewlett-Packard Co.\n") ;
if (! standard)
warning("Warning: optional enhancements of SGML enabled.") ;
mb_delims = mb_dlmptr;
wc_delims = m_dlmptr;
while (*mb_delims)
{
*wc_delims++ = MakeWideCharString(*mb_delims);
mb_delims++;
}
*wc_delims = 0;
ruleinit() ;
}
/* Initialization before starting a new rule */
void ruleinit(M_NOPAR)
{
/* Reinitialize for next rule */
lhs = NULL ;
nextlhs = &lhs ;
eltsinrule = 0 ;
plist = NULL ;
pcount = 0 ;
dellist(&bot.finals) ;
dellist(&bot.allfinal) ;
dellist(&bot.newfinal) ;
poccur = uoccur = moccur = FALSE ;
smin = emin = FALSE ;
srefp = 0 ;
useoradd = TRUE ;
egensuf = 1 ;
idoccur = FALSE ;
}
/* Rule end processing */
void rulend(M_NOPAR)
{
STATE *fsa ;
LOGICAL canbenull ;
LHS *lhsp ;
LHS *discard ;
int inptr ;
int exptr ;
if (contype == GRPO) fsa = startfsa(ruletree, &canbenull) ;
if (pcount > maxpar) maxpar = pcount ;
inptr = lhs->elt->inptr ;
exptr = lhs->elt->exptr ;
for (lhsp = lhs ; lhsp ; ) {
lhsp->elt->model = contype == GRPO ? fsa : (STATE *) M_NULLVAL ;
lhsp->elt->content = contype ;
lhsp->elt->inptr = inptr ;
lhsp->elt->exptr = exptr ;
if (plist) {
if (lhsp->elt->parptr)
warning1("Redefining parameter list for element %s",
lhsp->elt->enptr) ;
lhsp->elt->parptr = plist ;
lhsp->elt->paramcount = pcount ;
lhsp->elt->parindex = parcount - pcount + 1 ;
}
lhsp->elt->stmin = smin ;
lhsp->elt->etmin = emin ;
lhsp->elt->srefptr = srefp ;
lhsp->elt->useoradd = useoradd ;
discard = lhsp ;
lhsp = lhsp->next ;
m_free((M_POINTER) discard, "lhs") ;
}
if (ruletree) freetree(ruletree) ;
ruletree = NULL ;
ruleinit() ;
}
/* Skip rest of statement after an error */
void skiptoend(M_NOPAR)
{
int i ;
static errlev = 0 ;
if (! errlev++) {
curcon = ERROR ;
for (i = scan() ; ; i = scan())
if ((i == REND && ! entrule) ||
(i == TAGC && entrule) ||
i == ENDFILE) break ;
curcon = RULE ;
entrule = FALSE ;
}
errlev-- ;
ruleinit() ;
}

View File

@@ -0,0 +1,819 @@
comment
comcon:comcon {
/* $XConsortium: context.dat /main/3 1995/07/17 19:50:00 lehors $ */
/*
Copyright 1986 Tandem Computers Incorporated.
This product and information is proprietary of Tandem Computers Incorporated.
Copyright (c) 1986, 1987, 1988, 1989 Hewlett-Packard Co.
Context.dat defines the state transitions for program BUILD.
*/
}
;
produces
postel:content
postsref:entity
post2sref:entity2
;
except
lastm:excon
postc:excon
;
paropen
rule:firstparname
;
param
sref:pcon,
postc:pcon,
skipex:pcon,
excon:pcon,
lastm:pcon,
mcon:pcon,
postuse:pcon,
typedent:pcon {found(&poccur, param) ;}
postsref:pcon {
adddefent(thisrule);
found(&poccur, param);
}
;
shortref
rule:scon
;
usemap
pcon:ucon,
postc:ucon,
skipex:ucon,
excon:ucon,
lastm:ucon,
mcon:ucon,
default:ucon,
iddefault:ucon,
postdef:ucon,
curdef:ucon {found(&uoccur, "<USEMAP> or <ADDMAP>") ;}
;
addmap
pcon:ucon,
postc:ucon,
skipex:ucon,
excon:ucon,
lastm:ucon,
mcon:ucon,
default:ucon,
iddefault:ucon,
postdef:ucon,
curdef:ucon {
if (standard)
{
M_WCHAR *w_addmap, *w_tagc;
w_addmap = MakeWideCharString(addmap);
w_tagc = MakeWideCharString(tagc);
m_err2("%s%s not defined in the SGML standard",w_addmap,w_tagc);
m_free(w_addmap,"wide character string");
m_free(w_tagc,"wide character string");
}
else {
useoradd = FALSE;
found(&uoccur, "<USEMAP> or <ADDMAP>");
}
}
;
empty
ucon:postucon {srefp = EMPTYMAP ;}
;
entstart
rule:entdec {entrule = TRUE ;}
;
tagc
postucon:skipex
ucon:sref {
defmapname();
if (addmapname(genname, TRUE)) srefp = curmap + 1;
else m_err1("Default map name %s already in use", genname) ;
}
sconet:s2ref
parname:p2con
error:error
entval:rule,
typedec:rule,
postent:rule {entrule = FALSE ;}
;
ero
entity:entname
entity2:ent2name
;
entsystem
entity:typedent {SETETYPE(thisrule, M_SYSTEM) ;}
entity2:typed2ent {SETETYPE(mapname, M_SYSTEM) ;}
entval:typedec {entity->type = M_SYSTEM ;}
;
entst
entity:typedent {SETETYPE(thisrule, M_STARTTAG) ;}
entity2:typed2ent {SETETYPE(mapname, M_STARTTAG) ;}
entval:typedec {entity->type = M_STARTTAG ;}
mcon:mcon {smin = TRUE ;}
;
entet
entity:typedent {SETETYPE(thisrule, M_ENDTAG) ;}
entity2:typed2ent {SETETYPE(mapname, M_ENDTAG) ;}
entval:typedec {entity->type = M_ENDTAG ;}
mcon:mcon {emin = TRUE ;}
;
entmd
entity:typedent {SETETYPE(thisrule, M_MD) ;}
entity2:typed2ent {SETETYPE(mapname, M_MD) ;}
entval:typedec {entity->type = M_MD ;}
;
entpi
entity:typedent {SETETYPE(thisrule, M_PI) ;}
entity2:typed2ent {SETETYPE(mapname, M_PI) ;}
entval:typedec {entity->type = M_PI ;}
;
entsdata
entity:typedent {SETETYPE(thisrule, M_SDATA) ;}
entity2:typed2ent {SETETYPE(mapname, M_SDATA) ;}
entval:typedec {entity->type = M_SDATA ;}
;
min
pcon:mcon,
sref:mcon,
postc:mcon,
skipex:mcon,
excon:mcon,
lastm:mcon,
default:mcon,
iddefault:mcon,
postdef:mcon,
curdef:mcon,
postuse:mcon,
typedent:mcon {found(&moccur, min) ;}
postsref:mcon {
adddefent(thisrule);
found(&moccur, min);
}
;
grpo
rule:ngname
content:model {
contype = m_token;
ruletree = curtree = gettreenode();
}
model:model {
curtree->first = gettreenode();
curtree->first->parent = curtree;
curtree = curtree->first;
}
submod:model {
curtree->right = gettreenode();
curtree->right->parent = curtree->parent;
curtree = curtree->right;
}
openex:exname
type:ntname,
type2:nt2name {
newpar->type = m_token;
newpar->kwlist = M_NULLVAL;
}
;
grpc
namegroup:postel
modcon:occur2,
samecon:occur2,
occur:occur2,
occur2:occur2 {endmodel() ;}
exlist:excon
ntgroup:default
nt2group:default2
;
emi
model:neednm {
if (standard)
m_error("Explicit minimization is not provided in IS 8879");
else {
curtree->first = gettreenode();
curtree->first->parent = curtree;
curtree = curtree->first;
curtree->terminal = TRUE;
curtree->minim = TRUE;
}
}
submod:neednm2 {
if (standard)
m_error("Explicit minimization is not provided in IS 8879");
else {
curtree->right = gettreenode();
curtree->right->parent = curtree->parent;
curtree = curtree->right;
curtree->terminal = TRUE;
curtree->minim = TRUE;
}
}
;
incl
excon:openex {
lhs->elt->inptr = excount + 1;
exlist = NULL;
}
;
excl
excon:openex {
lhs->elt->exptr = excount + 1;
exlist = NULL;
}
;
psep
default:pcon
default2:p2con
iddefault:pcon
id2default:p2con
postdef:pcon
post2def:p2con
curdef:pcon
cur2def:p2con
postuse:sref
post2use:s2ref
typedent:sref
typed2ent:s2ref
postsref:sref {adddefent(thisrule) ;}
post2sref:s2ref {adddefent(mapname) ;}
;
rend
rule:rule
lastm:rule,
skipex:rule,
postc:rule,
excon:rule,
default:rule,
iddefault:rule,
postdef:rule,
curdef:rule,
error:rule,
mcon:rule,
postuse:rule,
pcon:rule,
sref:rule,
typedent:rule {rulend() ;}
postsref:rule {
adddefent(thisrule);
rulend();
}
default2:rule,
id2default:rule,
post2def:rule,
cur2def:rule {prulend() ;}
post2use:rule,
s2ref:rule,
typed2ent:rule {ruleinit() ;}
post2sref:rule {
adddefent(mapname);
ruleinit();
}
;
opt
lastm:postc,
occur:modcon,
occur2:samecon {curtree->occurrence = m_token ;}
;
plus
lastm:postc,
occur:modcon,
occur2:samecon {curtree->occurrence = m_token ;}
;
rep
lastm:postc,
occur:modcon,
occur2:samecon {curtree->occurrence = m_token ;}
;
seq
modcon:submod,
occur:submod {curtree->parent->connector = SEQ ; }
samecon:submod,
occur2:submod {
if (m_token != curtree->parent->connector)
m_error("All connectors in a submodel should be identical");
}
;
or
modcon:submod,
occur:submod {curtree->parent->connector = OR ; }
samecon:submod,
occur2:submod {
if (m_token != curtree->parent->connector)
m_error("All connectors in a submodel should be identical");
}
;
and
modcon:submod,
occur:submod {curtree->parent->connector = AND ; }
samecon:submod,
occur2:submod {
if (m_token != curtree->parent->connector)
m_error("All connectors in a submodel should be identical");
}
;
vi
curdef:defval,
cur2def:def2val {
if (standard) {
M_WCHAR *w_current;
w_current = MakeWideCharString(current);
warning1("Warning: %s initial values disallowed in ISO 8879",
w_current);
warning2(" Parameter %s for element %s",
newpar->paramname,
thisrule);
m_free(w_current,"wide character string");
}
}
;
entlit
entity:litent {
adddefent(thisrule);
entclen = 0;
}
entity2:lit2ent {
adddefent(mapname);
entclen = 0;
}
declitent:postent,
litent:postuse,
lit2ent:post2use,
edeclitent:postent,
elitent:postuse,
elit2ent:post2use {
entcontent[entclen] = M_EOS;
entity->content =
(M_WCHAR *) m_malloc(entclen + 1, "entity content");
w_strcpy(entity->content, entcontent);
entity->wheredef = M_DBUILD;
}
entval:declitent,
typedec:declitent,
typedent:litent,
typed2ent:lit2ent {entclen = 0 ;}
;
lit
litcon:litcon
default:default
default2:default2
defval:defval
def2val:def2val
sref:sref
s2ref:s2ref
;
entlita
entity:litaent {
adddefent(thisrule);
entclen = 0;
}
entity2:lita2ent {
adddefent(mapname);
entclen = 0;
}
declitaent:postent,
litaent:postuse,
lita2ent:post2use,
edclitaent:postent
elitaent:postuse
elita2ent:post2use {
entcontent[entclen] = M_EOS;
entity->content =
(M_WCHAR *) m_malloc(entclen + 1, "entity content");
w_strcpy(entity->content, entcontent);
entity->wheredef = M_DBUILD;
}
entval:declitaent,
typedec:declitaent,
typedent:litaent,
typed2ent:lita2ent {entclen = 0 ;}
;
lita
litcon:litcon
default:default
default2:default2
defval:defval
def2val:def2val
sref:sref
s2ref:s2ref
;
rnicdata
model:modcon {
curtree->first = gettreenode();
curtree->first->parent = curtree;
curtree = curtree->first;
curtree->terminal = TRUE;
curtree->value = NULL;
/* While the SGML Standard treats #CDATA as a single character
with the occurrence indicator REP (optional and repeatable), here
it is treated as a variable-length string with occurrence
indicator OPT (optional). As a result, a single error message
is issued when text occurs in an invalid context instead of
repeating the diagnostic for each character */
curtree->occurrence = OPT;
}
submod:samecon {
curtree->right = gettreenode();
curtree->right->parent = curtree->parent;
curtree = curtree->right;
curtree->terminal = TRUE;
curtree->value = NULL;
curtree->occurrence = OPT;
}
;
connor
namegroup:ngname
exlist:exname
ntgroup:ntname
nt2group:nt2name
;
connseq
namegroup:ngname
exlist:exname
ntgroup:ntname
nt2group:nt2name
;
connand
namegroup:ngname
exlist:exname
ntgroup:ntname
nt2group:nt2name
;
current
default:curdef,
default2:cur2def {
newpar->deftype = m_token;
newpar->defval = M_NULLVAL;
}
;
required
iddefault:postdef,
default:postdef,
id2default:post2def,
default2:post2def {newpar->deftype = m_token ;}
;
nulldef
default:postdef
default2:post2def
iddefault:postdef
id2default:post2def
;
any
content:postc {contype = m_token ;}
;
none
content:skipex {contype = m_token ;}
;
rcdata
content:skipex {contype = m_token ;}
;
cdata
content:skipex {contype = m_token ;}
type:default,
type2:default2 {newpar->type = m_token ;}
entity:typedent {SETETYPE(thisrule, M_CDATAENT) ;}
entity2:typed2ent {SETETYPE(mapname, M_CDATAENT) ;}
entval:typedec {entity->type = M_CDATAENT ;}
;
cro
litcon:litcon
;
litrs
litcon:litcon
;
litrsc
litcon:litcon
;
litre
litcon:litcon
;
litrec
litcon:litcon
;
littab
litcon:litcon
;
littabc
litcon:litcon
;
litspace
litcon:litcon
;
litcspace
litcon:litcon
;
refc
charent:charent
;
id
type:iddefault,
type2:id2default {
if (idoccur) m_error("Only one ID parameter allowed in a rule");
else {
idoccur = TRUE;
newpar->type = m_token;
}
}
;
idref
type:default,
type2:default2 {newpar->type = m_token ;}
;
idrefs
type:default,
type2:default2 {newpar->type = m_token ;}
;
nametype
type:default,
type2:default2 {newpar->type = m_token ;}
;
names
type:default,
type2:default2 {newpar->type = m_token ;}
;
nmtoken
type:default,
type2:default2 {newpar->type = m_token ;}
;
nmtokens
type:default,
type2:default2 {newpar->type = m_token ;}
;
number
type:default,
type2:default2 {newpar->type = m_token ;}
;
numbers
type:default,
type2:default2 {newpar->type = m_token ;}
;
nutoken
type:default,
type2:default2 {newpar->type = m_token ;}
;
nutokens
type:default,
type2:default2 {newpar->type = m_token ;}
;
entatt
type:default,
type2:default2 {newpar->type = m_token ;}
;
endfile
curdef:rule,
default:rule,
iddefault:rule,
excon:rule,
lastm:rule,
postc:rule,
postdef:rule,
skipex:rule,
mcon:rule,
postuse:rule,
typedent:rule {
rulend() ;
done();
}
postsref:rule {
adddefent(thisrule);
rulend();
done();
}
cur2def:rule,
default2:rule,
id2default:rule,
post2def:rule {prulend() ; done() ;}
rule:rule,
post2use:rule,
post2sref:rule,
typed2ent:rule {done() ;}
;
name
default:postdef,
default2:post2def {
newpar->deftype = NAME;
setdefault(name);
}
defval:postdef,
def2val:post2def {setdefault(name) ;}
exname:exlist {addex() ;}
model:occur {
curtree->first = gettreenode();
curtree->first->parent = curtree;
curtree = curtree->first;
curtree->terminal = TRUE;
curtree->value = ntrelt(name);
}
submod:occur2 {
curtree->right = gettreenode();
curtree->right->parent = curtree->parent;
curtree = curtree->right;
curtree->terminal = TRUE;
curtree->value = ntrelt(name);
}
neednm:occur,
neednm2:occur2
{curtree->value = ntrelt(name) ;}
ngname:namegroup {savelhs(FALSE) ;}
nt2name:nt2group,
ntname:ntgroup {addkeyword() ;}
pcon:type,
p2con:type2 {addpar() ;}
rule:postel {savelhs(FALSE) ;}
ucon:postucon {
addmapname(name, FALSE);
srefp = curmap + 1;
}
entname:postuse,
ent2name:post2use {addndent(name) ;}
firstparname:parname,
parname:parname {savelhs(TRUE) ;}
scon:sconet {
if (! addmapname(name, TRUE))
m_err1("Map name %s already in use", name);
else w_strcpy(mapname, name);
}
entdec:entval {
if (! addent(name))
m_err1("Entity %s already defined", name);
}
;
literal
default:postdef,
default2:post2def {
newpar->deftype = NAME;
setdefault(literal);
}
defval:postdef,
def2val:post2def {setdefault(literal) ;}
sref:postsref,
s2ref:post2sref {addsref(literal) ;}
;
text
declitent:declitent {
if (entclen >= M_LITLEN) {
curcon = EDECLITENT;
m_error("Entity content too long");
}
else entcontent[entclen++] = scanval;
}
declitaent:declitaent {
if (entclen >= M_LITLEN) {
curcon = EDCLITAENT;
m_error("Entity content too long");
}
else entcontent[entclen++] = scanval;
}
litent:litent {
if (entclen >= M_LITLEN) {
curcon = ELITENT;
m_error("Entity content too long");
}
else entcontent[entclen++] = scanval;
}
lit2ent:lit2ent {
if (entclen >= M_LITLEN) {
curcon = ELIT2ENT;
m_error("Entity content too long");
}
else entcontent[entclen++] = scanval;
}
litaent:litaent {
if (entclen >= M_LITLEN) {
curcon = ELITAENT;
m_error("Entity content too long");
}
else entcontent[entclen++] = scanval;
}
lita2ent:lita2ent {
if (entclen >= M_LITLEN) {
curcon = ELITA2ENT;
m_error("Entity content too long");
}
else entcontent[entclen++] = scanval;
}
edeclitent:edeclitent
edclitaent:edclitaent
elitent:elitent
elit2ent:elit2ent
elitaent:elitaent
elita2ent:elita2ent
;

View File

@@ -0,0 +1,45 @@
/* $XConsortium: eltree.c /main/3 1995/11/08 10:42:15 rswiston $ */
/*
Copyright 1986 Tandem Computers Incorporated.
This product and information is proprietary of Tandem Computers Incorporated.
Copyright (c) 1986, 1987, 1988, 1989 Hewlett-Packard Co.
*/
/* Eltree.c contains procedures that manipulate element names */
#include <string.h>
#include <malloc.h>
#include "build.h"
/* Enters an element name into the element name tree */
ELTSTRUCT *ntrelt(p)
M_WCHAR *p ;
{
ELTSTRUCT *new ;
ELTSTRUCT *old ;
int length ;
new = (ELTSTRUCT *) m_malloc(sizeof(ELTSTRUCT), "element structure") ;
if (old = (ELTSTRUCT *) m_ntrtrie(p, &eltree, (M_TRIE *) new)) {
m_free((M_POINTER) new, "element structure") ;
return(old) ;
}
*nextelt = new ;
nextelt = &new->next ;
new->eltno = ++ecount ;
length = w_strlen(p) + 1 ;
enamelen += length ;
new->enptr = (M_WCHAR *) m_malloc(length, "element name") ;
w_strcpy(new->enptr, p) ;
new->model = M_NULLVAL ;
new->content = M_NULLVAL ;
new->inptr = new->exptr = NULL ;
new->parptr = NULL ;
new->parindex = M_NULLVAL ;
new->paramcount = M_NULLVAL ;
new->stmin = new->etmin = FALSE ;
new->srefptr = M_NULLVAL ;
new->useoradd = TRUE ;
new->next = NULL ;
return(new) ;
}

View File

@@ -0,0 +1,23 @@
/* $XConsortium: except.c /main/3 1995/11/08 10:42:31 rswiston $ */
/*
Copyright 1986 Tandem Computers Incorporated.
This product and information is proprietary of Tandem Computers Incorporated.
Copyright (c) 1986, 1987, 1988, 1989 Hewlett-Packard Co.
*/
/* Except.c contains procedures related to exceptions for program BUILD */
#include "build.h"
/* Add an exception (inclusion or exclusion) for the current element */
void addex(M_NOPAR)
{
excount++ ;
*nextex = (EXCEPTION *) m_malloc(sizeof(EXCEPTION), "exception") ;
if (exlist) exlist->next = *nextex ;
exlist = *nextex ;
(*nextex)->next = NULL ;
(*nextex)->nextptr = NULL ;
(*nextex)->element = ntrelt(name)->eltno ;
nextex = &(*nextex)->nextptr ;
}

View File

@@ -0,0 +1,734 @@
/* $XConsortium: fsa.c /main/3 1995/11/08 10:42:48 rswiston $ */
/*
Copyright 1986 Tandem Computers Incorporated.
This product and information is proprietary of Tandem Computers Incorporated.
Copyright (c) 1986, 1987, 1988, 1989 Hewlett-Packard Co.
*/
/* Fsa.c contains the procedures used by program BUILD to convert a tree
representation of a content model to an FSA */
#include <malloc.h>
#include "build.h"
#include "context.h"
#include "delim.h"
/* Addarc adds an arc from FSA state <from> to state <to> setting other
fields as indicated by the other parameters.*/
#if defined(M_PROTO)
int addarc(STATE *from, STATE *to, ELTSTRUCT *label, ANDGROUP *and, LOGICAL optional, int id, LOGICAL minim, ELTSTRUCT **errelt)
#else
int addarc(from, to, label, and, optional, id, minim, errelt)
STATE *from, *to ;
ELTSTRUCT *label ;
ANDGROUP *and ;
LOGICAL optional ;
int id ;
LOGICAL minim ;
ELTSTRUCT **errelt ;
#endif
{
ARC *parc, *qarc ;
int determ ;
determ = checkdfsa(from, label, and, id, errelt) ;
parc = from->first ;
qarc = (ARC *) m_malloc(sizeof(ARC), "arc") ;
from->first = qarc ;
qarc->label = label ;
qarc->optional = optional ;
qarc->minim = minim ;
qarc->group = and ;
qarc->to = to ;
qarc->next = parc ;
qarc->id = id ;
return(determ) ;
}
/*checkand is used to verify nondeterminism from start and final states
of FSA's generated from and groups*/
void checkand(andstart, andptr, start, root, errelt)
ANDGROUP *andstart, *andptr ;
STATE *start ;
TREE *root ;
ELTSTRUCT **errelt ;
{
ARC *parc ;
ANDGROUP *pand ;
int c ;
for (parc = start->first ; parc ; parc = parc->next) {
if (parc->group) {
if (parc->group != andstart)
for (pand = parc->group ; pand ; pand = pand->next)
checkand(andstart, andptr, pand->start, root, errelt) ;
}
else if (c = checkdfsa(andptr->start,
parc->label,
parc->group,
parc->id,
errelt))
nondeterm(root, c, *errelt) ;
}
}
/*Checkdfsa is called when adding an arc to an FSA in order to verify that
no existing arc from the same state (or from a start state of an and-group
FSA labelling an arc from the same state) has the same label. */
int checkdfsa(from, label, and, id, errelt)
STATE *from ;
ELTSTRUCT *label ;
ANDGROUP *and ;
int id ;
ELTSTRUCT **errelt ;
{
int c ;
ARC *parc ;
ANDGROUP *group ;
for (parc = from->first ; parc ; parc = parc->next) {
if (parc->group) {
if (and == parc->group) return(ANDCONFLICT) ;
for (group = parc->group ; group ; group = group->next)
if (c = checkdfsa(group->start, label, and, id, errelt))
return(c) ;
}
else if (! and && label == parc->label && parc->id != id) {
if (label) {
*errelt = label ;
return(ELTCONFLICT) ;
}
return(DATACONFLICT) ;
}
}
return(FALSE) ;
}
/* Check use of repeated models with and groups */
int checkrepeat(from, and, errelt)
STATE *from ;
ANDGROUP *and ;
ELTSTRUCT **errelt ;
{
ARC *parc ;
int c ;
for (; and ; and = and->next)
for (parc = and->start->first ; parc ; parc = parc->next) {
if (parc->group)
if (c = checkrepeat(from, parc->group, errelt)) return(c) ;
else ;
else
if (c = checkdfsa(from,
parc->label,
M_NULLVAL,
parc->id,
errelt))
return(c) ;
else ;
}
return(FALSE) ;
}
/* Copyintolist copies one list of states into another */
void copyintolist(from, to)
STATELIST *from, **to ;
{
STATELIST **new, *old ;
old = *to ;
new = to ;
for ( ; from ; from = from->next) {
if (notinlist(from, old)) {
*new = (STATELIST *) m_malloc(sizeof(STATELIST), "state list") ;
(*new)->value = from->value ;
(*new)->level = from->level ;
new = &(*new)->next ;
}
}
*new = old ;
}
/* Dellist deletes a list of states */
void dellist(list)
STATELIST **list ;
{
STATELIST *p, *q ;
for (p = *list ; p ; ) {
q = p ;
p = p->next ;
m_free(q, "state list") ;
}
*list = NULL ;
}
/* Delstartarcs deletes the contents of the starta list of arcs from start
states of a submodel */
void delstartarcs(M_NOPAR)
{
ARC *arcptr ;
ARC *discard ;
for (arcptr = top->starta ; arcptr ; ) {
discard = arcptr ;
arcptr = arcptr->next ;
m_free(discard, "arc") ;
}
top->starta = NULL ;
}
/* Getand allocates and initializes a new andgroup structure */
ANDGROUP *getand(M_NOPAR)
{
ANDGROUP *new ;
new = (ANDGROUP *) m_malloc(sizeof(ANDGROUP), "and group") ;
new->nextptr = new->next = NULL ;
new->count = ++andused ;
*nextand = new ;
nextand = &new->nextptr ;
return(new) ;
}
/* Getstate obtains an FSA state */
STATE *getstate(M_NOPAR)
{
STATE *new ;
new = (STATE *) m_malloc(sizeof(STATE), "state") ;
new->final = FALSE ;
new->datacontent = FALSE ;
new->frompcdata = FALSE ;
new->first = NULL ;
new->count = ++stateused ;
new->next = NULL ;
*nextstate = new ;
nextstate = &new->next ;
return(new) ;
}
/* Makeand processes a submodel whose connector is & */
void makeand(canbenull, root, optional)
LOGICAL *canbenull ;
TREE *root ;
int optional ;
{
TREE *child ;
STATELIST *start, *final ;
LOGICAL groupbenull ;
ANDGROUP *andptr, *saveand, *otherand ;
STATELIST *index ;
ELTSTRUCT *errelt ;
for (child = root->first ; child ; child = child->right) {
if (child == root->first) {
*canbenull = TRUE ;
andptr = getand() ;
saveand = andptr ;
push() ;
copyintolist(top->oldtop->allfinal, &top->allfinal) ;
}
else {
andptr->next = getand() ;
andptr = andptr->next ;
}
andptr->start = startfsa(child, &groupbenull) ;
if (andptr->start->datacontent)
for (index = top->oldtop->starts ; index ; index = index->next)
index->value->datacontent = TRUE ;
if (! groupbenull) *canbenull = FALSE ;
/* Check for ambiguity between start state of branch just completed
and start state of the and-group (i.e., parent of branch just
completed) */
for (start = top->oldtop->starts ; start ; start = start->next)
checkand(saveand, andptr, start->value, root, &errelt) ;
/* Check for ambiguity between start state of branch just completed
and final states of previous branches */
for (final = top->allfinal ; final ; final = final->next)
checkand(saveand, andptr, final->value, root, &errelt) ;
copyintolist(top->finals, &top->allfinal) ;
copyintolist(top->newfinal, &top->allfinal) ;
copyintolist(top->finals, &top->oldtop->newfinal) ;
copyintolist(top->newfinal, &top->oldtop->newfinal) ;
dellist(&top->finals) ;
dellist(&top->newfinal) ;
/* Check for ambiguity between start states of branch just completed
and start states of previous branches */
for (otherand = saveand ; otherand != andptr ;
otherand = otherand->next)
checkand(saveand, andptr, otherand->start, root, &errelt) ;
}
pop() ;
if (*canbenull) optional = stacklevels + 1 ;
simplebranch(root, M_NULLVAL, saveand, optional) ;
if (*canbenull) copyintolist(top->starts, &top->finals) ;
for (final = top->finals ; final ; final = final->next)
final->level = stacklevels ;
}
/* Makefsa builds the portion of an FSA that corresponds to an entire
submodel (i.e., a subtree of the tree representation of the rule).
The value returned indicates whether the submodel can be null (i.e.,
whether all its elements are optional). The parameters are a pointer
to the root of the subtree and an integer indicating the level of
nesting (if any) of submodels at which the subtree became optional.
Note that as used here, "optional" means "not contextually required" in
the terminology of the Standard rather than "contextually optional".
Makefsa is a recursive procedure. As the FSA is built, a stack is
maintained of the nested content models that have been encountered
but not yet terminated. For each open model on the stack, starts is
a list of its start states (i.e., FSA states from which transitions
correspond to elements which can occur at the beginning of the rule
being processed), finals is a list of its final states, starta is a
list of arcs emanating from the start states of the model, and
allfinal and newfinal are lists of final states used in checking for
determinism when and-groups are used. In more detail, allfinal is a
list of final states of FSA's in and-groups that may occur just prior
to the current context; i.e., 1) when starting a new FSA in an and-group,
the set of final states of already-constructed FSA's in the same group
(or final states of FSA's in submodel and-groups that end such FSA's)
or 2) the set of final states of FSA's in an and-group that precedes
the current context (e.g., the final states of the and-group FSA's
when processing 'x' in ((a&b),x)). At each stage in the parse (or level
on the stack), newfinal is the set of states to be added to those in
allfinal as a result of processing at that level. Information in
allfinal is passed from model to submodel; information in newfinal
goes from submodel to model.
*/
LOGICAL makefsa(root, optional)
TREE *root ;
int optional ;
{
LOGICAL canbenull ;
canbenull = FALSE ;
if (root->occurrence == OPT || root->occurrence == REP)
optional = stacklevels + 1 ;
/* The branch consists of a single element name */
if (root->terminal)
simplebranch(root, root->value, M_NULLVAL, optional) ;
/* The submodel's connector is SEQ (,) */
else if (root->connector == SEQ)
makeseq(&canbenull, root, optional) ;
/* The submodel's connector is OR (|) */
else if (root->connector == OR)
makeor(&canbenull, root) ;
/* The submodel's connector is AND (&) */
else if (root->connector == AND)
makeand(&canbenull, root, optional) ;
/* The submodel is a single item in parentheses */
else canbenull = makefsa(root->first, optional) ;
/* The FSA is built, now repeat if occurrence indicator so indicates */
if (root->occurrence == OPT || root->occurrence == REP) canbenull = TRUE ;
if (root->occurrence == OPT) copyintolist(top->starts, &top->finals) ;
else if (root->occurrence == REP) {
repeat(root) ;
copyintolist(top->starts, &top->finals) ;
}
else if (root->occurrence == PLUS) repeat(root) ;
return(canbenull) ;
}
/* Makeor processes a submodel whose connector is | */
void makeor(canbenull, root)
LOGICAL *canbenull ;
TREE *root ;
{
TREE *child ;
STATELIST *final ;
push() ;
copyintolist(top->oldtop->starts, &top->starts) ;
copyintolist(top->oldtop->allfinal, &top->allfinal) ;
for (child = root->first ; child ; child = child->right) {
if (makefsa(child, stacklevels)) *canbenull = TRUE ;
savestartarcs() ;
delstartarcs() ;
copyintolist(top->finals, &top->oldtop->finals ) ;
dellist(&top->finals) ;
}
copyintolist(top->newfinal, &top->oldtop->newfinal) ;
pop() ;
for (final = top->finals ; final ; final = final->next)
final->level = stacklevels ;
}
/* Makeseq processes a submodel whose connector is , */
void makeseq(canbenull, root, optional)
LOGICAL *canbenull ;
TREE *root ;
int optional ;
{
LOGICAL branchnull ;
STATELIST *keepfinal = NULL, *final ;
TREE *child ;
push() ;
*canbenull = TRUE ;
copyintolist(top->oldtop->starts, &top->starts) ;
copyintolist(top->oldtop->allfinal, &top->allfinal) ;
for (child = root->first ; child ; child = child->right) {
branchnull = makefsa(child, optional) ;
if (*canbenull) savestartarcs() ;
if (! branchnull) {
*canbenull = FALSE ;
dellist(&top->allfinal) ;
dellist(&keepfinal) ;
}
copyintolist(top->newfinal, &top->allfinal) ;
copyintolist(top->newfinal, &keepfinal) ;
dellist(&top->newfinal) ;
delstartarcs() ;
dellist(&top->starts) ;
copyintolist(top->finals, &top->starts) ;
dellist(&top->finals) ;
if (! child->occurrence || child->occurrence == PLUS)
optional = FALSE ;
}
copyintolist(top->starts, &top->oldtop->finals) ;
copyintolist(keepfinal, &top->oldtop->newfinal) ;
dellist(&keepfinal) ;
pop() ;
for (final = top->finals ; final ; final = final->next)
final->level = stacklevels ;
}
/* Nondeterm issues a diagnostic when a nondeterministic model is
encountered */
void nondeterm(root, c, eltp)
TREE *root ;
int c ;
ELTSTRUCT *eltp ;
{
M_WCHAR *wtemp;
switch (c) {
case ANDCONFLICT:
wtemp = MakeWideCharString(and);
warning2("Error in model for %s: Conflict in use of '%s'",
thisrule,
wtemp) ;
m_free(wtemp, "wide character string");
break ;
case DATACONFLICT:
wtemp = MakeWideCharString(rnicdata);
warning2("Error in model for %s: Conflict in use of '%s'",
thisrule,
wtemp) ;
m_free(wtemp, "wide character string");
break ;
case ELTCONFLICT:
warning2("Error in model for %s: Conflict in use of '%s'",
thisrule,
eltp->enptr) ;
break ;
}
regenerate(ruletree, root) ;
msgline(" . . .\n") ;
}
/* Notinlist returns TRUE iff item is not in list. If item is in list,
it makes sure that the stored nesting level is the smaller of the two */
LOGICAL notinlist(item, list)
STATELIST *item, *list ;
{
for ( ; list ; list = list->next)
if (list->value == item->value) {
if (item->level < list->level) list->level = item->level ;
return(FALSE) ;
}
return(TRUE) ;
}
/* Returns true if the arc is labeled #PCDATA or with an and-group that
has an arc labelled #PCDATA from a start state */
LOGICAL permitspcd(a)
ARC *a ;
{
ANDGROUP *pand ;
ARC *b ;
if (a->group) {
for (pand = a->group ; pand ; pand = pand->next)
for (b = pand->start->first ;
b ;
b = b->next)
if (permitspcd(b)) return(TRUE) ;
return(FALSE) ;
}
/* Not an and-group */
if (a->label) return(FALSE) ;
return(TRUE) ;
}
/* Pop pops the submodel stack when the end of the current submodel is
encountered */
void pop(M_NOPAR)
{
STACK *discard ;
dellist(&top->starts) ;
dellist(&top->finals) ;
dellist(&top->allfinal) ;
dellist(&top->newfinal) ;
delstartarcs() ;
stacklevels-- ;
discard = top ;
top = top->oldtop ;
m_free((M_POINTER) discard, "stack entry") ;
}
/* Push pushes the submodel stack when a new group is encountered */
void push(M_NOPAR)
{
STACK *new ;
new = (STACK *) m_malloc(sizeof(STACK), "stack entry") ;
new->oldtop = top ;
top = new ;
stacklevels++ ;
top->starts = top->finals = top->newfinal = top->allfinal = NULL ;
top->starta = M_NULLVAL ;
}
/* Regenerate is used in error processing to print the portion of a grammar
rule preceding an error */
LOGICAL regenerate(start, stop)
TREE *start, *stop ;
{
TREE *child ;
if (start == stop) return(TRUE) ;
if (start->terminal)
{
char *mb_enptr;
if (start->value)
mb_enptr = MakeMByteString(start->value->enptr);
else
mb_enptr = NULL;
msg1line("%s", mb_enptr ? mb_enptr : rnicdata) ;
if (mb_enptr)
m_free(mb_enptr,"multi-byte string");
}
else
{
msgline("(") ;
for (child = start->first ; child ; child = child->right)
{
if (regenerate(child, stop)) return(TRUE) ;
if (child->right)
{
if (start->connector == SEQ) msg1line("%s", seq) ;
if (start->connector == OR) msg1line("%s", or) ;
if (start->connector == AND) msg1line("%s", and) ;
}
}
msgline(")") ;
}
if (start->occurrence == OPT) msg1line("%s", opt) ;
if (start->occurrence == PLUS) msg1line("%s", plus) ;
if (start->occurrence == REP) msg1line("%s", rep) ;
return(FALSE) ;
}
/* Repeat is called after a partial FSA is built for a submodel whose
occurrence indicator is RPT (*) or PLUS (+). It handles repetition
by adding arcs from all the final states to all the states reachable
in one transition from a start state, labelling them as arcs from
start states are labelled. */
void repeat(root)
TREE *root ;
{
STATELIST *final ;
ARC *a ;
int c ;
ELTSTRUCT *errelt ;
M_WCHAR *wtemp;
copyintolist(top->newfinal, &top->allfinal) ;
dellist(&top->newfinal) ;
for (a = top->starta ; a ; a = a->next) {
for (final = top->allfinal ; final ; final = final->next) {
if (a->group)
if (c = checkrepeat(final->value, a->group, &errelt)) {
wtemp = MakeWideCharString(root->occurrence == PLUS ? plus : rep);
warning1("Conflict in use of %s", wtemp);
m_free(wtemp, "wide character string");
nondeterm(root, c, errelt) ;
}
else
;
else
if (c = checkdfsa(final->value,
a->label,
a->group,
a->id,
&errelt))
nondeterm (root, c, errelt) ;
else
;
}
for (final = top->finals ; final ; final = final->next) {
if (samelabelarc(a, final->value)) continue ;
if (a->group)
if (c = checkrepeat(final->value, a->group, &errelt))
nondeterm(root, c, errelt) ;
if (a->label ||
a->group ||
! final->value->frompcdata) {
if (c = addarc(final->value, a->to, a->label,
a->group, TRUE, a->id,
a->minim, &errelt))
nondeterm(root, c, errelt) ;
if (permitspcd(a)) final->value->datacontent = TRUE ;
}
}
}
}
/* Used during processing of occurrence indicators in content models such
as (a+)+ to prohibit duplicate arcs */
LOGICAL samelabelarc(a, s)
ARC *a ;
STATE *s ;
{
ARC *b ;
for (b = s->first ; b ; b = b->next)
if (b->id == a->id) return(TRUE) ;
return(FALSE) ;
}
/* Saves the name of an element appearing on the left-hand side of a
grammar rule */
#if defined(M_PROTO)
void savelhs(LOGICAL param)
#else
void savelhs(param)
LOGICAL param ;
#endif
{
STATE *end ;
ELTSTRUCT *errelt ;
ELTSTRUCT *thiselt ;
*nextlhs = (LHS *) m_malloc(sizeof(LHS), "lhs") ;
(*nextlhs)->next = NULL ;
thiselt = ntrelt(name) ;
(*nextlhs)->elt = thiselt ;
nextlhs = &(*nextlhs)->next ;
if (! startstate) {
startstate = getstate() ;
end = getstate() ;
addarc(startstate, end, thiselt, M_NULLVAL, FALSE, 1, FALSE, &errelt) ;
end->final = TRUE ;
}
if (param && thiselt->parptr) {
m_err1("Parameters for %s already defined", thiselt->enptr) ;
return ;
}
if (! param && thiselt->model)
warning1("Duplicate model for element %s", thiselt->enptr) ;
}
/* Called when arcs are added to the start state of a submodel that is
also a start state of the parent model to set the parent model's
starta list */
void savestartarcs(M_NOPAR)
{
ARC *carcptr, *parcptr ;
for (carcptr = top->starta ; carcptr ; carcptr = carcptr->next) {
parcptr = (ARC *) m_malloc(sizeof(ARC), "arc") ;
parcptr->label = carcptr->label ;
parcptr->optional = carcptr->optional ;
parcptr->minim = carcptr->minim ;
parcptr->group = carcptr->group ;
parcptr->to = carcptr->to ;
parcptr->next = top->oldtop->starta ;
parcptr->id = carcptr->id ;
top->oldtop->starta = parcptr ;
}
}
/* Simplebranch adds a new state and transition to it in an FSA when a
submodel consists of a single element or of an and group */
void simplebranch(root, value, group, optional)
TREE *root ;
ELTSTRUCT *value ;
ANDGROUP *group ;
int optional ;
{
STATE *new = NULL ;
STATELIST *index ;
int c ;
ELTSTRUCT *errelt ;
/* Check for ambiguity between an arc to be added and arcs from final
states of and-groups that terminate at the start state of the new
arc */
for (index = top->allfinal ; index ; index = index->next)
if (c = checkdfsa(index->value, value, group, root->eltid, &errelt))
nondeterm(root, c, errelt) ;
for (index = top->starts ; index ; index = index->next) {
if (! group && ! value && index->value->frompcdata)
continue ;
if (! new) {
new = getstate() ;
new->frompcdata = (LOGICAL) (! group && ! value) ;
}
c = addarc(index->value, new, value, group,
(LOGICAL) (optional > index->level),
root->eltid, root->minim, &errelt) ;
if (c) nondeterm(root, c, errelt) ;
if (! group && ! value) index->value->datacontent = TRUE ;
}
if (new) {
top->finals = (STATELIST *) m_malloc(sizeof(STATELIST), "state list") ;
top->finals->value = new ;
top->finals->level = stacklevels ;
top->finals->next = NULL ;
top->starta = (ARC *) m_malloc(sizeof(ARC), "arc") ;
top->starta->label = value ;
top->starta->optional = FALSE ;
top->starta->minim = root->minim ;
top->starta->group = group ;
top->starta->to = new ;
top->starta->next = NULL ;
top->starta->id = root->eltid ;
}
else copyintolist(top->starts, &top->finals) ;
}
/* Startfsa creates a new FSA. It is called once for each content model and
once for each and group. Its parameters are the root of the
subtree in the tree representing the grammar rule being processed and
the pointer to a flag that is set to indicate whether or not the
submodel can be null. */
STATE *startfsa(root, canbenull)
TREE *root ;
LOGICAL *canbenull ;
{
STATELIST *item ;
STATE *first ;
top->starts = (STATELIST *) m_malloc(sizeof(STATELIST), "state list") ;
first = getstate() ;
top->starts->value = first ;
top->starts->level = stacklevels ;
top->starts->next = NULL ;
*canbenull = makefsa(root, FALSE) ;
for (item = top->finals ; item ; item = item->next)
item->value->final = TRUE ;
dellist(&top->starts) ;
delstartarcs() ;
return(first) ;
}

View File

@@ -0,0 +1,653 @@
/* $XConsortium: out.c /main/3 1995/11/08 10:43:06 rswiston $ */
/*
Copyright 1986 Tandem Computers Incorporated.
This product and information is proprietary of Tandem Computers Incorporated.
Copyright (c) 1986, 1987, 1988, 1989 Hewlett-Packard Co.
*/
/* Out.c contains the procedures used by program BUILD to output results */
#include <string.h>
#include <malloc.h>
#if defined(MSDOS)
#include <process.h>
#endif
#include "context.h"
#include "build.h"
#include "delim.h"
#include "entdef.h"
#define boolean(x) x ? "TRUE" : "FALSE"
/* Macro names written to dtd.h */
char many[] = "M_ANY" ;
char mcdata[] = "M_CDATA" ;
char mcdataent[] = "CDATAENT" ;
char mcdata_att[] = "M_CDATT" ;
char mcurrent[] = "M_CURRENT" ;
char mentatt[] = "M_ENTATT" ;
char merror[] = "M_ERROR" ;
char mgeneral[] = "" ;
char midrefs[] = "M_IDRFS" ;
char midref[] = "M_IDRF" ;
char mid[] = "M_ID" ;
char mkeyword[] = "M_KEYWORD" ;
char mnamedef[] = "M_NAMEDEF" ;
char mnamepar[] = "M_NAMEPAR" ;
char mnames[] = "M_NAMES" ;
char mnmtkns[] = "M_NMSTOKEN" ;
char mnmtoken[] = "M_NMTOKEN" ;
char mnone[] = "M_NONE" ;
char mnulldef[] = "M_NULLDEF" ;
char mnumbers[] = "M_NUMS" ;
char mnumber[] = "M_NUMBER" ;
char mnutkns[] = "M_NUSTOKEN" ;
char mnutoken[] = "M_NUTOKEN" ;
char mrcdata[] = "M_RCDATA" ;
char mregexp[] = "M_REGEXP" ;
char mrequired[] = "M_REQUIRED" ;
/* Deftype returns a string indicating the default type of the nth parameter.
*/
char *deftype(n)
int n ;
{
switch (n) {
case NAME: return(mnamedef) ;
case CURRENT: return(mcurrent) ;
case REQUIRED: return(mrequired) ;
case NULLDEF: return(mnulldef) ;
default:
errexit = ERREXIT ;
return(merror) ;
}
}
/* Called after all input is read to generate output */
void done(M_NOPAR)
{
if (! eltree.data) {
warning("Error: no elements specified") ;
return ;
}
eltreeout() ;
parout() ;
srefout() ;
entout("entity") ;
fsa() ;
exout() ;
template() ;
}
/* Prints data value of an entry in the element name tree */
void dumpentnode(file, value)
FILE *file ;
M_TRIE *value ;
{
fprintf(file, ", %d", ((ELTSTRUCT *) value)->eltno) ;
}
/* Prints data value of an entry in the trie of short reference map names,
reporting any maps that are referenced but not defined */
void dumpmapnode(file, value)
FILE *file ;
M_TRIE *value ;
{
fprintf(file, ", %d", ((MAP *) value)->map) ;
if (! ((MAP *) value)->defined)
warning1("Short reference map \"%s\" referenced but not defined.",
((MAP *) value)->mapname) ;
}
/* Prints data value of an entry in the trie of short reference delimiters */
void dumpsrefnode(file, value)
FILE *file ;
M_TRIE *value ;
{
fprintf(file, ", %d", ((SREFSTRUCT *) value)->srefcnt) ;
}
/* Controls printing of element blocks in alphabetical order to the
template file */
void eltblocks(tempfile)
FILE *tempfile ;
{
int n ;
M_TRIE *node[M_NAMELEN + 1] ;
M_TRIE *current ;
char symbol ;
n = 0 ;
current = eltree.data ;
while (TRUE) {
symbol = current->symbol ;
node[n] = current->next ;
if (! symbol) {
tempelt((ELTSTRUCT *) current->data, tempfile) ;
current = current->next ;
while (! current) {
n-- ;
if (n < 0) return ;
current = node[n] ;
}
}
else {
current = current->data ;
n++ ;
}
}
}
/* Writes data about elements */
void eltreeout(M_NOPAR)
{
M_WCHAR *p ;
int enameindex = 0 ;
ELTSTRUCT *eltp ;
LOGICAL first ;
m_openchk(&dtd, "dtd.h", "w") ;
fputs("#if defined(M_DTDDEF)\n", dtd) ;
fputs("#define M_DTDEXTERN\n", dtd) ;
fputs("#define M_DTDINIT(a) = a\n", dtd) ;
fputs("#else\n", dtd) ;
fputs("#define M_DTDEXTERN extern\n", dtd) ;
fputs("#define M_DTDINIT(a)\n", dtd) ;
fputs("#endif\n\n", dtd) ;
fputs("#include \"dtddef.h\"\n\n", dtd) ;
dumpptrie(&eltree, "m_entree", dtd, "M_DTDEXTERN", "M_DTDDEF",
dumpentnode) ;
fprintf(dtd, "M_DTDEXTERN M_WCHAR m_ename[%d]\n", enamelen) ;
fputs("#if defined(M_DTDDEF)\n = {\n", dtd) ;
first = TRUE ;
for (eltp = firstelt ; eltp ; eltp = eltp->next) {
if (first) first = FALSE ;
else fputs(",\n", dtd) ;
for (p = eltp->enptr ; *p ; p++)
fprintf(dtd, " %d,\n", *p) ;
fputs(" 0", dtd) ;
}
fputs(ndif, dtd) ;
fprintf(dtd, "M_DTDEXTERN int m_elcount M_DTDINIT(%d) ;\n", ecount) ;
fprintf(dtd,
"M_DTDEXTERN M_ELTSTRUCT m_element[%d]\n#if defined(M_DTDDEF)\n = {\n",
ecount) ;
first = TRUE ;
for (eltp = firstelt ; eltp ; eltp = eltp->next) {
if (first) first = FALSE ;
else fputs(",\n", dtd) ;
if (! eltp->content)
warning1("No content model for element %s", eltp->enptr) ;
fprintf(dtd, " %d, %d, %s, ",
enameindex, eltp->model ? eltp->model->count : 0,
typecon(eltp->content)) ;
fprintf(dtd, "%d, %d, ", eltp->inptr, eltp->exptr) ;
fprintf(dtd, "%d, %d, %d",
eltp->parindex, eltp->paramcount, eltp->srefptr) ;
enameindex += w_strlen(eltp->enptr) + 1 ;
fprintf(dtd, ", %s, %s, %s",
boolean(eltp->stmin), boolean(eltp->etmin), boolean(eltp->useoradd)) ;
}
fputs(ndif, dtd) ;
}
/* Enttype returns a string indicating the type of an entity */
char *enttype(n)
int n ;
{
switch(n) {
case M_GENERAL: return(mgeneral) ;
case M_SYSTEM: return(entsystem) ;
case M_STARTTAG: return(entst) ;
case M_ENDTAG: return(entet) ;
case M_MD: return(entmd) ;
case M_PI: return(entpi) ;
case M_CDATAENT: return(cdata) ;
case M_SDATA: return(entsdata) ;
default:
errexit = ERREXIT ;
return(merror) ;
}
}
/* Outputs exception lists */
void exout(M_NOPAR)
{
EXCEPTION *ex ;
int exindex = 0 ;
LOGICAL first = TRUE ;
fputs("M_DTDEXTERN M_EXCEPTION m_exception", dtd) ;
if (excount) {
fprintf(dtd,
"[%d]\n#if defined(M_DTDDEF)\n = {\n",
excount) ;
for (ex = firstex ; ex ; ex = ex->nextptr) {
if (! first) fputs(",\n", dtd) ;
first = FALSE ;
exindex++ ;
fprintf(dtd, " %d, %d", ex->element, ex->next ? exindex + 1 : 0) ;
}
fputs(ndif, dtd) ;
}
SUBONE
}
/* Outputs FSA definitions */
void fsa(M_NOPAR)
{
int arcount = 0 ;
STATE *pstate ;
FILE *farc ;
LOGICAL first ;
ANDGROUP *pand ;
ARC *parc ;
m_openchk(&farc, "arc.h", "w") ;
fprintf(dtd,
"M_DTDEXTERN M_STATESTRUCT m_state[%d]\n#if defined(M_DTDDEF)\n = {\n",
stateused) ;
for (pstate = firststate ; pstate ; pstate = pstate->next)
for (parc = pstate->first ; parc ; parc = parc->next)
++arcount ;
fprintf(farc,
"M_DTDEXTERN M_ARCSTRUCT m_arc[%d]\n#if defined(M_DTDDEF)\n = {\n",
arcount) ;
arcount = 0 ;
first = TRUE ;
for (pstate = firststate ; pstate ; pstate = pstate->next) {
if (first) first = FALSE ;
else fputs(",\n", dtd) ;
fprintf(dtd, " %s, %s, %d",
boolean(pstate->final), boolean(pstate->datacontent),
pstate->first ? ++arcount : 0) ;
for (parc = pstate->first ; parc ; parc = parc->next) {
if (arcount > 1) fputs(",\n", farc) ;
fprintf(farc, " %d, %s, %d, %d, %d, %d",
parc->label ? parc->label->eltno : 0,
boolean(parc->optional),
parc->minim ? parc->id : 0,
parc->group ? parc->group->count : 0,
parc->to->count,
parc->next ? ++arcount : 0
) ;
}
}
fputs(ndif, dtd) ;
fputs(ndif, farc) ;
fputs("M_DTDEXTERN M_ANDSTRUCT m_andgroup", dtd) ;
if (andused) {
fprintf(dtd, "[%d]\n#if defined(M_DTDDEF)\n = {\n", andused) ;
first = TRUE ;
for (pand = firstand ; pand ; pand = pand->nextptr) {
if (first) first = FALSE ;
else fputs(",\n", dtd) ;
fprintf(dtd, " %d, %d",
pand->start->count,
pand->next ? pand->next->count : M_NULLVAL) ;
}
fputs(ndif, dtd) ;
}
SUBONE
fclose(farc) ;
}
/* Writes data about parameters */
void parout(M_NOPAR)
{
PARAMETER *paramp ;
LOGICAL first = TRUE ;
int pnameindex = 0 ;
M_WCHAR *p ;
int kw ;
int defindex = 0 ;
PTYPE *ptypep ;
fputs("M_DTDEXTERN M_WCHAR m_keyword", dtd) ;
if (kwlen)
{
fprintf(dtd,
"[%d]\n#if defined(M_DTDDEF)\n = {\n", /* keep the "}" balanced */
kwlen) ;
first = TRUE ;
for (ptypep = firstptype ; ptypep ; ptypep = ptypep->nextptr)
{
if (first) first = FALSE ;
else fputs(",\n", dtd) ;
for (p = ptypep->keyword ; *p ; p++)
fprintf(dtd, " %d,\n", *p) ;
fputs(" 0", dtd) ;
}
fputs(ndif, dtd) ;
}
SUBONE
fputs("M_DTDEXTERN M_WCHAR m_defval", dtd) ;
if (deflen)
{
fprintf(dtd,
"[%d]\n#if defined(M_DTDDEF)\n = {\n", /* keep the "}" balanced */
deflen) ;
first = TRUE ;
for (paramp = firstpar ; paramp ; paramp = paramp->nextptr)
if (paramp->defstring)
{
if (first) first = FALSE ;
else fputs(",\n", dtd) ;
for (p = paramp->defstring ; *p ; p++)
fprintf(dtd, " %d,\n", *p) ;
fputs(" 0", dtd) ;
}
fputs(ndif, dtd) ;
}
SUBONE
fputs(
"M_DTDEXTERN struct {\n int keyword, next ;\n } m_ptype",
dtd) ;
if (ptypelen)
{
fprintf(dtd, "[%d]\n#if defined(M_DTDDEF)\n = {\n", ptypelen) ;
/* keep the "}" balanced */
kw = 0 ;
first = TRUE ;
for (ptypep = firstptype ; ptypep ; ptypep = ptypep->nextptr)
{
if (first) first = FALSE ;
else fprintf(dtd, ",\n") ;
fprintf(dtd, " %d, %d", kw, ptypep->next) ;
kw += w_strlen(ptypep->keyword) + 1 ;
}
fputs(ndif, dtd) ;
}
SUBONE
fputs("M_DTDEXTERN M_PARAMETER m_parameter", dtd) ;
if (parcount)
{
kw = 0 ;
fprintf(dtd,
"[%d]\n#if defined(M_DTDDEF)\n = {\n", /* keep the "}" balanced */
parcount) ;
first = TRUE ;
for (paramp = firstpar ; paramp ; paramp = paramp->nextptr)
{
if (first) first = FALSE ;
else fputs(",\n", dtd) ;
fprintf(dtd,
" %d, %s, %d, %s, ",
pnameindex,
partype(paramp->type),
paramp->kwlist,
deftype(paramp->deftype) );
pnameindex += w_strlen(paramp->paramname) + 1 ;
if (paramp->defval)
fprintf(dtd, "&m_keyword[%d]", paramp->defval - 1) ;
else if (paramp->defstring)
{
fprintf(dtd, "&m_defval[%d]", defindex) ;
defindex += w_strlen(paramp->defstring) + 1 ;
}
else
fputs("NULL", dtd) ;
}
fputs(ndif, dtd) ;
}
SUBONE
fputs("M_DTDEXTERN M_WCHAR m_pname", dtd) ;
if (pnamelen)
{
fprintf(dtd,
"[%d]\n#if defined(M_DTDDEF)\n = {\n", /* keep the "}" balanced */
pnamelen) ;
first = TRUE ;
for (paramp = firstpar ; paramp ; paramp = paramp->nextptr)
{
if (first) first = FALSE ;
else fputs(",\n", dtd) ;
for (p = paramp->paramname ; *p ; p++) fprintf(dtd, " %d,\n", *p) ;
fputs(" 0", dtd) ;
}
fputs(ndif, dtd) ;
}
SUBONE
fprintf(dtd, "#define M_MAXPAR %d\n\n", maxpar) ;
}
/* Partype returns a string indicating the type of the nth parameter. */
char *partype(n)
int n ;
{
switch(n) {
case GRPO: return(mkeyword) ;
case CDATA: return(mcdata_att) ;
case ID: return(mid) ;
case IDREF: return(midref) ;
case IDREFS: return(midrefs) ;
case NAMETYPE: return(mnamepar) ;
case NAMES: return(mnames) ;
case NMTOKEN: return(mnmtoken) ;
case NMTOKENS: return(mnmtkns) ;
case NUMBER: return(mnumber) ;
case NUMBERS: return(mnumbers) ;
case NUTOKEN: return(mnutoken) ;
case NUTOKENS: return(mnutkns) ;
case ENTATT: return(mentatt) ;
default:
errexit = ERREXIT ;
return(merror) ;
}
}
/* Write short reference information */
void srefout(M_NOPAR)
{
LOGICAL first = TRUE ;
int *mapbysref ;
SREFSTRUCT *srefp ;
SREFDATA *data ;
int count = 0 ;
int thisrow ;
int i, j ;
fprintf(dtd, "#define M_MAXSR %d\n", maxsr) ;
fprintf(dtd, "#define M_MAXSEQ %d\n", maxseq) ;
fprintf(dtd, "#define M_SREFCNT %d\n", sreflen) ;
dumpptrie(&maptree, "m_maptree", dtd, "M_DTDEXTERN", "M_DTDDEF",
dumpmapnode) ;
dumpptrie(&sreftree, "m_sreftree", dtd, "M_DTDEXTERN", "M_DTDDEF",
dumpsrefnode) ;
fputs("M_DTDEXTERN int m_map", dtd) ;
if (mapcnt) {
mapbysref = (int *) calloc(mapcnt * sreflen, sizeof(int)) ;
if (! mapbysref) {
m_error("Unable to allocate workspace to process short references") ;
exit(TRUE) ;
}
for (srefp = firstsref ; srefp ; srefp = srefp->next)
for (data = srefp->data ; data ; data = data->next)
if (data->entidx)
mapbysref[sreflen * (data->map - 1) + srefp->srefcnt - 1] =
data->entidx ;
fprintf(dtd, "[%d]\n#if defined(M_DTDDEF)\n = {\n", mapcnt) ;
for (i = 0 ; i < mapcnt ; i++) {
if (i) fputs(",\n", dtd) ;
thisrow = 0 ;
for (j = 0 ; j < sreflen ; j++)
if (mapbysref[sreflen * i + j]) thisrow++ ;
fprintf(dtd, " %d", thisrow ? count + 1 : M_NULLVAL) ;
count += thisrow ;
}
fputs(ndif, dtd) ;
}
SUBONE
fputs(
"M_DTDEXTERN M_SREF m_sref", dtd) ;
if (count) {
fprintf(dtd, "[%d]\n#if defined(M_DTDDEF)\n = {\n", count) ;
first = TRUE ;
count = 0 ;
for (i = 0 ; i < mapcnt ; i++)
for (j = 0 ; j < sreflen ; )
if (mapbysref[sreflen * i + j]) {
count++ ;
if (first) first = FALSE ;
else fputs(",\n", dtd) ;
fprintf(dtd, " %d, %d, ", j + 1, mapbysref[sreflen * i + j]) ;
for (j++ ; j < sreflen ; j++)
if (mapbysref[sreflen * i + j]) break ;
fprintf(dtd, "%d", j < sreflen ? count + 1 : 0) ;
}
else j++ ;
fputs(ndif, dtd) ;
}
SUBONE
}
/* Output one element block in a template */
void tempelt(eltp, tempfile)
ELTSTRUCT *eltp ;
FILE *tempfile ;
{
PARAMETER *paramp ;
PTYPE *ptypep ;
M_WCHAR *p ;
char *mb_paramname;
int indent ;
int i ;
char *mb_enptr;
mb_enptr = MakeMByteString(eltp->enptr);
fprintf(tempfile, "\n<ELEMENT %s>\n", mb_enptr) ;
m_free(mb_enptr, "Multi-byte string");
if (eltp->parptr)
{
fputs(" /*\n", tempfile) ;
fputs(" <PARAM>\n", tempfile) ;
for (paramp = eltp->parptr ; paramp ; paramp = paramp->next)
{
fputs(" ", tempfile) ;
indent = 9 ;
for (p = paramp->paramname ; *p ; p++, indent += 2)
{
int length;
char mbyte[32]; /* larger than any multibyte character */
char *pc, c;
length = wctomb(mbyte, *p);
if (length < 0)
m_error("Invalid multibyte character found in an element");
else
{
pc = mbyte;
if (length == 1)
{
c = *pc;
putc(isupper(c) ? tolower(c) : c, tempfile) ;
}
else
while (--length >= 0) putc(*pc++, tempfile) ;
}
}
mb_paramname = MakeMByteString(paramp->paramname);
fprintf(tempfile, " = %s ", mb_paramname) ;
m_free(mb_paramname,"multi-byte string");
if (paramp->type == GRPO)
{
putc('(', tempfile) ;
for (ptypep = paramp->ptypep ; ptypep ; )
{
char *mb_keyword;
mb_keyword = MakeMByteString(ptypep->keyword);
fprintf(tempfile,
"%s = %s",
mb_keyword,
mb_keyword) ;
m_free(mb_keyword,"multi-byte string");
ptypep = ptypep->next ? ptypep->nextptr : (PTYPE *) NULL ;
if (ptypep)
{
fputs(",\n", tempfile) ;
for (i = 0 ; i < indent ; i++) putc(' ', tempfile) ;
}
}
putc(')', tempfile) ;
}
fputs(" ;\n", tempfile) ;
}
fputs(" */\n", tempfile) ;
}
fputs(" /*<STRING-CODE>*/\n", tempfile) ;
fputs(" <START-CODE>\n", tempfile) ;
fputs(" <START-STRING><\\START-STRING>\n", tempfile) ;
fputs(" /*<TEXT-CODE>*/\n", tempfile) ;
fputs(" /*<PI-CODE>*/\n", tempfile) ;
fputs(" <END-CODE>\n", tempfile) ;
fputs(" <END-STRING><\\END-STRING>\n", tempfile) ;
}
/* Write template */
void template(M_NOPAR)
{
FILE *tempfile ;
M_ENTITY *ent ;
LOGICAL undefent = FALSE ;
char *mb_name;
m_openchk(&tempfile, "template", "w") ;
for (ent = firstent ; ent ; ent = ent->next) {
if (! ent->wheredef) {
if (! undefent) {
fputs("/*\n", tempfile) ;
undefent = TRUE ;
}
mb_name = MakeMByteString(ent->name);
fprintf(tempfile, "<!ENTITY %s %s \"\">\n", mb_name, ent->type) ;
m_free(mb_name, "wide character ent->name");
}
}
if (undefent) fputs("*/\n", tempfile) ;
fputs("<SIGN-ON>\n", tempfile) ;
fputs("<GLOBAL-DEFINE>\n<GLOBAL-DECLARE>\n\n", tempfile) ;
eltblocks(tempfile) ;
fclose(tempfile) ;
}
/* Typecon returns a string indicating the content type of the nth element.*/
char *typecon(n)
int n ;
{
switch(n) {
case GRPO: return(mregexp) ;
case ANY: return(many) ;
case NONE: return(mnone) ;
case CDATA: return(mcdata) ;
case RCDATA: return(mrcdata) ;
default:
errexit = ERREXIT ;
return(merror) ;
}
}
#include "entout.c"

View File

@@ -0,0 +1,322 @@
/* $XConsortium: param.c /main/3 1995/11/08 10:43:22 rswiston $ */
/*
Copyright 1986 Tandem Computers Incorporated.
This product and information is proprietary of Tandem Computers Incorporated.
Copyright (c) 1986, 1987, 1988, 1989 Hewlett-Packard Co.
*/
/* Param.c contains procedures related to parameters for program BUILD */
#include <malloc.h>
#include <string.h>
#include "build.h"
#include "context.h"
#include "delim.h"
/* Add a keyword to the list of possible values of a keyword parameter for
the current element
*/
void addkeyword(M_NOPAR)
{
int length ;
PARAMETER *par ;
PTYPE *kw ;
/* Check if duplicate keyword for this parameter */
for (kw = newpar->ptypep ; kw ; kw = kw->nextptr)
if (w_strcmp(kw->keyword, name) == 0)
{
warning3("Warning: Repeated keyword %s in parameter %s of %s",
name,
newpar->paramname,
thisrule) ;
return ;
}
/* Check if duplicate keyword within parameters of this element */
for (par = plist ; par != newpar ; par = par->next)
for (kw = par->ptypep ; kw ; kw = kw->nextptr)
{
if (w_strcmp(kw->keyword, name) == 0)
warning4("Keyword %s used in parameters %s and %s of %s",
name,
par->paramname,
newpar->paramname,
thisrule) ;
if (! kw->next) break ;
}
*nextptype = (PTYPE *) m_malloc(sizeof(PTYPE), "ptype") ;
if (newpar->kwlist) thisptype->next = ptypelen + 1 ;
else
{
newpar->kwlist = ptypelen + 1 ;
newpar->ptypep = *nextptype ;
}
thisptype = *nextptype ;
thisptype->next = M_NULLVAL ;
thisptype->nextptr = NULL ;
nextptype = &(thisptype->nextptr) ;
length = w_strlen(name) + 1 ;
thisptype->keyword = (M_WCHAR *) m_malloc(length, "keyword") ;
w_strcpy(thisptype->keyword, name) ;
kwlen += length ;
ptypelen++ ;
}
/* Add a parameter to the current element */
void addpar(M_NOPAR)
{
PARAMETER *paramp, *last ;
int length ;
parcount++ ;
pcount++ ;
for (paramp = plist ; paramp ; paramp = paramp->next)
{
if (w_strcmp(name, paramp->paramname) == 0)
warning2("Multiple definition of parameter %s for element %s",
name,
thisrule) ;
last = paramp ;
}
newpar = (PARAMETER *) m_malloc(sizeof(PARAMETER), "parameter") ;
if (! plist)
plist = newpar ;
else
last->next = newpar ;
*nextpar = newpar ;
nextpar = &newpar->nextptr ;
*nextpar = NULL ;
newpar->next = NULL ;
newpar->deftype = NULLDEF ;
newpar->defval = M_NULLVAL ;
newpar->defstring = NULL ;
newpar->kwlist = M_NULLVAL ;
length = w_strlen(name) + 1 ;
pnamelen += length ;
newpar->paramname = (M_WCHAR *) m_malloc(length, "parameter name") ;
w_strcpy(newpar->paramname, name) ;
newpar->ptypep = NULL ;
}
/* Check that specified default value is legal parameter value */
#if defined(M_PROTO)
LOGICAL checkdefault( const M_WCHAR *string )
#else
LOGICAL checkdefault(string)
M_WCHAR *string ;
#endif /* M_PROTO */
{
const M_WCHAR *p ;
int len ;
LOGICAL first ;
if (newpar->type == CDATA) return(TRUE) ;
if (m_allwhite(string)) return(FALSE) ;
first = TRUE ;
switch (newpar->type)
{
case IDREF:
case NAMETYPE:
case ENTATT:
case NMTOKEN:
case NUMBER:
case NUTOKEN:
/* Check length of default */
if (w_strlen(string) > M_NAMELEN) return(FALSE) ;
for (p = string ; *p ; p++)
{
if (m_cttype(*p) == M_NONNAME) return(FALSE) ;
else if (first || newpar->type == NUMBER)
switch (newpar->type)
{
case IDREF:
case NAMETYPE:
case ENTATT:
if (m_cttype(*p) != M_NMSTART) return(FALSE) ;
break ;
case NUMBER:
case NUTOKEN:
if (m_cttype(*p) != M_DIGIT) return(FALSE) ;
break ;
}
first = FALSE ;
}
return(TRUE) ;
case IDREFS:
case NAMES:
case NMTOKENS:
case NUMBERS:
case NUTOKENS:
len = 1 ;
for (p = string ; *p ; p++)
{
if (m_cttype(*p) == M_NONNAME)
{
if (! m_whitespace(*p)) return(FALSE) ;
len = 1 ;
}
else if (len == 1)
switch (newpar->type)
{
case IDREFS:
case NAMES:
if (m_cttype(*p) != M_NMSTART) return(FALSE) ;
break ;
case NUMBERS:
case NUTOKENS:
if (m_cttype(*p) != M_DIGIT) return(FALSE) ;
break ;
}
else if (newpar->type == NUMBERS &&
m_cttype(*p) != M_DIGIT) return(FALSE) ;
if (len++ > M_NAMELEN) return(FALSE) ;
}
break ;
}
}
/* Normalize parameter default. Change tabs and RE's to spaces, capitalize
all letters (unless type is CDATA), remove extra space in lists */
#if defined(M_PROTO)
void normdefault(M_WCHAR *string )
#else
void normdefault(string)
M_WCHAR *string ;
#endif /* M_PROTO */
{
M_WCHAR *p, *q ;
int i ;
switch (newpar->type)
{
case IDREF:
case NAMETYPE:
case NMTOKEN:
case NUTOKEN:
case ENTATT:
for ( ; *string ; string++)
*string = m_ctupper(*string) ;
return ;
case IDREFS:
case NAMES:
case NMTOKENS:
case NUTOKENS:
case NUMBERS:
/* Remove leading spaces */
for (p = string; *p ; p++)
if (! m_whitespace(*p)) break ;
w_strcpy(string, p) ;
/* Capitalize and normalize white space */
for (p = string, i = 0 ; *p ; p++, i++)
if (m_whitespace(*p))
{
mbtowc(p, " ", 1);
for (q = p + 1 ; m_whitespace(*q); q++) ;
w_strcpy(p + 1, q) ;
}
else
*p = m_ctupper(*p) ;
if (i && m_whitespace(string[i - 1])) string[i - 1] = M_EOS ;
return ;
default:
for ( ; *string ; string++)
{
char mbyte[32]; /* bigger than the biggest multibyte char */
int length;
length = wctomb(mbyte, *string);
if (length < 0)
{
m_error("Invalid wide character seen");
mbyte[0] = ' ';
mbyte[1] = 0;
}
if ((length == 1) && (*mbyte == '\n' || *mbyte == '\t'))
mbtowc(string, " ", 1);
}
return ;
}
}
/* Called at end of parameter attribute list rule */
void prulend(M_NOPAR)
{
LHS *lhsp ;
LHS *discard ;
if (pcount > maxpar) maxpar = pcount ;
for (lhsp = lhs ; lhsp ; )
{
if (lhsp->elt->parptr)
m_err1(
"Program error: prulend for %s, element with predefined parameters",
lhsp->elt->enptr) ;
lhsp->elt->parptr = plist ;
lhsp->elt->paramcount = pcount ;
lhsp->elt->parindex = parcount - pcount + 1 ;
discard = lhsp ;
lhsp = lhsp->next ;
m_free((M_POINTER) discard, "lhs") ;
}
ruleinit() ;
}
/* Make string the default for the current parameter of the current element */
#if defined(M_PROTO)
void setdefault(const M_WCHAR *string)
#else
void setdefault()
M_WCHAR *string;
#endif /* M_PROTO */
{
PTYPE *kw ;
int keycount ;
int length ;
/* Process default for non-keyword parameter*/
if (newpar->type != GRPO)
{
/* First check it is a legitimate value */
if (! checkdefault(string))
{
m_err2("\"%s\": Not a valid default value for parameter %s",
string,
newpar->paramname) ;
return ;
}
length = w_strlen(string) + 1 ;
newpar->defstring = (M_WCHAR *) m_malloc(length, "default") ;
w_strcpy(newpar->defstring, string) ;
deflen += length ;
/* Value is valid. Change tabs and RE's to spaces, if value is not
CDATA, put it in all caps, remove extra white space. */
normdefault(newpar->defstring) ;
}
else
{
/* It is a keyword parameter, store a pointer to the value */
for (kw = newpar->ptypep ; kw ; kw = kw->nextptr)
{
if (! m_wcupstrcmp(string, kw->keyword))
{
for (keycount = 0 ; kw ; kw = kw->nextptr)
keycount += w_strlen(kw->keyword) + 1 ;
newpar->defval = kwlen - keycount + 1;
return ;
}
}
m_err2("Invalid default: %s not a valid value for %s",
string,
newpar->paramname) ;
}
}

View File

@@ -0,0 +1,592 @@
/* $XConsortium: proto.h /main/3 1995/11/08 10:43:37 rswiston $ */
/*
Copyright (c) 1988, 1989 Hewlett-Packard Co.
*/
/* Proto.h contains function prototypes for program BUILD. */
int addarc(
#if defined(M_PROTO)
STATE *from, STATE *to, ELTSTRUCT *label, ANDGROUP *and, LOGICAL optional,
int id, LOGICAL minim, ELTSTRUCT **errelt
#endif
) ;
void adddefent(
#if defined(M_PROTO)
M_WCHAR *mapname
#endif
) ;
LOGICAL addent(
#if defined(M_PROTO)
M_WCHAR *name
#endif
) ;
void addex(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
void addkeyword(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
LOGICAL addmapname(
#if defined(M_PROTO)
M_WCHAR *p, LOGICAL define
#endif
) ;
void addndent(
#if defined(M_PROTO)
M_WCHAR *p
#endif
) ;
void addpar(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
void addsref(
#if defined(M_PROTO)
M_WCHAR *p
#endif
) ;
LOGICAL m_allwhite(
#if defined(M_PROTO)
const M_WCHAR *string
#endif
) ;
void checkand(
#if defined(M_PROTO)
ANDGROUP *andstart, ANDGROUP *andptr, STATE *start, TREE *root,
ELTSTRUCT **errelt
#endif
) ;
LOGICAL checkdefault(
#if defined(M_PROTO)
const M_WCHAR *string
#endif
) ;
int checkdfsa(
#if defined(M_PROTO)
STATE *from, ELTSTRUCT *label, ANDGROUP *and, int id, ELTSTRUCT **errelt
#endif
) ;
int checkrepeat(
#if defined(M_PROTO)
STATE *from, ANDGROUP *and, ELTSTRUCT **errelt
#endif
) ;
void copyintolist(
#if defined(M_PROTO)
STATELIST *from, STATELIST **to
#endif
) ;
void countdown(
#if defined(M_PROTO)
M_TRIE *parent, int *count
#endif
) ;
void defmapname(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
char *deftype(
#if defined(M_PROTO)
int n
#endif
) ;
void dellist(
#if defined(M_PROTO)
STATELIST **list
#endif
) ;
void delstartarcs(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
void done(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
void dumpentnode(
#if defined(M_PROTO)
FILE *file, M_TRIE *value
#endif
) ;
void dumpmapnode(
#if defined(M_PROTO)
FILE *file, M_TRIE *value
#endif
) ;
void dumpsrefnode(
#if defined(M_PROTO)
FILE *file,
M_TRIE *value
#endif
) ;
void dumpptrie(
#if defined(M_PROTO)
M_TRIE *intname, char *extname, FILE *file, char *externdef, char *defdef,
void (*proc)( FILE *, M_TRIE *)
#endif
) ;
void m_dumptrie(
#if defined(M_PROTO)
FILE *file,
M_TRIE *xtrie,
char *extname,
int *count,
void (*proc)(M_ENTITY *)
#endif
) ;
void eltblocks(
#if defined(M_PROTO)
FILE *tempfile
#endif
) ;
void eltreeout(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
void endmodel(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
void entout(
#if defined(M_PROTO)
char *fname
#endif
) ;
char *enttype(
#if defined(M_PROTO)
int n
#endif
) ;
void m_error(
#if defined(M_PROTO)
char *text
#endif
) ;
void m_err1(
#if defined(M_PROTO)
const char *text, const M_WCHAR *arg
#endif
) ;
void m_mberr1(
#if defined(M_PROTO)
char *text, const char *arg
#endif
) ;
void m_err2(
#if defined(M_PROTO)
const char *text, const M_WCHAR *arg1, const M_WCHAR *arg2
#endif
) ;
void exout(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
void m_free(
#if defined(M_PROTO)
void *block, char *msg
#endif
) ;
void freetree(
#if defined(M_PROTO)
TREE *ruletree
#endif
) ;
void found(
#if defined(M_PROTO)
LOGICAL *flag, char *delim
#endif
) ;
void fsa(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
int getachar(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
ANDGROUP *getand(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
LOGICAL getname(
#if defined(M_PROTO)
int first
#endif
) ;
STATE *getstate(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
int gettoken(
#if defined(M_PROTO)
int *c, int context
#endif
) ;
TREE *gettreenode(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
void m_initctype(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
void initialize(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
LOGICAL litproc(
#if defined(M_PROTO)
int delim
#endif
) ;
void main(
#if defined(M_PROTO)
int argc, char **argv
#endif
) ;
void makeand(
#if defined(M_PROTO)
LOGICAL *canbenull, TREE *root, int optional
#endif
) ;
LOGICAL makefsa(
#if defined(M_PROTO)
TREE *root, int optional
#endif
) ;
void makeor(
#if defined(M_PROTO)
LOGICAL *canbenull, TREE *root
#endif
) ;
void makeseq(
#if defined(M_PROTO)
LOGICAL *canbenull, TREE *root, int optional
#endif
) ;
void *m_malloc(
#if defined(M_PROTO)
int size, char *msg
#endif
) ;
void msgline(
#if defined(M_PROTO)
char *text
#endif
) ;
void msg1line(
#if defined(M_PROTO)
char *text, char *arg1
#endif
) ;
void nondeterm(
#if defined(M_PROTO)
TREE *root, int c, ELTSTRUCT *eltp
#endif
) ;
void normdefault(
#if defined(M_PROTO)
M_WCHAR *string
#endif
) ;
LOGICAL notinlist(
#if defined(M_PROTO)
STATELIST *item, STATELIST *list
#endif
) ;
ELTSTRUCT *ntrelt(
#if defined(M_PROTO)
M_WCHAR *p
#endif
) ;
void m_openchk(
#if defined(M_PROTO)
FILE **ptr, char *name, char *mode
#endif
) ;
void parout(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
char *partype(
#if defined(M_PROTO)
int n
#endif
) ;
LOGICAL permitspcd(
#if defined(M_PROTO)
ARC *a
#endif
) ;
void pop(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
void prulend(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
void push(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
LOGICAL regenerate(
#if defined(M_PROTO)
TREE *start, TREE *stop
#endif
) ;
void repeat(
#if defined(M_PROTO)
TREE *root
#endif
) ;
void ruleinit(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
void rulend(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
LOGICAL samelabelarc(
#if defined(M_PROTO)
ARC *a, STATE *s
#endif
) ;
void savelhs(
#if defined(M_PROTO)
LOGICAL param
#endif
) ;
void savestartarcs(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
int scan(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
void setdefault(
#if defined(M_PROTO)
const M_WCHAR *string
#endif
) ;
void simplebranch(
#if defined(M_PROTO)
TREE *root, ELTSTRUCT *value, ANDGROUP *group, int optional
#endif
) ;
void skiptoend(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
int m_sprscon(
#if defined(M_PROTO)
int i, int j
#endif
) ;
void srefout(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
STATE *startfsa(
#if defined(M_PROTO)
TREE *root, LOGICAL *canbenull
#endif
) ;
void tempelt(
#if defined(M_PROTO)
ELTSTRUCT *eltp, FILE *tempfile
#endif
) ;
void template(
#if defined(M_PROTO)
M_NOPAR
#endif
) ;
char *typecon(
#if defined(M_PROTO)
int n
#endif
) ;
void undodelim(
#if defined(M_PROTO)
M_WCHAR *delim
#endif
) ;
void ungetachar(
#if defined(M_PROTO)
int c
#endif
) ;
int m_wcupstrcmp(
#if defined(M_PROTO)
const M_WCHAR *p, const M_WCHAR *q
#endif
) ;
int m_wcmbupstrcmp(
#if defined(M_PROTO)
const M_WCHAR *p, const char *q
#endif
) ;
int m_mbmbupstrcmp(
#if defined(M_PROTO)
const char *p, const char *q
#endif
) ;
void warning(
#if defined(M_PROTO)
char *text
#endif
) ;
void warning1(
#if defined(M_PROTO)
char *text, M_WCHAR *arg
#endif
) ;
void warning2(
#if defined(M_PROTO)
char *text, M_WCHAR *arg1, M_WCHAR *arg2
#endif
) ;
void warning3(
#if defined(M_PROTO)
char *text, M_WCHAR *arg1, M_WCHAR *arg2, M_WCHAR *arg3
#endif
) ;
void warning4(
#if defined(M_PROTO)
char *text, M_WCHAR *arg1, M_WCHAR *arg2, M_WCHAR *arg3, M_WCHAR *arg4
#endif
) ;
LOGICAL m_whitespace(
#if defined(M_PROTO)
M_WCHAR c
#endif
) ;

View File

@@ -0,0 +1,152 @@
/* $XConsortium: scan.c /main/3 1995/11/08 10:43:54 rswiston $ */
/*
Copyright 1986 Tandem Computers Incorporated.
This product and information is proprietary of Tandem Computers Incorporated.
Copyright (c) 1986, 1987, 1988, 1989 Hewlett-Packard Co.
*/
/* Scan.c contains scanner procedures for program BUILD */
#include <string.h>
#if defined(MSDOS)
#include <process.h>
#endif
#include "build.h"
#define M_CONDEF
#include "context.h"
#define M_DELIMDEF
#include "delim.h"
#include "sref.h"
/* Reads a name */
LOGICAL getname(first)
int first;
{
M_WCHAR *p;
int c;
*(p = name) = first;
if ((curcon != DEFAULT && curcon != DEFVAL &&
curcon != DEFAULT2 && curcon != DEF2VAL) ||
newpar->type != CDATA)
*p = m_ctupper(*p);
while (TRUE)
{
c = getachar();
*++p = (M_WCHAR) c;
if (m_cttype(*p) == M_NONNAME) break;
if (p >= name + M_NAMELEN)
{
*(name + M_NAMELEN) = M_EOS;
m_error("Name too long");
return(FALSE);
}
if ((curcon != DEFAULT && curcon != DEFVAL &&
curcon != DEFAULT2 && curcon != DEF2VAL) ||
newpar->type != CDATA)
*p = m_ctupper(*p);
}
ungetachar(c);
*p = M_EOS;
return(TRUE);
}
/* Returns the next token to the main procedure */
int scan(M_NOPAR)
{
int c;
int n;
M_WCHAR wsp, wnl, wtb;
mbtowc(&wsp, " ", 1);
mbtowc(&wnl, "\n", 1);
mbtowc(&wtb, "\t", 1);
while (TRUE)
{
if (! m_newcon(curcon - 1, TEXT - 1))
{
while ((n = gettoken(&c, COMCON)) == COMMENT)
while ((n = gettoken(&c, COMCON)) != COMMENT)
if (c == EOF)
{
m_error("EOF occurred within comment");
exit(ERREXIT);
}
ungetachar(c);
}
n = gettoken(&c, curcon);
if (n)
{
if (n != LIT && n != LITA) return(n);
if (litproc(n))
{
if (scantrace)
{
char *mb_literal;
mb_literal = MakeMByteString(literal);
printf("literal '%s'\n", mb_literal);
m_free(mb_literal, "multibyte string");
}
return(LITERAL);
}
/* Litproc returns FALSE in case of error, when returned have
scanned to the end of erroneous rule */
else continue;
}
if (c == wsp || c == wnl || c == wtb)
{
if (m_newcon(curcon - 1, TEXT - 1))
{
scanval = (M_WCHAR) c;
return(TEXT);
}
else continue;
}
if (m_newcon(curcon - 1, NAME - 1))
if (m_cttype(c) == M_NMSTART ||
(m_cttype(c) != M_NONNAME &&
(curcon == DEFAULT || curcon == DEFVAL || curcon == NTNAME ||
curcon == DEFAULT2 || curcon == DEF2VAL || curcon == NT2NAME
))
)
{
if (getname(c))
{
if (scantrace)
{
char *mb_name;
mb_name = MakeMByteString(name);
printf("name '%s'\n", mb_name);
m_free(mb_name, "multibyte string");
}
return(NAME);
}
else continue;
}
if (c == EOF) return(ENDFILE);
if (m_newcon(curcon - 1, TEXT - 1))
{
scanval = (M_WCHAR) c;
return(TEXT);
}
if (curcon != ERROR)
{
char mbyte[32]; /* bigger than the biggest multibyte char */
wctomb(mbyte, c);
fprintf(stderr, "\n'%s' (%d)", mbyte, c);
fprintf(m_errfile, "\n'%s' (%d)", mbyte, c);
m_error("Unexpected character");
}
} /* End while */
} /* End scan */
#include "scanutil.c"
#if defined(sparse)
#include "sparse.c"
#endif

View File

@@ -0,0 +1,188 @@
/* $XConsortium: sref.c /main/3 1995/11/08 10:44:07 rswiston $ */
/* Copyright (c) 1986, 1987, 1988, 1989 Hewlett-Packard Co. */
/* Sref.c contains procedures related to short reference map declarations */
#include <string.h>
#include <malloc.h>
#include "build.h"
#include "sref.h"
#include "entdef.h"
static M_WCHAR *wc_prefix = NULL;
/* Add an entity with the default name constructed by adding a suffix
to the name of the short reference map in which it is invoked, and
a prefix m- */
void adddefent(mapname)
M_WCHAR *mapname;
{
M_WCHAR *p;
int n, length;
char c;
if (!wc_prefix)
{
wc_prefix = MakeWideCharString(M_PREFIX);
w_strcpy(genname, wc_prefix);
}
w_strcpy(&genname[w_strlen(wc_prefix)], mapname);
p = &genname[w_strlen(genname)];
for (n = egensuf ; n ; n /= 10)
{
if (p - genname > M_NAMELEN)
{
m_err1("Entity name based on %s too long", mapname);
return;
}
c = ('0' + (n % 10));
mbtowc(p, &c, 1);
*p++;
}
*p = M_EOS;
egensuf++;
if (! addent(genname))
{
m_err1("Default entity name %s already in use", genname);
return;
}
thissref->entidx = entity->index;
}
/* Add an entity, return FALSE if already there, TRUE if adding it.
Pointer to the entity structure is in global M_STRUCT *entity. */
LOGICAL addent(name)
M_WCHAR *name;
{
M_ENTITY *new;
new = (M_ENTITY *) m_malloc(sizeof(M_ENTITY), "entity");
if (entity = (M_ENTITY *) m_ntrtrie(name, m_enttrie, (M_TRIE *) new))
{
m_free((M_POINTER) new, "entity");
return(FALSE);
}
entity = new;
if (lastent) lastent->next = entity;
else firstent = entity;
lastent = entity;
entity->type = M_GENERAL;
entity->wheredef = FALSE;
entity->content = NULL;
entity->name = (M_WCHAR *) m_malloc(w_strlen(name) + 1, "entity name");
entity->index = ++m_entcnt;
entity->next = NULL;
w_strcpy(entity->name, name);
return(TRUE);
}
/* Add a short reference map name */
#if defined(M_PROTO)
LOGICAL addmapname(M_WCHAR* p, LOGICAL define)
#else
LOGICAL addmapname(p, define)
M_WCHAR *p;
LOGICAL define;
#endif
{
MAP *old;
MAP *new;
LOGICAL retval;
new = (MAP *) m_malloc(sizeof(MAP), "map");
if (old = (MAP *) m_ntrtrie(p, &maptree, (M_TRIE *) new))
{
m_free(new, "map");
curmap = old->map;
retval = old->defined;
if (define) old->defined = TRUE;
return((LOGICAL) (retval ? FALSE : TRUE));
}
curmap = ++mapcnt;
new->map = mapcnt;
new->mapname = (M_WCHAR *) m_malloc(w_strlen(p) + 1, "map name");
w_strcpy(new->mapname, p);
new->defined = define;
new->nextptr = NULL;
*nextmap = new;
nextmap = &new->nextptr;
return(TRUE);
}
/* Add a named entity to a short reference map */
void addndent(p)
M_WCHAR *p;
{
addent(p);
thissref->entidx = entity->index;
}
/* Add a short reference delimiter */
void addsref(p)
M_WCHAR *p;
{
SREFSTRUCT *delim;
SREFSTRUCT *prevsr;
M_WCHAR *q;
M_WCHAR c;
int noseq = 0;
/* Define the delimiter */
delim = (SREFSTRUCT *)
m_malloc(sizeof(SREFSTRUCT), "short reference delimiter");
if (prevsr = (SREFSTRUCT *) m_ntrtrie(p, &sreftree, (M_TRIE *) delim))
{
m_free(delim, "short reference delimiter");
delim = prevsr;
}
else
{
for (q = p ; *q ; q++)
{
c = m_ctupper(*q);
if (m_cttype(c) == M_NMSTART)
{
if (c != BLANKSEQ && c != WSSEQ && c != RS)
{
m_free(delim, "short reference delimiter");
m_err1(
"Letters not permitted in short reference delimiters: %s",
p);
return;
}
if (c != RS) noseq++;
}
}
if (w_strlen(p) > maxsr) maxsr = w_strlen(p);
if (noseq > maxseq) maxseq = noseq;
delim->srefcnt = ++sreflen;
*nextsref = delim;
nextsref = &delim->next;
delim->next = NULL;
delim->data = NULL;
}
/* Add the delimiter to this map and prepare for the associated
entity */
thissref = (SREFDATA *)
m_malloc(sizeof(SREFDATA), "short reference delimiter");
thissref->map = curmap;
thissref->entidx = M_NULLVAL;
thissref->next = delim->data;
delim->data = thissref;
}
/* Prefix left-hand side with "M-" to create default short reference map
name, truncating to M_NAMELEN characters if necessary */
void defmapname(M_NOPAR)
{
if (!wc_prefix)
{
wc_prefix = MakeWideCharString(M_PREFIX);
w_strcpy(genname, wc_prefix);
}
w_strcpy(&genname[w_strlen(wc_prefix)], thisrule);
genname[M_NAMELEN] = M_EOS;
}

View File

@@ -0,0 +1,52 @@
/* $XConsortium: tree.c /main/3 1995/11/08 10:44:17 rswiston $ */
/*
Copyright 1986 Tandem Computers Incorporated.
This product and information is proprietary of Tandem Computers Incorporated.
Copyright (c) 1986, 1987, 1988, 1989 Hewlett-Packard Co.
*/
/* Tree.c has procedures used by BUILD to construct the tree representation
of a content model */
#include <malloc.h>
#include "build.h"
#include "context.h"
/* Called after a right parenthesis is read while scanning a content model.
Resets curcon if it is the outermost submodel. */
void endmodel(M_NOPAR)
{
curtree = curtree->parent ;
if (! curtree->parent) curcon = LASTM ;
else if (curtree == curtree->parent->first) curcon = OCCUR ;
}
/* Release storage used for the tree representation of a rule */
void freetree(treep)
TREE *treep ;
{
TREE *child, *discard ;
for (child = treep->first ; child ; ) {
discard = child->right ;
freetree(child) ;
child = discard ;
}
m_free((M_POINTER) treep, "tree node") ;
}
/* Gettreenode obtains a node to use in the tree representation of a rule */
TREE *gettreenode(M_NOPAR)
{
TREE *new ;
new = (TREE *) m_malloc(sizeof(TREE), "tree node") ;
new->first = new->right = new->parent = NULL ;
new->connector = new->occurrence = M_NULLVAL ;
new->value = NULL ;
new->terminal = FALSE ;
new->minim = FALSE ;
new->eltid = eltsinrule++ ;
return(new) ;
}