This commit was manufactured by cvs2svn to create branch
[gnupg.git] / agent / sexp-parse.h
1 /* sexp-parse.h - S-Exp helper functions
2  *      Copyright (C) 2002 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 2 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, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #ifndef SEXP_PARSE_H
22 #define SEXP_PARSE_H
23
24 #include "../common/util.h"
25
26 /* Return the length of the next S-Exp part and update the pointer to
27    the first data byte.  0 is return on error */
28 static inline size_t
29 snext (unsigned char const **buf)
30 {
31   const unsigned char *s;
32   int n;
33
34   s = *buf;
35   for (n=0; *s && *s != ':' && digitp (s); s++)
36     n = n*10 + atoi_1 (s);
37   if (!n || *s != ':')
38     return 0; /* we don't allow empty lengths */
39   *buf = s+1;
40   return n;
41 }
42
43 /* Skip over the S-Expression BUF points to and update BUF to point to
44    the chacter right behind.  DEPTH gives the initial number of open
45    lists and may be passed as a positive number to skip over the
46    remainder of an S-Expression if the current position is somewhere
47    in an S-Expression.  The function may return an error code if it
48    encounters an impossible conditions */
49 static inline int
50 sskip (unsigned char const **buf, int *depth)
51 {
52   const unsigned char *s = *buf;
53   size_t n;
54   int d = *depth;
55   
56   while (d > 0)
57     {
58       if (*s == '(')
59         {
60           d++;
61           s++;
62         }
63       else if (*s == ')')
64         {
65           d--;
66           s++;
67         }
68       else
69         {
70           if (!d)
71             return gpg_error (GPG_ERR_INV_SEXP);
72           n = snext (&s);
73           if (!n)
74             return gpg_error (GPG_ERR_INV_SEXP); 
75           s += n;
76         }
77     }
78   *buf = s;
79   *depth = d;
80   return 0;
81 }
82
83
84 /* Check whether the the string at the address BUF points to matches
85    the token.  Return true on match and update BUF to point behind the
86    token. */
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 #endif /*SEXP_PARSE_H*/