diff options
author | Niels Möller <nisse@lysator.liu.se> | 2003-01-12 20:54:04 +0100 |
---|---|---|
committer | Niels Möller <nisse@lysator.liu.se> | 2003-01-12 20:54:04 +0100 |
commit | e563d808f8254fde8e6c1f581399eb7e94d49eb1 (patch) | |
tree | 7279347c55121b85a88c41f9662d0c50ab491866 /tools/parse.c | |
parent | bd7386a12db9849243cc255d84728270500146cf (diff) | |
download | nettle-e563d808f8254fde8e6c1f581399eb7e94d49eb1.tar.gz |
* tools/input.c, tools/input.h, tools/output.c, tools/output.h,
tools/parse.c, tools/parse.h, tools/misc.c, tools/misc.h: Moved
parts ov sexp-conv.c to separate files
Rev: src/nettle/tools/Makefile.am:1.3
Rev: src/nettle/tools/input.c:1.1
Rev: src/nettle/tools/input.h:1.1
Rev: src/nettle/tools/misc.c:1.1
Rev: src/nettle/tools/misc.h:1.1
Rev: src/nettle/tools/output.c:1.1
Rev: src/nettle/tools/output.h:1.1
Rev: src/nettle/tools/parse.c:1.1
Rev: src/nettle/tools/parse.h:1.1
Rev: src/nettle/tools/sexp-conv.c:1.13
Diffstat (limited to 'tools/parse.c')
-rw-r--r-- | tools/parse.c | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/tools/parse.c b/tools/parse.c new file mode 100644 index 00000000..6c5f5ada --- /dev/null +++ b/tools/parse.c @@ -0,0 +1,156 @@ +/* parse.c */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002, 2003 Niels Möller + * + * The nettle library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The nettle library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the nettle library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#include "parse.h" + +#include "input.h" + +#include <assert.h> +#include <stdlib.h> + +void +sexp_compound_token_init(struct sexp_compound_token *token) +{ + token->type = 0; + nettle_buffer_init(&token->display); + nettle_buffer_init(&token->string); +} + +void +sexp_compound_token_clear(struct sexp_compound_token *token) +{ + nettle_buffer_clear(&token->display); + nettle_buffer_clear(&token->string); +} + +void +sexp_parse_init(struct sexp_parser *parser, + struct sexp_input *input, + enum sexp_mode mode) +{ + parser->input = input; + parser->mode = mode; + + /* Start counting with 1 for the top level, to make comparisons + * between transport and level simpler. + * + * FIXME: Is that trick ugly? */ + parser->level = 1; + parser->transport = 0; +} + +/* Get next token, and check that it is of the expected kind. */ +static void +sexp_check_token(struct sexp_parser *parser, + enum sexp_token token, + struct nettle_buffer *string) +{ + sexp_get_token(parser->input, + parser->transport ? SEXP_CANONICAL : parser->mode, + string); + + if (token && parser->input->token != token) + die("Syntax error.\n"); +} + +/* Performs further processing of the input, in particular display + * types and transport decoding. + * + * This is complicated a little by the requirement that a + * transport-encoded block, {xxxxx}, must include exactly one + * expression. We check at the end of strings and list whether or not + * we should expect a SEXP_CODING_END as the next token. */ +void +sexp_parse(struct sexp_parser *parser, + struct sexp_compound_token *token) +{ + for (;;) + { + sexp_get_token(parser->input, + parser->transport ? SEXP_CANONICAL : parser->mode, + &token->string); + + switch(parser->input->token) + { + case SEXP_LIST_END: + if (parser->level == parser->transport) + die("Unmatched end of list in transport encoded data.\n"); + parser->level--; + + if (!parser->level) + die("Unmatched end of list.\n"); + + token->type = SEXP_LIST_END; + + check_transport_end: + if (parser->level == parser->transport) + { + sexp_check_token(parser, SEXP_CODING_END, &token->string); + assert(parser->transport); + assert(parser->level == parser->transport); + + parser->level--; + parser->transport = 0; + } + return; + + case SEXP_EOF: + if (parser->level > 1) + die("Unexpected end of file.\n"); + + token->type = SEXP_EOF; + return; + + case SEXP_LIST_START: + parser->level++; + token->type = SEXP_LIST_START; + return; + + case SEXP_DISPLAY_START: + sexp_check_token(parser, SEXP_STRING, &token->display); + sexp_check_token(parser, SEXP_DISPLAY_END, &token->display); + sexp_check_token(parser, SEXP_STRING, &token->string); + + token->type = SEXP_DISPLAY; + goto check_transport_end; + + case SEXP_STRING: + token->type = SEXP_STRING; + goto check_transport_end; + + case SEXP_TRANSPORT_START: + if (parser->mode == SEXP_CANONICAL) + die("Base64 not allowed in canonical mode.\n"); + parser->level++; + parser->transport = parser->level; + + continue; + + case SEXP_CODING_END: + die("Unexpected end of transport encoding.\n"); + + default: + /* Internal error. */ + abort(); + } + } +} |