P_Attdef new_attdef(nm, decl_val, range, def_type, def_val)

- create a new attribute definition String nm; int decl_val; P_Group range; int def_type; String def_val;

P_Attlist new_attlist(elems)

- create a new attribute specification list P_Group elems;

new_attdef() creates a new attribute definition with all the values filled in. nm is the attribute name, decl_val is the declared value, i.e. NAME, NMTOKEN, etc (see Standard page 42-43, section 11.3.2-11.3.4). The declared value of a name token group is called ENUMERATE. For declared values NOTATION and ENUMERATE, there is a list with all the possible values, stored in range. def_type is the default type, i.e. FIXED, CURRENT, etc. If there is a default value it is contained in def_val. new_attlist() creates a new attribute specification list. elems are the associated elements.

void add_attdef(attlist, attdef)

- add an attribute definition P_Attlist attlist; P_Attdef attdef;

void store_attlist(attlist)

- add an attribute specification list P_Attlist attlist;

void attdef_delete(attdef)

- delete an attribute definition P_Attdef attdef;

String attr_var_name(name)

- return a unique attribute name String name;

add_attdef() adds, after creation of an attribute definition, this definition to the corresponding attribute specification list. store_attlist() adds the attribute specification list, after this list is filled with attribute definitions to the already existing list of attribute specifications. All the checks for unique attribute names, etc are already completed.

To delete an complete attribute definition, for instance after encounting an error, attdef_delete() is used. The allocated memory is released.

In ``gen_tags.c'' a table is generated with as entries information about the elements. For every table-entry there is also a reference to an attribute specification list. To get a unique name for every attribute specification list, attr_var_name() is called with the name of the element, a unique name is returned.

Bool attr_required(elem)

- return whether element has required attribute String elem;

Bool attr_conref(elem)

- return whether element has conref attribute String elem;

If the attribute specification list for the element elem has a required attribute, i.e. the default type is REQUIRED attr_required() returns TRUE, otherwise FALSE is returned. The same holds for attr_conref() with default type is CONREF.

Bool attr_unique(attlist, attdef)

- check attribute definition P_Attlist attlist; P_Attdef attdef;

void attr_cap_points(att, attch, avgrp, id, idref)

- calculate capacity points int *att; int *attch; int *avgrp; int *id; int *idref;

void check_attributes()

- check the attributes

An attribute definition must satisfy certain conditions. attr_unique() checks these conditions. A name in an attribute definition must be unique over its attribute specification list. There may be also at most one ID-attribute and at most one NOTATION-attribute in one attribute specification list. Also ID-attributes may not have a default value and the default type must be IMPLIED or REQUIRED. All the names in the notation list, and all the name tokens in the declared value must be unique. If one of this conditions is not satisfied, attr_unique() reports this and returns FALSE, otherwise TRUE is returned.

Capacity points are counted for attributes. This is done in attr_cap_points(). The number of IDREF and ID attributes are handled by id and idref. The number of characters in the default value is added to attch and the number of tokens in the notation list or in the declared value list are stored in avgrp. The number of attributes is added to att.

The function check_attributes() checks whether every element associated with an attribute specification list is defined, otherwise an error message is generated. If an attribute specification list contains a NOTATION attribute, and the names of the notations must be defined in a NOTATION declaration. After the DTD is read in all the defined notations are known, so the names can be checked. Futhermore a NOTATION and CONREF attribute can not have an EMPTY content, this is checked also in check_attributes().

void attr_gen_group(fp, attlist)

- generate range lists FILE *fp; P_Group attlist;

void attr_gen_attr(fp, attlist, nr)

- generate attribute specification list FILE *fp; P_Group attlist; int nr;

void attrs_generate(file_attr, file_extern)

- generate attributes String file_attr; String file_extern;

All information about attributes is put through to the document-parser. If the declared value is NOTATION or ENUMERATE, the corresponding range must be printed. This is done in attr_gen_group(). The range, as we call it, is stored in a character array with the name range., i.e. range1, range2, etc.

attr_gen_attr() generates a structure for an attribute specification list. This structure contains several attribute definitions. Each definition contains the attribute name, the declared value, the name of the range structure if there is any, otherwise zero, the default type and a default value or zero. The name of the attribute specification list is attr, i.e. attr1, attr2, etc. This name is returned by a call to attr_var_name().

attrs_generate() generates the structures for all the attribute specification lists and generates also a file with the extern definitions. This last file is needed for referring to it in the generated table on ``tags.i'' (see ``gen_tags.c''). The name of the generated files: ``att_par.i'' is the file with the attribute specifications, ``att_par.ext'' is the file with the external definitions.

void attdef_print(fp, attdef)

- print an attribute definition FILE *fp; P_Attdef attdef;

void attrs_print(fp)

- print all attributes FILE *fp;

If the debug option is specified, it is possible to print all the attributes with the associated values. Also the elements corresponding to the attribute specification list are given.

att_gen.c att_gen.h