Exemple #1
0
// Save out the generated code for a Go Table type.
static bool SaveType(const Parser &parser, const Definition &def,
                     const std::string &classcode, const std::string &path,
                     bool needs_imports) {
  if (!classcode.length()) return true;

  std::string namespace_name;
  std::string namespace_dir = path;
  auto &namespaces = parser.namespaces_.back()->components;
  for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
    if (namespace_name.length()) {
      namespace_name += ".";
      namespace_dir += PATH_SEPARATOR;
    }
    namespace_name = *it;
    namespace_dir += *it;
    mkdir(namespace_dir.c_str(), S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
  }


  std::string code = "";
  BeginFile(namespace_name, needs_imports, &code);
  code += classcode;
  std::string filename = namespace_dir + PATH_SEPARATOR + def.name + ".go";
  return SaveFile(filename.c_str(), code, false);
}
Exemple #2
0
  // Save out the generated code for a Go Table type.
  bool SaveType(const Definition &def, const std::string &classcode,
                bool needs_imports) {
    if (!classcode.length()) return true;

    std::string code = "";
    BeginFile(LastNamespacePart(*def.defined_namespace), needs_imports, &code);
    code += classcode;
    std::string filename =
        NamespaceDir(*def.defined_namespace) + def.name + ".go";
    return SaveFile(filename.c_str(), code, false);
  }
  // Save out the generated code for a Python Table type.
  bool SaveType(const Definition &def, const std::string &classcode,
                bool needs_imports) {
    if (!classcode.length()) return true;

    std::string namespace_dir = path_;
    auto &namespaces = parser_.namespaces_.back()->components;
    for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
      if (it != namespaces.begin()) namespace_dir += kPathSeparator;
      namespace_dir += *it;
      std::string init_py_filename = namespace_dir + "/__init__.py";
      SaveFile(init_py_filename.c_str(), "", false);
    }

    std::string code = "";
    BeginFile(LastNamespacePart(*def.defined_namespace), needs_imports, &code);
    code += classcode;
    std::string filename = NamespaceDir(*def.defined_namespace) +
                           def.name + ".py";
    return SaveFile(filename.c_str(), code, false);
  }
