constprefix_ = (iter != parsed_options.end());
iter = parsed_options.find("events");
events_ = (iter != parsed_options.end());
+ iter = parsed_options.find("xmldoc");
+ xmldoc_ = (iter != parsed_options.end());
out_dir_base_ = "gen-delphi";
" *)\n";
}
+ string replace_all( string contents, string search, string replace);
+ string xml_encode( string contents);
+ string xmldoc_encode( string contents);
+ string xmlattrib_encode( string contents);
+ void generate_delphi_doc (std::ostream& out, t_field* field);
+ void generate_delphi_doc (std::ostream& out, t_doc* tdoc);
+ void generate_delphi_doc (std::ostream& out, t_function* tdoc);
+ void generate_delphi_docstring_comment (std::ostream &out, string contents);
+
bool type_can_be_null(t_type* ttype) {
while (ttype->is_typedef()) {
ttype = ((t_typedef*)ttype)->get_type();
bool register_types_;
bool constprefix_;
bool events_;
+ bool xmldoc_;
void indent_up_impl(){
++indent_impl_;
};
};
};
+string t_delphi_generator::replace_all( string contents, string search, string repl) {
+ string str( contents);
+
+ size_t slen = search.length();
+ size_t rlen = repl.length();
+ size_t incr = (rlen > 0) ? rlen : 1;
+
+ if( slen > 0) {
+ size_t found = str.find(search);
+ while( (found != string::npos) && (found < str.length())) {
+ str.replace( found, slen, repl);
+ found = str.find(search, found+incr);
+ }
+ }
+
+ return str;
+};
+
+// XML encoding
+string t_delphi_generator::xml_encode( string contents) {
+ string str( contents);
+
+ // escape the escape
+ str = replace_all( str, "&", "&");
+
+ // other standard XML entities
+ str = replace_all( str, "<", "<");
+ str = replace_all( str, ">", ">");
+
+ return str;
+}
+
+// XML attribute encoding
+string t_delphi_generator::xmlattrib_encode( string contents) {
+ string str( xml_encode( contents));
+
+ // our attribs are enclosed in "
+ str = replace_all( str, "\"", "\\\"");
+
+ return str;
+}
+
+// XML encoding for doc comments
+string t_delphi_generator::xmldoc_encode( string contents) {
+ string str( xml_encode( contents));
+
+ // XMLDoc specific: convert linebreaks into <para>graphs</para>
+ str = replace_all( str, "\r\n", "\r");
+ str = replace_all( str, "\n", "\r");
+ str = replace_all( str, "\r", "</para>\n<para>");
+
+ return str;
+}
+
+void t_delphi_generator::generate_delphi_docstring_comment(ostream &out, string contents) {
+ if( xmldoc_) {
+ generate_docstring_comment(out,
+ "{$REGION 'XMLDoc'}/// <summary>\n",
+ "/// ", "<para>" + contents + "</para>",
+ "/// </summary>\n{$ENDREGION}\n");
+ }
+};
+
+void t_delphi_generator::generate_delphi_doc(ostream &out, t_field* field) {
+ if( xmldoc_) {
+ if (field->get_type()->is_enum()) {
+ string combined_message = xmldoc_encode( field->get_doc())
+ + "\n<seealso cref=\""
+ + xmldoc_encode( type_name(field->get_type()))
+ + "\"/>";
+ generate_delphi_docstring_comment(out, combined_message);
+ } else {
+ generate_delphi_doc(out, (t_doc*)field);
+ }
+ }
+}
+
+void t_delphi_generator::generate_delphi_doc(ostream &out, t_doc* tdoc) {
+ if (tdoc->has_doc() && xmldoc_) {
+ generate_delphi_docstring_comment(out, xmldoc_encode( tdoc->get_doc()));
+ }
+}
+
+void t_delphi_generator::generate_delphi_doc(ostream &out, t_function* tfunction) {
+ if (tfunction->has_doc() && xmldoc_) {
+ stringstream ps;
+ const vector<t_field*>& fields = tfunction->get_arglist()->get_members();
+ vector<t_field*>::const_iterator p_iter;
+ for (p_iter = fields.begin(); p_iter != fields.end(); ++p_iter) {
+ t_field* p = *p_iter;
+ ps << "\n<param name=\"" << xmlattrib_encode( p->get_name()) << "\">";
+ if (p->has_doc()) {
+ std::string str = p->get_doc();
+ str.erase(std::remove(str.begin(), str.end(), '\n'), str.end()); // remove the newlines that appear from the parser
+ ps << xmldoc_encode(str);
+ }
+ ps << "</param>";
+ }
+ generate_docstring_comment(out,
+ "{$REGION 'XMLDoc'}",
+ "/// ",
+ "<summary><para>" + xmldoc_encode(tfunction->get_doc()) + "</para></summary>" + ps.str(),
+ "{$ENDREGION}\n");
+ }
+}
+
bool t_delphi_generator::find_keyword( std::map<std::string, int>& keyword_map, std::string name) {
int len = name.length();
f_all.open( f_name.c_str() );
f_all << autogen_comment() << endl;
+ generate_delphi_doc(f_all, program_);
f_all << "unit " << unitname << ";" << endl << endl;
f_all << "interface" << endl << endl;
f_all << "uses" << endl;
indent(f_all) << "c" << tmp_unit << "_Option_Register_Types = " << ( register_types_ ? "True" : "False") << ";" << endl;
indent(f_all) << "c" << tmp_unit << "_Option_ConstPrefix = " << ( constprefix_ ? "True" : "False") << ";" << endl;
indent(f_all) << "c" << tmp_unit << "_Option_Events = " << ( events_ ? "True" : "False") << ";" << endl;
+ indent(f_all) << "c" << tmp_unit << "_Option_XmlDoc = " << ( xmldoc_ ? "True" : "False") << ";" << endl;
indent_down();
f_all << "type" << endl;
}
indent_up();
+ generate_delphi_doc(s_struct, ttypedef);
indent(s_struct) <<
type_name(ttypedef) << " = ";
void t_delphi_generator::generate_enum(t_enum* tenum) {
has_enum = true;
indent_up();
+ generate_delphi_doc( s_enum, tenum);
indent(s_enum) <<
type_name(tenum,true,true) << " = " << "(" << endl;
indent_up();
s_enum << ",";
s_enum << endl;
}
+ generate_delphi_doc(s_enum, *c_iter);
indent(s_enum) << normalize_name((*c_iter)->get_name()) << " = " << value;
}
s_enum << endl;
indent(s_const) << "public" << endl;
indent_up();
for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) {
+ generate_delphi_doc(s_const, *c_iter);
print_const_prop(s_const, normalize_name((*c_iter)->get_name()),
(*c_iter)->get_type(), (*c_iter)->get_value());
}
if ((! is_exception) || is_x_factory) {
+ generate_delphi_doc(out, tstruct);
indent(out) << struct_intf_name << " = interface(IBase)" << endl;
indent_up();
indent(out) << "end;" << endl << endl;
}
+ generate_delphi_doc(out, tstruct);
indent(out) << struct_name << " = ";
if (is_final) {
out << "sealed ";
void t_delphi_generator::generate_service(t_service* tservice) {
indent_up();
+ generate_delphi_doc(s_service, tservice);
indent(s_service) << normalize_clsnm(service_name_, "T") << " = class" << endl;
indent(s_service) << "public" << endl;
indent_up();
indent_up();
+ generate_delphi_doc(s_service, tservice);
if (tservice->get_extends() != NULL) {
extends = type_name(tservice->get_extends(), true, true);
extends_iface = extends + ".Iface";
+ generate_delphi_doc(s_service, tservice);
indent(s_service) <<
"Iface = interface(" << extends_iface << ")" << endl;
} else {
vector<t_function*>::iterator f_iter;
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter)
{
- indent(s_service) <<
+ generate_delphi_doc(s_service, *f_iter);
+ indent(s_service) <<
function_signature(*f_iter) << endl;
}
indent_down();
extends_client = extends + ".Client, ";
}
+ generate_delphi_doc(s_service, tservice);
if (tservice->get_extends() != NULL) {
extends = type_name(tservice->get_extends(), true, true);
extends_client = extends + ".TClient";
indent(s_service) << "// Iface" << endl;
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
string funname = (*f_iter)->get_name();
+ generate_delphi_doc(s_service, *f_iter);
indent(s_service) << function_signature(*f_iter) << endl;
}
indent_down();
t_type* ftype = tfield->get_type();
bool is_xception = ftype->is_xception();
+ generate_delphi_doc(out,tfield);
indent(out) << "property " << prop_name(tfield, struct_is_xception) << ": " << type_name(ftype, false, true, is_xception, true) << " read " << fieldPrefix + prop_name(tfield, struct_is_xception)
<< " write Set" << prop_name(tfield, struct_is_xception) << ";" << endl;
}
" register_types: Enable TypeRegistry, allows for creation of struct, union\n"
" and container instances by interface or TypeInfo()\n"
" constprefix: Name TConstants classes after IDL to reduce ambiguities\n"
-" events: Enable and use processing events in the generated code.\n");
+" events: Enable and use processing events in the generated code.\n"
+" xmldoc: Enable XMLDoc comments for Help Insight etc.\n");