Line data Source code
1 : /* sexp-parse.h - S-expression helper functions
2 : * Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
3 : *
4 : * This file is free software; you can redistribute it and/or modify
5 : * it under the terms of either
6 : *
7 : * - the GNU Lesser General Public License as published by the Free
8 : * Software Foundation; either version 3 of the License, or (at
9 : * your option) any later version.
10 : *
11 : * or
12 : *
13 : * - the GNU General Public License as published by the Free
14 : * Software Foundation; either version 2 of the License, or (at
15 : * your option) any later version.
16 : *
17 : * or both in parallel, as here.
18 : *
19 : * This file is distributed in the hope that it will be useful,
20 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 : * GNU General Public License for more details.
23 : *
24 : * You should have received a copy of the GNU General Public License
25 : * along with this program; if not, see <http://www.gnu.org/licenses/>.
26 : */
27 :
28 : #ifndef SEXP_PARSE_H
29 : #define SEXP_PARSE_H
30 :
31 : #include <gpg-error.h>
32 :
33 :
34 : /* Return the length of the next S-Exp part and update the pointer to
35 : the first data byte. 0 is returned on error */
36 : static inline size_t
37 11841 : snext (unsigned char const **buf)
38 : {
39 : const unsigned char *s;
40 : int n;
41 :
42 11841 : s = *buf;
43 31017 : for (n=0; *s && *s != ':' && (*s >= '0' && *s <= '9'); s++)
44 19176 : n = n*10 + (*s - '0');
45 11841 : if (!n || *s != ':')
46 1 : return 0; /* we don't allow empty lengths */
47 11840 : *buf = s+1;
48 11840 : return n;
49 : }
50 :
51 : /* Skip over the S-Expression BUF points to and update BUF to point to
52 : the character right behind. DEPTH gives the initial number of open
53 : lists and may be passed as a positive number to skip over the
54 : remainder of an S-Expression if the current position is somewhere
55 : in an S-Expression. The function may return an error code if it
56 : encounters an impossible condition. */
57 : static inline gpg_error_t
58 1732 : sskip (unsigned char const **buf, int *depth)
59 : {
60 1732 : const unsigned char *s = *buf;
61 : size_t n;
62 1732 : int d = *depth;
63 :
64 14890 : while (d > 0)
65 : {
66 11427 : if (*s == '(')
67 : {
68 1760 : d++;
69 1760 : s++;
70 : }
71 9667 : else if (*s == ')')
72 : {
73 3622 : d--;
74 3622 : s++;
75 : }
76 : else
77 : {
78 6045 : if (!d)
79 0 : return gpg_error (GPG_ERR_INV_SEXP);
80 6045 : n = snext (&s);
81 6045 : if (!n)
82 1 : return gpg_error (GPG_ERR_INV_SEXP);
83 6044 : s += n;
84 : }
85 : }
86 1731 : *buf = s;
87 1731 : *depth = d;
88 1731 : return 0;
89 : }
90 :
91 :
92 : /* Check whether the the string at the address BUF points to matches
93 : the token. Return true on match and update BUF to point behind the
94 : token. Return false and do not update the buffer if it does not
95 : match. */
96 : static inline int
97 4007 : smatch (unsigned char const **buf, size_t buflen, const char *token)
98 : {
99 4007 : size_t toklen = strlen (token);
100 :
101 4007 : if (buflen != toklen || memcmp (*buf, token, toklen))
102 2138 : return 0;
103 1869 : *buf += toklen;
104 1869 : return 1;
105 : }
106 :
107 : /* Format VALUE for use as the length indicatior of an S-expression.
108 : The caller needs to provide a buffer HELP_BUFFER wth a length of
109 : HELP_BUFLEN. The return value is a pointer into HELP_BUFFER with
110 : the formatted length string. The colon and a trailing nul are
111 : appended. HELP_BUFLEN must be at least 3 - a more useful value is
112 : 15. If LENGTH is not NULL, the LENGTH of the resulting string
113 : (excluding the terminating nul) is stored at that address. */
114 : static inline char *
115 0 : smklen (char *help_buffer, size_t help_buflen, size_t value, size_t *length)
116 : {
117 0 : char *p = help_buffer + help_buflen;
118 :
119 0 : if (help_buflen >= 3)
120 : {
121 0 : *--p = 0;
122 0 : *--p = ':';
123 : do
124 : {
125 0 : *--p = '0' + (value % 10);
126 0 : value /= 10;
127 : }
128 0 : while (value && p > help_buffer);
129 : }
130 :
131 0 : if (length)
132 0 : *length = (help_buffer + help_buflen) - p;
133 0 : return p;
134 : }
135 :
136 :
137 : #endif /*SEXP_PARSE_H*/
|