Followup to r29659: *really* fix a bunch of error leaks in the
[svn.git] / subversion / libsvn_fs_base / util / skel.h
blob3b4b0ded48c75228511e40cc2d39953d50a2c751
1 /* skel.h : interface to `skeleton' functions
3 * ====================================================================
4 * Copyright (c) 2000-2004 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 * ====================================================================
18 #ifndef SVN_LIBSVN_FS_SKEL_H
19 #define SVN_LIBSVN_FS_SKEL_H
21 #include <apr_pools.h>
23 #include "svn_string.h"
25 #ifdef __cplusplus
26 extern "C" {
27 #endif /* __cplusplus */
30 /* What is a skel? */
32 /* Subversion needs to read a lot of structured data from database
33 records. Instead of writing a half-dozen parsers and getting lazy
34 about error-checking, we define a reasonably dense, open-ended
35 syntax for strings and lists, and then use that for the concrete
36 representation of files, directories, property lists, etc. This
37 lets us handle all the fussy character-by-character testing and
38 sanity checks all in one place, allowing the users of this library
39 to focus on higher-level consistency.
41 A `skeleton' (or `skel') is either an atom, or a list. A list may
42 contain zero or more elements, each of which may be an atom or a
43 list.
45 Here's a description of the syntax of a skel:
47 A "whitespace" byte is either 9, 10, 12, 13, or 32 (ASCII tab,
48 newline, form feed, and space).
50 A "digit" byte is 48 -- 57 (ASCII digits).
52 A "name" byte is 65 -- 90, or 97 -- 122 (ASCII upper- and
53 lower-case characters).
55 An atom has one the following two forms:
56 - any string of bytes whose first byte is a name character, and
57 which contains no whitespace characters, bytes 40 (ASCII '(') or
58 bytes 41 (ASCII ')') (`implicit-length form'), or
59 - a string of digit bytes, followed by exactly one whitespace
60 character, followed by N bytes, where N is the value of the digit
61 bytes as a decimal number (`explicit-length form').
63 In the first case, the `contents' of the atom are the entire string
64 of characters. In the second case, the contents of the atom are
65 the N bytes after the count and whitespace.
67 A list consists of a byte 40 (ASCII '('), followed by a series of
68 atoms or lists, followed by a byte 41 (ASCII ')'). There may be
69 zero or more whitespace characters after the '(' and before the
70 ')', and between any pair of elements. If two consecutive elements
71 are atoms, they must be separated by at least one whitespace
72 character. */
75 /* The `skel' structure. */
77 /* A structure representing the results of parsing an array of bytes
78 as a skel. */
79 struct skel_t {
81 /* True if the string was an atom, false if it was a list.
83 If the string is an atom, DATA points to the beginning of its
84 contents, and LEN gives the content length, in bytes.
86 If the string is a list, DATA and LEN delimit the entire body of
87 the list. */
88 svn_boolean_t is_atom;
90 const char *data;
91 apr_size_t len;
93 /* If the string is a list, CHILDREN is a pointer to a
94 null-terminated linked list of skel objects representing the
95 elements of the list, linked through their NEXT pointers. */
96 struct skel_t *children;
97 struct skel_t *next;
99 typedef struct skel_t skel_t;
103 /* Operations on skels. */
106 /* Parse the LEN bytes at DATA as the concrete representation of a
107 skel, and return a skel object allocated from POOL describing its
108 contents. If the data is not a properly-formed SKEL object, return
109 zero.
111 The returned skel objects point into the block indicated by DATA
112 and LEN; we don't copy the contents. */
113 skel_t *svn_fs_base__parse_skel(const char *data, apr_size_t len,
114 apr_pool_t *pool);
117 /* Create an atom skel whose contents are the C string STR, allocated
118 from POOL. */
119 skel_t *svn_fs_base__str_atom(const char *str, apr_pool_t *pool);
122 /* Create an atom skel whose contents are the LEN bytes at ADDR,
123 allocated from POOL. */
124 skel_t *svn_fs_base__mem_atom(const void *addr, apr_size_t len,
125 apr_pool_t *pool);
128 /* Create an empty list skel, allocated from POOL. */
129 skel_t *svn_fs_base__make_empty_list(apr_pool_t *pool);
132 /* Prepend SKEL to LIST. */
133 void svn_fs_base__prepend(skel_t *skel, skel_t *list);
136 /* Append SKEL to LIST. This is not as efficient as prepending skels,
137 so prepend in places where you can sensibly do so, and you want to
138 save a couple clock cycles. */
139 void svn_fs_base__append(skel_t *skel, skel_t *list);
142 /* Return a string whose contents are a concrete representation of
143 SKEL. Allocate the string from POOL. */
144 svn_stringbuf_t *svn_fs_base__unparse_skel(skel_t *skel, apr_pool_t *pool);
147 /* Return true iff SKEL is an atom whose data is the same as STR. */
148 svn_boolean_t svn_fs_base__matches_atom(skel_t *skel, const char *str);
151 /* Return true iff SKEL is an atom whose data is the same as STR. */
152 svn_boolean_t svn_fs_base__atom_matches_string(skel_t *skel,
153 const svn_string_t *str);
156 /* Return the length of the list skel SKEL. Atoms have a length of -1. */
157 int svn_fs_base__list_length(skel_t *skel);
160 /* Return TRUE if SKEL1 and SKEL2 are the same in structure and contents,
161 or 0 if they are not. This is like a lisp `equal' not `eq': atoms
162 are equal if their lengths and contents are the same, lists are
163 equal if they have the same number and order of equal elements. */
164 svn_boolean_t svn_fs_base__skels_are_equal(skel_t *skel1, skel_t *skel2);
167 /* Make a copy of SKEL and its data in POOL. */
168 skel_t *svn_fs_base__copy_skel(skel_t *skel, apr_pool_t *pool);
171 #ifdef __cplusplus
173 #endif /* __cplusplus */
175 #endif /* SVN_LIBSVN_FS_SKEL_H */