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