~ubuntu-branches/ubuntu/quantal/nettle/quantal

« back to all changes in this revision

Viewing changes to tools/parse.c

  • Committer: Bazaar Package Importer
  • Author(s): Marek Habersack
  • Date: 2004-05-04 15:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20040504155602-7jbhw5mabvwksl3j
Tags: upstream-1.10
Import upstream version 1.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* parse.c */
 
2
 
 
3
/* nettle, low-level cryptographics library
 
4
 *
 
5
 * Copyright (C) 2002, 2003 Niels M�ller
 
6
 *  
 
7
 * The nettle library is free software; you can redistribute it and/or modify
 
8
 * it under the terms of the GNU Lesser General Public License as published by
 
9
 * the Free Software Foundation; either version 2.1 of the License, or (at your
 
10
 * option) any later version.
 
11
 * 
 
12
 * The nettle library is distributed in the hope that it will be useful, but
 
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 
14
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 
15
 * License for more details.
 
16
 * 
 
17
 * You should have received a copy of the GNU Lesser General Public License
 
18
 * along with the nettle library; see the file COPYING.LIB.  If not, write to
 
19
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 
20
 * MA 02111-1307, USA.
 
21
 */
 
22
 
 
23
#if HAVE_CONFIG_H
 
24
# include "config.h"
 
25
#endif
 
26
 
 
27
#include <assert.h>
 
28
#include <stdlib.h>
 
29
 
 
30
#include "parse.h"
 
31
 
 
32
#include "input.h"
 
33
 
 
34
void
 
35
sexp_compound_token_init(struct sexp_compound_token *token)
 
36
{
 
37
  token->type = 0;
 
38
  nettle_buffer_init(&token->display);
 
39
  nettle_buffer_init(&token->string);
 
40
}
 
41
 
 
42
void
 
43
sexp_compound_token_clear(struct sexp_compound_token *token)
 
44
{
 
45
  nettle_buffer_clear(&token->display);
 
46
  nettle_buffer_clear(&token->string);
 
47
}
 
48
 
 
49
void
 
50
sexp_parse_init(struct sexp_parser *parser,
 
51
                struct sexp_input *input,
 
52
                enum sexp_mode mode)
 
53
{
 
54
  parser->input = input;
 
55
  parser->mode = mode;
 
56
 
 
57
  /* Start counting with 1 for the top level, to make comparisons
 
58
   * between transport and level simpler.
 
59
   *
 
60
   * FIXME: Is that trick ugly? */
 
61
  parser->level = 1;
 
62
  parser->transport = 0;
 
63
}
 
64
 
 
65
/* Get next token, and check that it is of the expected kind. */
 
66
static void
 
67
sexp_check_token(struct sexp_parser *parser,
 
68
                 enum sexp_token token,
 
69
                 struct nettle_buffer *string)
 
70
{
 
71
  sexp_get_token(parser->input,
 
72
                 parser->transport ? SEXP_CANONICAL : parser->mode,
 
73
                 string);
 
74
 
 
75
  if (token && parser->input->token != token)
 
76
    die("Syntax error.\n");
 
77
}
 
78
 
 
79
/* Performs further processing of the input, in particular display
 
80
 * types and transport decoding.
 
81
 *
 
82
 * This is complicated a little by the requirement that a
 
83
 * transport-encoded block, {xxxxx}, must include exactly one
 
84
 * expression. We check at the end of strings and list whether or not
 
85
 * we should expect a SEXP_CODING_END as the next token. */
 
86
void
 
87
sexp_parse(struct sexp_parser *parser,
 
88
           struct sexp_compound_token *token)
 
89
{
 
90
  for (;;)
 
91
    {
 
92
      sexp_get_token(parser->input,
 
93
                     parser->transport ? SEXP_CANONICAL : parser->mode,
 
94
                     &token->string);
 
95
 
 
96
      switch(parser->input->token)
 
97
        {
 
98
        case SEXP_LIST_END:
 
99
          if (parser->level == parser->transport)
 
100
            die("Unmatched end of list in transport encoded data.\n");
 
101
          parser->level--;
 
102
 
 
103
          if (!parser->level)
 
104
            die("Unmatched end of list.\n");
 
105
 
 
106
          token->type = SEXP_LIST_END;
 
107
 
 
108
        check_transport_end:
 
109
          if (parser->level == parser->transport)
 
110
            {
 
111
              sexp_check_token(parser, SEXP_CODING_END, &token->string);
 
112
              assert(parser->transport);
 
113
              assert(parser->level == parser->transport);
 
114
 
 
115
              parser->level--;
 
116
              parser->transport = 0;
 
117
            }
 
118
          return;
 
119
    
 
120
        case SEXP_EOF:
 
121
          if (parser->level > 1)
 
122
            die("Unexpected end of file.\n");
 
123
 
 
124
          token->type = SEXP_EOF;
 
125
          return;
 
126
 
 
127
        case SEXP_LIST_START:
 
128
          parser->level++;
 
129
          token->type = SEXP_LIST_START;
 
130
          return;
 
131
 
 
132
        case SEXP_DISPLAY_START:
 
133
          sexp_check_token(parser, SEXP_STRING, &token->display);
 
134
          sexp_check_token(parser, SEXP_DISPLAY_END, &token->display);
 
135
          sexp_check_token(parser, SEXP_STRING, &token->string);
 
136
 
 
137
          token->type = SEXP_DISPLAY;
 
138
          goto check_transport_end;
 
139
 
 
140
        case SEXP_STRING:
 
141
          token->type = SEXP_STRING;
 
142
          goto check_transport_end;
 
143
 
 
144
        case SEXP_TRANSPORT_START:
 
145
          if (parser->mode == SEXP_CANONICAL)
 
146
            die("Base64 not allowed in canonical mode.\n");
 
147
          parser->level++;
 
148
          parser->transport = parser->level;
 
149
 
 
150
          continue;
 
151
 
 
152
        case SEXP_CODING_END:
 
153
          die("Unexpected end of transport encoding.\n");
 
154
          
 
155
        default:
 
156
          /* Internal error. */
 
157
          abort();
 
158
        }
 
159
    }
 
160
}