1 /* svn_skel.h : interface to `skeleton' functions
3 * ====================================================================
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
20 * ====================================================================
26 #include <apr_pools.h>
28 #include "svn_string.h"
32 #endif /* __cplusplus */
37 /* Subversion needs to read a lot of structured data from database
38 records. Instead of writing a half-dozen parsers and getting lazy
39 about error-checking, we define a reasonably dense, open-ended
40 syntax for strings and lists, and then use that for the concrete
41 representation of files, directories, property lists, etc. This
42 lets us handle all the fussy character-by-character testing and
43 sanity checks all in one place, allowing the users of this library
44 to focus on higher-level consistency.
46 A `skeleton' (or `skel') is either an atom, or a list. A list may
47 contain zero or more elements, each of which may be an atom or a
50 Here's a description of the syntax of a skel:
52 A "whitespace" byte is 9, 10, 12, 13, or 32 (ASCII tab, newline,
53 form feed, carriage return, or space).
55 A "digit" byte is 48 -- 57 (ASCII digits).
57 A "name" byte is 65 -- 90, or 97 -- 122 (ASCII upper- and
58 lower-case characters).
60 An atom has one the following two forms:
61 - any string of bytes whose first byte is a name character, and
62 which contains no whitespace characters, bytes 40 (ASCII '(') or
63 bytes 41 (ASCII ')') (`implicit-length form'), or
64 - a string of digit bytes, followed by exactly one whitespace
65 character, followed by N bytes, where N is the value of the digit
66 bytes as a decimal number (`explicit-length form').
68 In the first case, the `contents' of the atom are the entire string
69 of characters. In the second case, the contents of the atom are
70 the N bytes after the count and whitespace.
72 A list consists of a byte 40 (ASCII '('), followed by a series of
73 atoms or lists, followed by a byte 41 (ASCII ')'). There may be
74 zero or more whitespace characters after the '(' and before the
75 ')', and between any pair of elements. If two consecutive elements
76 are atoms, they must be separated by at least one whitespace
80 /* The `skel' structure. */
82 /* A structure representing the results of parsing an array of bytes
86 /* True if the string was an atom, false if it was a list.
88 If the string is an atom, DATA points to the beginning of its
89 contents, and LEN gives the content length, in bytes.
91 If the string is a list, DATA and LEN delimit the entire body of
93 svn_boolean_t is_atom;
98 /* If the string is a list, CHILDREN is a pointer to a
99 null-terminated linked list of skel objects representing the
100 elements of the list, linked through their NEXT pointers. */
101 struct svn_skel_t *children;
102 struct svn_skel_t *next;
104 typedef struct svn_skel_t svn_skel_t;
108 /* Operations on skels. */
111 /* Parse the LEN bytes at DATA as the concrete representation of a
112 skel, and return a skel object allocated from POOL describing its
113 contents. If the data is not a properly-formed SKEL object, return
116 The returned skel objects point into the block indicated by DATA
117 and LEN; we don't copy the contents. */
118 svn_skel_t *svn_skel__parse(const char *data, apr_size_t len,
122 /* Create an atom skel whose contents are the C string STR, allocated
124 svn_skel_t *svn_skel__str_atom(const char *str, apr_pool_t *pool);
127 /* Create an atom skel whose contents are the LEN bytes at ADDR,
128 allocated from POOL. */
129 svn_skel_t *svn_skel__mem_atom(const void *addr, apr_size_t len,
133 /* Create an empty list skel, allocated from POOL. */
134 svn_skel_t *svn_skel__make_empty_list(apr_pool_t *pool);
136 /* Duplicates the skel structure SRC_SKEL and if DUP_DATA is true also the
137 data it references in RESULT_POOL */
138 svn_skel_t *svn_skel__dup(const svn_skel_t *src_skel, svn_boolean_t dup_data,
139 apr_pool_t *result_pool);
142 /* Prepend SKEL to LIST. */
143 void svn_skel__prepend(svn_skel_t *skel, svn_skel_t *list);
146 /* Append SKEL to LIST. Note: this must traverse the LIST, so you
147 generally want to use svn_skel__prepend().
149 NOTE: careful of the argument order here. */
150 void svn_skel__append(svn_skel_t *list, svn_skel_t *skel);
153 /* Create an atom skel whose contents are the string representation
154 of the integer VALUE, allocated in RESULT_POOL, and then prepend
156 void svn_skel__prepend_int(apr_int64_t value,
158 apr_pool_t *result_pool);
161 /* Create an atom skel (allocated from RESULT_POOL) whose contents refer
162 to the string VALUE, then prepend it to SKEL.
164 NOTE: VALUE must have a lifetime *at least* that of RESULT_POOL. This
165 function does NOT copy it into RESULT_POOL. */
166 void svn_skel__prepend_str(const char *value,
168 apr_pool_t *result_pool);
171 /* Parse SKEL as an integer and return the result in *N.
172 * SCRATCH_POOL is used for temporary memory. */
174 svn_skel__parse_int(apr_int64_t *n, const svn_skel_t *skel,
175 apr_pool_t *scratch_pool);
178 /* Return a string whose contents are a concrete representation of
179 SKEL. Allocate the string from POOL. */
180 svn_stringbuf_t *svn_skel__unparse(const svn_skel_t *skel, apr_pool_t *pool);
183 /* Return true iff SKEL is an atom whose data is the same as STR. */
184 svn_boolean_t svn_skel__matches_atom(const svn_skel_t *skel, const char *str);
187 /* Return the length of the list skel SKEL. Atoms have a length of -1. */
188 int svn_skel__list_length(const svn_skel_t *skel);
191 /* Parse a `PROPLIST' SKEL into a regular hash of properties,
192 *PROPLIST_P, which has const char * property names, and
193 svn_string_t * values. Use RESULT_POOL for all allocations. */
195 svn_skel__parse_proplist(apr_hash_t **proplist_p,
196 const svn_skel_t *skel,
197 apr_pool_t *result_pool);
199 /* Parse a `IPROPS' SKEL into a depth-first ordered array of
200 svn_prop_inherited_item_t * structures *IPROPS. Use RESULT_POOL
201 for all allocations. */
203 svn_skel__parse_iprops(apr_array_header_t **iprops,
204 const svn_skel_t *skel,
205 apr_pool_t *result_pool);
207 /* Parse a `PROPLIST' SKEL looking for PROPNAME. If PROPNAME is found
208 then return its value in *PROVAL, allocated in RESULT_POOL. */
210 svn_skel__parse_prop(svn_string_t **propval,
211 const svn_skel_t *skel,
212 const char *propname,
213 apr_pool_t *result_pool);
215 /* Unparse a PROPLIST hash (which has const char * property names and
216 svn_string_t * values) into a `PROPLIST' skel *SKEL_P. Use POOL
217 for all allocations. */
219 svn_skel__unparse_proplist(svn_skel_t **skel_p,
220 const apr_hash_t *proplist,
223 /* Unparse INHERITED_PROPS, a depth-first ordered array of
224 svn_prop_inherited_item_t * structures, into a `IPROPS' skel *SKEL_P.
225 Use RESULT_POOL for all allocations. */
227 svn_skel__unparse_iproplist(svn_skel_t **skel_p,
228 const apr_array_header_t *inherited_props,
229 apr_pool_t *result_pool,
230 apr_pool_t *scratch_pool);
234 #endif /* __cplusplus */
236 #endif /* SVN_SKEL_H */