// Save out the generated code for a Go Table type.
static bool SaveType(const Parser &parser, const Definition &def,
                     const std::string &classcode, const std::string &path,
                     bool needs_imports) {
  if (!classcode.length()) return true;

  std::string namespace_name;
  std::string namespace_dir = path;  // Either empty or ends in separator.
  auto &namespaces = parser.namespaces_.back()->components;
  for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
    if (namespace_name.length()) {
      namespace_name += ".";
    }
    namespace_name = *it;
    namespace_dir += *it + kPathSeparator;
  }
  EnsureDirExists(namespace_dir);

  std::string code = "";
  BeginFile(namespace_name, needs_imports, &code);
  code += classcode;
  std::string filename = namespace_dir + def.name + ".go";
  return SaveFile(filename.c_str(), code, false);
}
Exemple #5
0
void WriteNodesFile(GF_List *BNodes, GF_List *NDTs)
{
	FILE *f;
	u32 i, j;
	X3DNode *n;
	X3DField *bf;
	f = BeginFile(0);

	fprintf(f, "#include <gpac/scenegraph_vrml.h>\n\n");
	fprintf(f, "#ifndef GPAC_DISABLE_X3D\n\n");

	//write all tags
	fprintf(f, "\n\nenum {\n");

	for (i=0; i<gf_list_count(BNodes); i++) {
		n = gf_list_get(BNodes, i);
		if (i)
			fprintf(f, ",\n\tTAG_X3D_%s", n->name);
		else
			fprintf(f, "\tTAG_X3D_%s = GF_NODE_RANGE_FIRST_X3D", n->name);
	}
	fprintf(f, ",\n\tTAG_LastImplementedX3D\n};\n\n");

	for (i=0; i<gf_list_count(BNodes); i++) {
		n = gf_list_get(BNodes, i);
		if (n->skip_impl) continue;
		fprintf(f, "typedef struct _tagX3D%s\n{\n", n->name);
		fprintf(f, "\tBASE_NODE\n");

		/*write children field*/
		for (j=0; j<gf_list_count(n->Fields); j++) {
			bf = gf_list_get(n->Fields, j);
			if (!stricmp(bf->name, "addChildren") || !strcmp(bf->name, "removeChildren")) continue;
			if (strcmp(bf->type, "eventOut") && !strcmp(bf->name, "children")) {
				fprintf(f, "\tVRML_CHILDREN\n");
				break;
			}
		}
		for (j=0; j<gf_list_count(n->Fields); j++) {
			bf = gf_list_get(n->Fields, j);

			if (!strcmp(bf->name, "addChildren") || !strcmp(bf->name, "removeChildren")) continue;
			if (strcmp(bf->type, "eventOut") && !strcmp(bf->name, "children")) continue;

			if (strstr(bf->familly, "Node")) {
				//this is a POINTER to a node
				if (strstr(bf->familly, "SF")) {
					fprintf(f, "\tGF_Node *%s;\t/*%s*/\n", bf->name, bf->type);
				} else {
					//this is a POINTER to a chain
					fprintf(f, "\tGF_ChildNodeItem *%s;\t/*%s*/\n", bf->name, bf->type);
				}
			} else {
				fprintf(f, "\t%s %s;\t/*%s*/\n", bf->familly, bf->name, bf->type);
			}
			if (!strcmp(bf->type, "eventIn"))
				fprintf(f, "\tvoid (*on_%s)(GF_Node *pThis, struct _route *route);\t/*eventInHandler*/\n", bf->name);
		}
		fprintf(f, "} X_%s;\n\n\n", n->name);
	}

	fprintf(f, "#endif /*GPAC_DISABLE_X3D*/\n\n");
	EndFile(f, 0);

}
Exemple #6
0
int main (int argc, char **argv)
{
	FILE *nodes, *pf;
	GF_List *XNodes, *NDTs;
	X3DNode *n;
	X3DField *bf;
	u32 nb_nodes, nb_imp;

	nodes = gf_fopen("templates_X3D.txt", "rt");
	if (!nodes) {
		fprintf(stdout, "cannot open \"templates_X3D.txt\" - aborting\n");
		return 0;
	}

	XNodes = gf_list_new();
	NDTs = gf_list_new();
	//all nodes are in the same list but we keep version info
	ParseTemplateFile(nodes, XNodes, NDTs);
	gf_fclose(nodes);

	if (argc>1) {
		pf = gf_fopen(argv[1], "rt");
		if (!pf) fprintf(stdout, "Cannot open profile file %s\n", argv[1]);
		else {
			parse_profile(XNodes, pf);
			gf_fclose(pf);
		}
	}

	//write the nodes def
	WriteNodesFile(XNodes, NDTs);

	nodes = BeginFile(1);

	//write all nodes init stuff
	WriteNodeCode(XNodes, nodes);

	WriteNDT(nodes, XNodes, NDTs);
	fprintf(nodes, "#endif /*GPAC_DISABLE_X3D*/\n\n");

	EndFile(nodes, 1);

	//free NDTs
	while (gf_list_count(NDTs)) {
		char *tmp = gf_list_get(NDTs, 0);
		gf_free(tmp);
		gf_list_rem(NDTs, 0);
	}
	gf_list_del(NDTs);

	nb_nodes = gf_list_count(XNodes);
	nb_imp = 0;
	//free nodes
	while (gf_list_count(XNodes)) {
		n = gf_list_get(XNodes, 0);
		if (!n->skip_impl) nb_imp++;
		gf_list_rem(XNodes, 0);
		while (gf_list_count(n->NDT)) {
			char *tmp = gf_list_get(n->NDT, 0);
			gf_free(tmp);
			gf_list_rem(n->NDT, 0);
		}
		gf_list_del(n->NDT);
		while (gf_list_count(n->Fields)) {
			bf = gf_list_get(n->Fields, 0);
			gf_free(bf);
			gf_list_rem(n->Fields, 0);
		}
		gf_list_del(n->Fields);
		gf_free(n);
	}
	gf_list_del(XNodes);

	fprintf(stdout, "Generation done: %d nodes implemented (%d nodes total)\n", nb_imp, nb_nodes);
	return 0;
}
Exemple #7
0
void generateSVGCode_V1(GF_List *svg_elements)
{
	FILE *output;
	u32 i;

	/***************************************************/
	/***************************************************/
	/*************** Creating .h file ******************/
	/***************************************************/
	/***************************************************/
	output = BeginFile(0);
	fprintf(output, "#include <gpac/scenegraph_svg.h>\n\n\n");
	fprintf(output, "/* Definition of SVG element internal tags */\n");
	fprintf(output, "/* TAG names are made of \"TAG_SVG\" + SVG element name (with - replaced by _) */\n");

	/* write all tags */
	fprintf(output, "enum {\n");
	for (i=0; i<gf_list_count(svg_elements); i++) {
		SVGGenElement *elt = (SVGGenElement *)gf_list_get(svg_elements, i);
		if (i == 0) {
			fprintf(output, "\tTAG_SVG_%s = GF_NODE_RANGE_FIRST_SVG_SA", elt->implementation_name);
		} else {
			fprintf(output, ",\n\tTAG_SVG_%s", elt->implementation_name);
		}
	}

	fprintf(output, ",\n\t/*undefined elements (when parsing) use this tag*/\n\tTAG_SVG_UndefinedElement\n};\n\n");

	fprintf(output, "/******************************************\n");
	fprintf(output, "*   SVG Elements structure definitions    *\n");
	fprintf(output, "*******************************************/\n");
	for (i=0; i<gf_list_count(svg_elements); i++) {
		SVGGenElement *elt = (SVGGenElement *)gf_list_get(svg_elements, i);
		generateNode(output, elt);
	}
	fprintf(output, "/******************************************\n");
	fprintf(output, "*  End SVG Elements structure definitions *\n");
	fprintf(output, "*******************************************/\n");
	EndFile(output, 0);

	/***************************************************/
	/***************************************************/
	/*************** Creating .c file ******************/
	/***************************************************/
	/***************************************************/
	output = BeginFile(1);
	fprintf(output, "#include <gpac/nodes_svg_sa.h>\n\n");

	fprintf(output, "#ifndef GPAC_DISABLE_SVG\n\n");
	fprintf(output, "#include <gpac/internal/scenegraph_dev.h>\n\n");
	fprintf(output, "#ifdef GPAC_ENABLE_SVG_SA\n\n");
	for (i=0; i<gf_list_count(svg_elements); i++) {
		SVGGenElement *elt = (SVGGenElement *)gf_list_get(svg_elements, i);
		generateNodeImpl(output, elt);
	}

	/***************************************************/
	/* SVG_SA_Element *gf_svg_sa_create_node(u32 ElementTag)  */
	/***************************************************/
	fprintf(output, "SVG_SA_Element *gf_svg_sa_create_node(u32 ElementTag)\n");
	fprintf(output, "{\n");
	fprintf(output, "\tswitch (ElementTag) {\n");
	for (i=0; i<gf_list_count(svg_elements); i++) {
		SVGGenElement *elt = (SVGGenElement *)gf_list_get(svg_elements, i);
		fprintf(output, "\t\tcase TAG_SVG_%s: return (SVG_SA_Element*) gf_svg_new_%s();\n",elt->implementation_name,elt->implementation_name);
	}
	fprintf(output, "\t\tdefault: return NULL;\n\t}\n}\n\n");

	/***************************************************/
	/* void gf_svg_sa_element_del(SVG_SA_Element *elt)        */
	/***************************************************/
	fprintf(output, "void gf_svg_sa_element_del(SVG_SA_Element *elt)\n{\n");
	fprintf(output, "\tGF_Node *node = (GF_Node *)elt;\n");
	fprintf(output, "\tswitch (node->sgprivate->tag) {\n");
	for (i=0; i<gf_list_count(svg_elements); i++) {
		SVGGenElement *elt = (SVGGenElement *)gf_list_get(svg_elements, i);
		fprintf(output, "\t\tcase TAG_SVG_%s: gf_svg_sa_%s_del(node); return;\n", elt->implementation_name, elt->implementation_name);
	}
	fprintf(output, "\t\tdefault: return;\n\t}\n}\n\n");

	/***************************************************/
	/* u32 gf_svg_sa_get_attribute_count(SVG_SA_Element *elt) */
	/***************************************************/
	fprintf(output, "u32 gf_svg_sa_get_attribute_count(GF_Node *node)\n{\n");
	fprintf(output, "\tswitch (node->sgprivate->tag) {\n");
	for (i=0; i<gf_list_count(svg_elements); i++) {
		SVGGenElement *elt = (SVGGenElement *)gf_list_get(svg_elements, i);
		fprintf(output, "\t\tcase TAG_SVG_%s: return %i;\n", elt->implementation_name, elt->nb_atts);
	}
	fprintf(output, "\t\tdefault: return 0;\n\t}\n}\n\n");

	/***********************************************************************/
	/* GF_Err gf_svg_sa_get_attribute_info(GF_Node *node, GF_FieldInfo *info) */
	/***********************************************************************/
	fprintf(output, "GF_Err gf_svg_sa_get_attribute_info(GF_Node *node, GF_FieldInfo *info)\n{\n");
	fprintf(output, "\tswitch (node->sgprivate->tag) {\n");
	for (i=0; i<gf_list_count(svg_elements); i++) {
		SVGGenElement *elt = (SVGGenElement *)gf_list_get(svg_elements, i);
		fprintf(output, "\t\tcase TAG_SVG_%s: return gf_svg_sa_%s_get_attribute(node, info);\n", elt->implementation_name, elt->implementation_name);
	}
	fprintf(output, "\t\tdefault: return GF_BAD_PARAM;\n\t}\n}\n\n");

	/****************************************************************/
	/* u32 gf_svg_sa_node_type_by_class_name(const char *element_name) */
	/****************************************************************/
	fprintf(output, "u32 gf_svg_sa_node_type_by_class_name(const char *element_name)\n{\n\tif (!element_name) return TAG_UndefinedNode;\n");
	for (i=0; i<gf_list_count(svg_elements); i++) {
		SVGGenElement *elt = (SVGGenElement *)gf_list_get(svg_elements, i);
		fprintf(output, "\tif (!stricmp(element_name, \"%s\")) return TAG_SVG_%s;\n", elt->svg_name, elt->implementation_name);
	}
	fprintf(output, "\treturn TAG_UndefinedNode;\n}\n\n");


	/***************************************************/
	/* const char *gf_svg_sa_get_element_name(u32 tag) */
	/***************************************************/
	fprintf(output, "const char *gf_svg_sa_get_element_name(u32 tag)\n{\n\tswitch(tag) {\n");
	for (i=0; i<gf_list_count(svg_elements); i++) {
		SVGGenElement *elt = (SVGGenElement *)gf_list_get(svg_elements, i);
		fprintf(output, "\tcase TAG_SVG_%s: return \"%s\";\n", elt->implementation_name, elt->svg_name);
	}
	fprintf(output, "\tdefault: return \"UndefinedNode\";\n\t}\n}\n\n");

	/***************************************************/
	/* const char *gf_svg_sa_get_attribute_index_by_name(u32 tag) */
	/***************************************************/
	fprintf(output, "s32 gf_svg_sa_get_attribute_index_by_name(GF_Node *node, char *name)\n{\n\tswitch(node->sgprivate->tag) {\n");
	for (i=0; i<gf_list_count(svg_elements); i++) {
		SVGGenElement *elt = (SVGGenElement *)gf_list_get(svg_elements, i);
		fprintf(output, "\tcase TAG_SVG_%s: return gf_svg_sa_%s_get_attribute_index_from_name(name);\n", elt->implementation_name, elt->implementation_name);
	}
	fprintf(output, "\tdefault: return -1;\n\t}\n}\n\n");

	/***************************************************/
	/* Bool gf_svg_is_element_transformable(u32 tag) */
	/***************************************************/
	fprintf(output, "Bool gf_svg_is_element_transformable(u32 tag)\n{\n\tswitch(tag) {\n");
	for (i=0; i<gf_list_count(svg_elements); i++) {
		SVGGenElement *elt = (SVGGenElement *)gf_list_get(svg_elements, i);
		fprintf(output, "\tcase TAG_SVG_%s:", elt->implementation_name);
		if (elt->has_transform) fprintf(output, "return 1;\n");
		else fprintf(output, "return 0;\n");
	}
	fprintf(output, "\tdefault: return 0;\n\t}\n}\n");

	fprintf(output, "#endif /*GPAC_ENABLE_SVG_SA*/\n");
	fprintf(output, "#endif /*GPAC_DISABLE_SVG*/\n\n");
	EndFile(output, 1);

	generate_laser_tables(svg_elements);
}
Exemple #8
0
void generate_laser_tables(GF_List *svg_elements)
{
	FILE *output;
	u32 i;
	u32 special_cases;

	output = BeginFile(2);
	if (generation_mode	== 1) fprintf(output, "\n#include <gpac/nodes_svg_sa.h>\n\n");
	else if (generation_mode == 2) fprintf(output, "\n#include <gpac/nodes_svg_sani.h>\n\n");
	else if (generation_mode == 3) fprintf(output, "\n#include <gpac/nodes_svg_da.h>\n\n");

	for (i=0; i<gf_list_count(svg_elements); i++) {
		u32 j, fcount;
		SVGGenElement *elt = (SVGGenElement *)gf_list_get(svg_elements, i);

		fcount = gf_list_count(elt->attributes);

		fprintf(output, "static const s32 %s_field_to_attrib_type[] = {\n", elt->implementation_name);

		/*core info: id, xml:id, class, xml:lang, xml:base, xml:space, externalResourcesRequired*/
		fprintf(output, "-1, -1, -1, 125, 124, -1, 24");
		if (elt->has_media_properties) generateGenericAttrib(output, elt, 2);
		if (elt->has_properties) generateGenericAttrib(output, elt, 1);
		if (elt->has_opacity_properties) generateGenericAttrib(output, elt, 3);
		if (elt->has_focus) generateGenericAttrib(output, elt, 4);
		if (elt->has_xlink) generateGenericAttrib(output, elt, 5);
		if (elt->has_timing) generateGenericAttrib(output, elt, 6);
		if (elt->has_sync) generateGenericAttrib(output, elt, 7);
		if (elt->has_animation) generateGenericAttrib(output, elt, 8);
		if (elt->has_conditional) generateGenericAttrib(output, elt, 9);
		/*WATCHOUT - HARDCODED VALUES*/
		if (elt->has_transform) fprintf(output, ", 105");
		if (elt->has_xy) fprintf(output, ", 116, 129");


		/*svg.width and svg.height escapes*/
		special_cases = 0;
		if (!strcmp(elt->svg_name, "svg")) special_cases = 1;
		else if (!strcmp(elt->svg_name, "a")) special_cases = 2;

		for (j=0; j<fcount; j++) {
			SVGGenAttribute *att = gf_list_get(elt->attributes, j);
			s32 type = get_lsr_att_name_type(att->svg_name);
			if (special_cases==1) {
				if (!strcmp(att->svg_name, "width"))
					type = 95;
				else if (!strcmp(att->svg_name, "height"))
					type = 94;
			}
			if ((special_cases==2) && !strcmp(att->svg_name, "target"))
				type = 0;
			fprintf(output, ", %d", type);
		}
		fprintf(output, "\n};\n\n");

	}
	fprintf(output, "s32 gf_lsr_field_to_attrib_type(GF_Node *n, u32 fieldIndex)\n{\n\tif(!n) return -2;\n\tswitch (gf_node_get_tag(n)) {\n");
	for (i=0; i<gf_list_count(svg_elements); i++) {
		u32 fcount;
		SVGGenElement *elt = (SVGGenElement *)gf_list_get(svg_elements, i);
		fprintf(output, "\tcase TAG_SVG_%s:\n", elt->implementation_name);
		fcount = gf_list_count(elt->attributes);
		fprintf(output, "\t\treturn %s_field_to_attrib_type[fieldIndex];\n", elt->implementation_name);
	}
	fprintf(output, "\tdefault:\n\t\treturn -2;\n\t}\n}\n\n");
}
Exemple #9
0
void generate_laser_tables_da(GF_List *atts)
{
	FILE *output;
	u32 i, count, j, count2;

	output = BeginFile(2);

	fprintf(output, "\n#include <gpac/internal/laser_dev.h>\n\n");
	fprintf(output, "\n\ns32 gf_lsr_anim_type_from_attribute(u32 tag) {\n\tswitch(tag) {\n");

	count = gf_list_count(atts);
	j=0;
	while (laser_attribute_name_type_list[j]) {
		for (i=0; i<count; i++) {
			SVGGenAttribute *att = gf_list_get(atts, i);

			if (!strcmp(att->implementation_name, laser_attribute_name_type_list[j])) {
				fprintf(output, "\tcase TAG_SVG_ATT_%s: return %d;\n", att->implementation_name, j);
				break;
			}
		}
		if (i==count) {
			//fprintf(stdout, "Warning: Ignoring %s\n", laser_attribute_name_type_list[j]);
			fprintf(output, "\tcase TAG_LSR_ATT_%s: return %d;\n", laser_attribute_name_type_list[j], j);
		}
		j++;
	}
	fprintf(output, "\tdefault: return -1;\n\t}\n}\n\n");

	fprintf(output, "\n\ns32 gf_lsr_rare_type_from_attribute(u32 tag) {\n\tswitch(tag) {\n");
	count = gf_list_count(atts);
	j=0;
	while (laser_attribute_rare_type_list[j]) {
		for (i=0; i<count; i++) {
			SVGGenAttribute *att = gf_list_get(atts, i);

			if (!strcmp(att->implementation_name, laser_attribute_rare_type_list[j])) {
				fprintf(output, "\tcase TAG_SVG_ATT_%s: return %d;\n", att->implementation_name, j);
				break;
			}
		}
		if (i==count) {
			if (!strcmp(laser_attribute_rare_type_list[j], "extension")) {
				fprintf(output, "\tcase TAG_SVG_ATT_syncMaster: return %d;\n", j);
				fprintf(output, "\tcase TAG_SVG_ATT_focusHighlight: return %d;\n", j);
				fprintf(output, "\tcase TAG_SVG_ATT_initialVisibility: return %d;\n", j);
				fprintf(output, "\tcase TAG_SVG_ATT_fullscreen: return %d;\n", j);
				fprintf(output, "\tcase TAG_SVG_ATT_requiredFonts: return %d;\n", j);
			} else {
				fprintf(stdout, "Warning: Ignoring %s\n", laser_attribute_rare_type_list[j]);
			}
		}
		j++;
	}
	fprintf(output, "\tdefault: return -1;\n\t}\n}\n\n");



	fprintf(output, "\n\ns32 gf_lsr_anim_type_to_attribute(u32 tag) {\n\tswitch(tag) {\n");
	j=0;
	while (laser_attribute_name_type_list[j]) {
		for (i=0; i<count; i++) {
			SVGGenAttribute *att = gf_list_get(atts, i);

			if (!strcmp(att->implementation_name, laser_attribute_name_type_list[j])) {
				fprintf(output, "\tcase %d: return TAG_SVG_ATT_%s;\n", j, att->implementation_name);
				break;
			}
		}
		if (i==count) {
			fprintf(output, "\tcase %d: return TAG_LSR_ATT_%s;\n", j, laser_attribute_name_type_list[j]);
		}
		j++;
	}
	fprintf(output, "\tdefault: return -1;\n\t}\n}\n\n");

	fprintf(output, "\n\ns32 gf_lsr_rare_type_to_attribute(u32 tag) {\n\tswitch(tag) {\n");
	j=0;
	while (laser_attribute_rare_type_list[j]) {
		for (i=0; i<count; i++) {
			SVGGenAttribute *att = gf_list_get(atts, i);

			if (!strcmp(att->implementation_name, laser_attribute_rare_type_list[j])) {
				fprintf(output, "\tcase %d: return TAG_SVG_ATT_%s;\n", j, att->implementation_name);
				break;
			}
		}
		j++;
	}
	fprintf(output, "\tdefault: return -1;\n\t}\n}\n\n");


	fprintf(output, "\n\nu32 gf_lsr_same_rare(SVGAllAttributes *elt_atts, SVGAllAttributes *base_atts)\n{\n");
	fprintf(output, "\tGF_FieldInfo f_elt, f_base;\n");

	j=0;
	while (laser_attribute_rare_type_list[j]) {
		SVGGenAttribute *att = NULL;
		if (!strcmp(laser_attribute_rare_type_list[j], "extension")) {
			j++;
			continue;
		}
		for (i=0; i<count; i++) {
			att = gf_list_get(atts, i);
			if (!strcmp(att->implementation_name, laser_attribute_rare_type_list[j]))
				break;
			att = NULL;
		}
		assert(att);

		fprintf(output, "\tf_elt.fieldType = f_base.fieldType = %s_datatype;\n", att->impl_type);
		fprintf(output, "\tf_elt.fieldIndex = f_base.fieldIndex = TAG_SVG_ATT_%s;\n", laser_attribute_rare_type_list[j]);
		fprintf(output, "\tf_elt.far_ptr = elt_atts->%s;\n", laser_attribute_rare_type_list[j]);
		fprintf(output, "\tf_base.far_ptr = base_atts->%s;\n", laser_attribute_rare_type_list[j]);
		fprintf(output, "\tif (!gf_svg_attributes_equal(&f_elt, &f_base)) return 0;\n\n");

		j++;
	}
	fprintf(output, "\treturn 1;\n}\n\n");

	fclose(output);
}