summaryrefslogtreecommitdiff
path: root/tools/parse.c
diff options
context:
space:
mode:
authorNiels Möller <nisse@lysator.liu.se>2003-01-12 20:54:04 +0100
committerNiels Möller <nisse@lysator.liu.se>2003-01-12 20:54:04 +0100
commite563d808f8254fde8e6c1f581399eb7e94d49eb1 (patch)
tree7279347c55121b85a88c41f9662d0c50ab491866 /tools/parse.c
parentbd7386a12db9849243cc255d84728270500146cf (diff)
downloadnettle-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.c156
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();
+ }
+ }
+}