@@ -124,112 +124,118 @@ static VALUE rxml_dtd_type(VALUE self)
124124
125125/*
126126 * call-seq:
127- * XML::Dtd.new("DTD string") -> dtd
128- * XML::Dtd.new("public", "system") -> dtd
129- * XML::Dtd.new("name", "public", "system", document) -> external subset dtd
130- * XML::Dtd.new("name", "public", "system", document, false) -> internal subset dtd
131- * XML::Dtd.new("name", "public", "system", document, true) -> internal subset dtd
127+ * XML::Dtd.new(dtd_string) -> dtd
128+ * XML::Dtd.new(external_id, system_id) -> dtd
129+ * XML::Dtd.new(external_id, system_id, name, document, internal) -> dtd
132130 *
133- * Create a new Dtd from the specified public and system
134- * identifiers.
131+ * Create a new Dtd from the specified public and system identifiers:
132+ *
133+ * * The first usage creates a DTD from a string and requires 1 parameter.
134+ * * The second usage loads and parses an external DTD and requires 2 parameters.
135+ * * The third usage creates a new internal or external DTD and requires 3 parameters and 2 optional parameters.
136+ * It then attaches the DTD to the specified document if it is not nil
137+ *
138+ * Parameters:
139+ *
140+ * dtd_string - A string that contains a complete DTD
141+ * external_id - A string that specifies the DTD's external name. For example, "-//W3C//DTD XHTML 1.0 Transitional//EN"
142+ * system_id - A string that specififies the DTD's system name. For example, "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
143+ * name - A string that specifies the DTD's name. For example "xhtml1".
144+ * document - A xml document.
145+ * internal - Boolean value indicating whether this is an internal or external DTD. Optional. If not specified
146+ * then external is assumed.
135147 */
136148static VALUE rxml_dtd_initialize (int argc , VALUE * argv , VALUE self )
137149{
138- VALUE external , system , dtd_string ;
139- xmlParserInputBufferPtr buffer ;
140- xmlCharEncoding enc = XML_CHAR_ENCODING_NONE ;
141- xmlChar * new_string ;
142150 xmlDtdPtr xdtd ;
151+ VALUE external , system ;
143152
144- // 1 argument -- string --> parsujeme jako dtd
145- // 2 arguments -- public, system --> bude se hledat
146- // 3 arguments -- public, system, name --> creates an external subset (any parameter may be nil)
147- // 4 arguments -- public, system, name, doc --> creates an external subset (any parameter may be nil)
148- // 5 arguments -- public, system, name, doc, true --> creates an internal subset (all but last parameter may be nil)
149153 switch (argc )
150154 {
151- case 3 :
152- case 4 :
153- case 5 : {
154- VALUE name , doc , internal ;
155- const xmlChar * xname = NULL , * xpublic = NULL , * xsystem = NULL ;
156- xmlDocPtr xdoc = NULL ;
155+ case 3 :
156+ case 4 :
157+ case 5 :
158+ {
159+ const xmlChar * xname = NULL , * xpublic = NULL , * xsystem = NULL ;
160+ xmlDocPtr xdoc = NULL ;
157161
158- rb_scan_args (argc , argv , "32" , & external , & system , & name , & doc , & internal );
162+ VALUE name , doc , internal ;
163+ rb_scan_args (argc , argv , "32" , & external , & system , & name , & doc , & internal );
159164
160- if (external != Qnil ) {
161- Check_Type (external , T_STRING );
162- xpublic = (const xmlChar * ) StringValuePtr (external );
163- }
164- if (system != Qnil ) {
165- Check_Type (system , T_STRING );
166- xsystem = (const xmlChar * ) StringValuePtr (system );
167- }
168- if (name != Qnil ) {
169- Check_Type (name , T_STRING );
170- xname = (const xmlChar * ) StringValuePtr (name );
171- }
172- if (doc != Qnil ) {
173- if (rb_obj_is_kind_of (doc , cXMLDocument ) == Qfalse )
174- rb_raise (rb_eTypeError , "Must pass an LibXML::XML::Document object" );
175- Data_Get_Struct (doc , xmlDoc , xdoc );
176- }
165+ Check_Type (external , T_STRING );
166+ xpublic = (const xmlChar * ) StringValuePtr (external );
177167
178- if (internal == Qnil || internal == Qfalse )
179- xdtd = xmlNewDtd (xdoc , xname , xpublic , xsystem );
180- else
181- xdtd = xmlCreateIntSubset (xdoc , xname , xpublic , xsystem );
168+ Check_Type (system , T_STRING );
169+ xsystem = (const xmlChar * ) StringValuePtr (system );
182170
183- if ( xdtd == NULL )
184- rxml_raise ( xmlGetLastError () );
171+ Check_Type ( name , T_STRING );
172+ xname = ( const xmlChar * ) StringValuePtr ( name );
185173
186- /* Document will free this dtd now. */
187- RDATA (self )-> dfree = NULL ;
188- DATA_PTR (self ) = xdtd ;
174+ if (doc != Qnil )
175+ {
176+ if (rb_obj_is_kind_of (doc , cXMLDocument ) == Qfalse )
177+ rb_raise (rb_eTypeError , "Must pass an LibXML::XML::Document object" );
178+ Data_Get_Struct (doc , xmlDoc , xdoc );
179+ }
189180
190- xmlSetTreeDoc ((xmlNodePtr ) xdtd , xdoc );
191- }
192- break ;
181+ if (internal == Qnil || internal == Qfalse )
182+ xdtd = xmlNewDtd (xdoc , xname , xpublic , xsystem );
183+ else
184+ xdtd = xmlCreateIntSubset (xdoc , xname , xpublic , xsystem );
193185
194- case 2 :
195- rb_scan_args ( argc , argv , "20" , & external , & system );
186+ if ( xdtd == NULL )
187+ rxml_raise ( xmlGetLastError () );
196188
197- Check_Type (external , T_STRING );
198- Check_Type (system , T_STRING );
189+ /* The document will free the dtd so Ruby should not */
190+ RDATA (self )-> dfree = NULL ;
191+ DATA_PTR (self ) = xdtd ;
199192
200- xdtd = xmlParseDTD ((xmlChar * ) StringValuePtr (external ),
201- (xmlChar * ) StringValuePtr (system ));
193+ xmlSetTreeDoc ((xmlNodePtr ) xdtd , xdoc );
194+ }
195+ break ;
202196
203- if (xdtd == NULL )
204- rxml_raise (xmlGetLastError ());
197+ case 2 :
198+ {
199+ rb_scan_args (argc , argv , "20" , & external , & system );
205200
206- DATA_PTR (self ) = xdtd ;
201+ Check_Type (external , T_STRING );
202+ Check_Type (system , T_STRING );
207203
208- xmlSetTreeDoc ((xmlNodePtr ) xdtd , NULL );
209- break ;
204+ xdtd = xmlParseDTD ((xmlChar * ) StringValuePtr (external ), (xmlChar * ) StringValuePtr (system ));
210205
211- case 1 :
212- rb_scan_args (argc , argv , "10" , & dtd_string );
213- Check_Type (dtd_string , T_STRING );
206+ if (xdtd == NULL )
207+ rxml_raise (xmlGetLastError ());
214208
215- /* Note that buffer is freed by xmlParserInputBufferPush*/
216- buffer = xmlAllocParserInputBuffer (enc );
217- new_string = xmlStrdup ((xmlChar * ) StringValuePtr (dtd_string ));
218- xmlParserInputBufferPush (buffer , xmlStrlen (new_string ),
219- (const char * ) new_string );
209+ DATA_PTR (self ) = xdtd ;
220210
221- xdtd = xmlIOParseDTD (NULL , buffer , enc );
211+ xmlSetTreeDoc ((xmlNodePtr ) xdtd , NULL );
212+ break ;
213+ }
214+ case 1 :
215+ {
216+ VALUE dtd_string ;
217+ rb_scan_args (argc , argv , "10" , & dtd_string );
218+ Check_Type (dtd_string , T_STRING );
222219
223- if (xdtd == NULL )
224- rxml_raise (xmlGetLastError ());
220+ /* Note that buffer is freed by xmlParserInputBufferPush*/
221+ xmlCharEncoding enc = XML_CHAR_ENCODING_NONE ;
222+ xmlParserInputBufferPtr buffer = xmlAllocParserInputBuffer (enc );
223+ xmlChar * new_string = xmlStrdup ((xmlChar * ) StringValuePtr (dtd_string ));
224+ xmlParserInputBufferPush (buffer , xmlStrlen (new_string ),
225+ (const char * ) new_string );
225226
226- xmlFree ( new_string );
227+ xdtd = xmlIOParseDTD ( NULL , buffer , enc );
227228
228- DATA_PTR ( self ) = xdtd ;
229- break ;
229+ if ( xdtd == NULL )
230+ rxml_raise ( xmlGetLastError ()) ;
230231
231- default :
232- rb_raise (rb_eArgError , "wrong number of arguments" );
232+ xmlFree (new_string );
233+
234+ DATA_PTR (self ) = xdtd ;
235+ break ;
236+ }
237+ default :
238+ rb_raise (rb_eArgError , "wrong number of arguments" );
233239 }
234240
235241 return self ;
0 commit comments