Followup to r29625: fix getopt tests.
[svn.git] / subversion / include / svn_xml.h
blob8d08f8f3132c22fbbebb03d700eeb491e57ceb2b
1 /**
2 * @copyright
3 * ====================================================================
4 * Copyright (c) 2000-2006 CollabNet. All rights reserved.
6 * This software is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution. The terms
8 * are also available at http://subversion.tigris.org/license-1.html.
9 * If newer versions of this license are posted there, you may use a
10 * newer version instead, at your option.
12 * This software consists of voluntary contributions made by many
13 * individuals. For exact contribution history, see the revision
14 * history and logs, available at http://subversion.tigris.org/.
15 * ====================================================================
16 * @endcopyright
18 * @file svn_xml.h
19 * @brief XML code shared by various Subversion libraries.
24 #ifndef SVN_XML_H
25 #define SVN_XML_H
27 #include <apr.h>
28 #include <apr_pools.h>
29 #include <apr_hash.h>
31 #include "svn_error.h"
32 #include "svn_string.h"
34 #ifdef __cplusplus
35 extern "C" {
36 #endif /* __cplusplus */
38 /** The namespace all Subversion XML uses. */
39 #define SVN_XML_NAMESPACE "svn:"
41 /** Used as style argument to svn_xml_make_open_tag() and friends. */
42 enum svn_xml_open_tag_style {
43 /** <tag ...> */
44 svn_xml_normal = 1,
46 /** <tag ...>, no cosmetic newline */
47 svn_xml_protect_pcdata,
49 /** <tag .../> */
50 svn_xml_self_closing
55 /** Determine if a string of character @a data of length @a len is a
56 * safe bet for use with the svn_xml_escape_* functions found in this
57 * header.
59 * Return @c TRUE if it is, @c FALSE otherwise.
61 * Essentially, this function exists to determine whether or not
62 * simply running a string of bytes through the Subversion XML escape
63 * routines will produce legitimate XML. It should only be necessary
64 * for data which might contain bytes that cannot be safely encoded
65 * into XML (certain control characters, for example).
67 svn_boolean_t svn_xml_is_xml_safe(const char *data,
68 apr_size_t len);
70 /** Create or append in @a *outstr an xml-escaped version of @a string,
71 * suitable for output as character data.
73 * If @a *outstr is @c NULL, store a new stringbuf, else append to the
74 * existing stringbuf there.
76 void svn_xml_escape_cdata_stringbuf(svn_stringbuf_t **outstr,
77 const svn_stringbuf_t *string,
78 apr_pool_t *pool);
80 /** Same as svn_xml_escape_cdata_stringbuf(), but @a string is an
81 * @c svn_string_t.
83 void svn_xml_escape_cdata_string(svn_stringbuf_t **outstr,
84 const svn_string_t *string,
85 apr_pool_t *pool);
87 /** Same as svn_xml_escape_cdata_stringbuf(), but @a string is a
88 * NULL-terminated C string.
90 void svn_xml_escape_cdata_cstring(svn_stringbuf_t **outstr,
91 const char *string,
92 apr_pool_t *pool);
95 /** Create or append in @a *outstr an xml-escaped version of @a string,
96 * suitable for output as an attribute value.
98 * If @a *outstr is @c NULL, store a new stringbuf, else append to the
99 * existing stringbuf there.
101 void svn_xml_escape_attr_stringbuf(svn_stringbuf_t **outstr,
102 const svn_stringbuf_t *string,
103 apr_pool_t *pool);
105 /** Same as svn_xml_escape_attr_stringbuf(), but @a string is an
106 * @c svn_string_t.
108 void svn_xml_escape_attr_string(svn_stringbuf_t **outstr,
109 const svn_string_t *string,
110 apr_pool_t *pool);
112 /** Same as svn_xml_escape_attr_stringbuf(), but @a string is a
113 * NULL-terminated C string.
115 void svn_xml_escape_attr_cstring(svn_stringbuf_t **outstr,
116 const char *string,
117 apr_pool_t *pool);
120 * Return UTF-8 string @a string if it contains no characters that are
121 * unrepresentable in XML. Else, return a copy of @a string,
122 * allocated in @a pool, with each unrepresentable character replaced
123 * by "?\uuu", where "uuu" is the three-digit unsigned decimal value
124 * of that character.
126 * Neither the input nor the output need be valid XML; however, the
127 * output can always be safely XML-escaped.
129 * @note The current implementation treats all Unicode characters as
130 * representable, except for most ASCII control characters (the
131 * exceptions being CR, LF, and TAB, which are valid in XML). There
132 * may be other UTF-8 characters that are invalid in XML; see
133 * http://subversion.tigris.org/servlets/ReadMsg?list=dev&msgNo=90591
134 * and its thread for details.
136 * @since New in 1.2.
138 const char *svn_xml_fuzzy_escape(const char *string,
139 apr_pool_t *pool);
142 /*---------------------------------------------------------------*/
144 /* Generalized Subversion XML Parsing */
146 /** A generalized Subversion XML parser object */
147 typedef struct svn_xml_parser_t svn_xml_parser_t;
149 typedef void (*svn_xml_start_elem)(void *baton,
150 const char *name,
151 const char **atts);
153 typedef void (*svn_xml_end_elem)(void *baton, const char *name);
155 /* data is not NULL-terminated. */
156 typedef void (*svn_xml_char_data)(void *baton,
157 const char *data,
158 apr_size_t len);
161 /** Create a general Subversion XML parser */
162 svn_xml_parser_t *svn_xml_make_parser(void *baton,
163 svn_xml_start_elem start_handler,
164 svn_xml_end_elem end_handler,
165 svn_xml_char_data data_handler,
166 apr_pool_t *pool);
169 /** Free a general Subversion XML parser */
170 void svn_xml_free_parser(svn_xml_parser_t *svn_parser);
173 /** Push @a len bytes of xml data in @a buf at @a svn_parser.
175 * If this is the final push, @a is_final must be set.
177 * An error will be returned if there was a syntax problem in the XML,
178 * or if any of the callbacks set an error using
179 * svn_xml_signal_bailout().
181 * If an error is returned, the @c svn_xml_parser_t will have been freed
182 * automatically, so the caller should not call svn_xml_free_parser().
184 svn_error_t *svn_xml_parse(svn_xml_parser_t *svn_parser,
185 const char *buf,
186 apr_size_t len,
187 svn_boolean_t is_final);
191 /** The way to officially bail out of xml parsing.
193 * Store @a error in @a svn_parser and set all expat callbacks to @c NULL.
195 void svn_xml_signal_bailout(svn_error_t *error,
196 svn_xml_parser_t *svn_parser);
202 /*** Helpers for dealing with the data Expat gives us. ***/
204 /** Return the value associated with @a name in expat attribute array @a atts,
205 * else return @c NULL.
207 * (There could never be a @c NULL attribute value in the XML,
208 * although the empty string is possible.)
210 * @a atts is an array of c-strings: even-numbered indexes are names,
211 * odd-numbers hold values. If all is right, it should end on an
212 * even-numbered index pointing to @c NULL.
214 const char *svn_xml_get_attr_value(const char *name, const char **atts);
218 /* Converting between Expat attribute lists and APR hash tables. */
221 /** Create an attribute hash from @c va_list @a ap.
223 * The contents of @a ap are alternating <tt>char *</tt> keys and
224 * <tt>char *</tt> vals, terminated by a final @c NULL falling on an
225 * even index (zero-based).
227 apr_hash_t *svn_xml_ap_to_hash(va_list ap, apr_pool_t *pool);
229 /** Create a hash that corresponds to Expat xml attribute list @a atts.
231 * The hash's keys and values are <tt>char *</tt>'s.
233 * @a atts may be NULL, in which case you just get an empty hash back
234 * (this makes life more convenient for some callers).
236 apr_hash_t *svn_xml_make_att_hash(const char **atts, apr_pool_t *pool);
239 /** Like svn_xml_make_att_hash(), but takes a hash and preserves any
240 * key/value pairs already in it.
242 void svn_xml_hash_atts_preserving(const char **atts,
243 apr_hash_t *ht,
244 apr_pool_t *pool);
246 /** Like svn_xml_make_att_hash(), but takes a hash and overwrites
247 * key/value pairs already in it that also appear in @a atts.
249 void svn_xml_hash_atts_overlaying(const char **atts,
250 apr_hash_t *ht,
251 apr_pool_t *pool);
255 /* Printing XML */
257 /** Create an XML header and return it in @a *str.
259 * Fully-formed XML documents should start out with a header,
260 * something like
261 * \<?xml version="1.0" encoding="utf-8"?\>
263 * This function returns such a header. @a *str must either be @c NULL, in
264 * which case a new string is created, or it must point to an existing
265 * string to be appended to.
267 void svn_xml_make_header(svn_stringbuf_t **str, apr_pool_t *pool);
270 /** Store a new xml tag @a tagname in @a *str.
272 * If @a str is @c NULL, allocate @a *str in @a pool; else append the new
273 * tag to @a *str, allocating in @a str's pool
275 * Take the tag's attributes from varargs, a NULL-terminated list of
276 * alternating <tt>char *</tt> key and <tt>char *</tt> val. Do xml-escaping
277 * on each val.
279 * @a style is one of the enumerated styles in @c svn_xml_open_tag_style.
281 void svn_xml_make_open_tag(svn_stringbuf_t **str,
282 apr_pool_t *pool,
283 enum svn_xml_open_tag_style style,
284 const char *tagname,
285 ...);
288 /** Like svn_xml_make_open_tag(), but takes a @c va_list instead of being
289 * variadic.
291 void svn_xml_make_open_tag_v(svn_stringbuf_t **str,
292 apr_pool_t *pool,
293 enum svn_xml_open_tag_style style,
294 const char *tagname,
295 va_list ap);
298 /** Like svn_xml_make_open_tag(), but takes a hash table of attributes
299 * (<tt>char *</tt> keys mapping to <tt>char *</tt> values).
301 * You might ask, why not just provide svn_xml_make_tag_atts()?
303 * The reason is that a hash table is the most natural interface to an
304 * attribute list; the fact that Expat uses <tt>char **</tt> atts instead is
305 * certainly a defensible implementation decision, but since we'd have
306 * to have special code to support such lists throughout Subversion
307 * anyway, we might as well write that code for the natural interface
308 * (hashes) and then convert in the few cases where conversion is
309 * needed. Someday it might even be nice to change expat-lite to work
310 * with apr hashes.
312 * See conversion functions svn_xml_make_att_hash() and
313 * svn_xml_make_att_hash_overlaying(). Callers should use those to
314 * convert Expat attr lists into hashes when necessary.
316 void svn_xml_make_open_tag_hash(svn_stringbuf_t **str,
317 apr_pool_t *pool,
318 enum svn_xml_open_tag_style style,
319 const char *tagname,
320 apr_hash_t *attributes);
323 /** Makes a close tag. */
324 void svn_xml_make_close_tag(svn_stringbuf_t **str,
325 apr_pool_t *pool,
326 const char *tagname);
330 #ifdef __cplusplus
332 #endif /* __cplusplus */
334 #endif /* SVN_XML_H */