Commit 3a69f832 authored by Niels Möller's avatar Niels Möller
Browse files

(struct sexp_input): Deleted the mode from

the state, that should be passed as argument to relevant
functions. Instead, introduces enum sexp_coding, to say if base64
coding is in effect.

Rev: src/nettle/examples/sexp-conv.c:1.6
parent f9099a79
...@@ -53,11 +53,18 @@ enum sexp_token ...@@ -53,11 +53,18 @@ enum sexp_token
SEXP_EOF, SEXP_EOF,
}; };
enum sexp_coding
{
SEXP_PLAIN,
SEXP_BASE64,
SEXP_HEX,
};
struct sexp_input struct sexp_input
{ {
FILE *f; FILE *f;
enum sexp_mode mode; enum sexp_coding coding;
/* Used in transport mode */ /* Used in transport mode */
struct base64_decode_ctx base64; struct base64_decode_ctx base64;
...@@ -72,10 +79,10 @@ struct sexp_input ...@@ -72,10 +79,10 @@ struct sexp_input
}; };
static void static void
sexp_input_init(struct sexp_input *input, FILE *f, enum sexp_mode mode) sexp_input_init(struct sexp_input *input, FILE *f)
{ {
input->f = f; input->f = f;
input->mode = mode; input->coding = SEXP_PLAIN;
input->level = 0; input->level = 0;
nettle_buffer_init(&input->string); nettle_buffer_init(&input->string);
...@@ -107,9 +114,9 @@ sexp_output_init(struct sexp_output *output, FILE *f, enum sexp_mode mode) ...@@ -107,9 +114,9 @@ sexp_output_init(struct sexp_output *output, FILE *f, enum sexp_mode mode)
static int static int
sexp_get_char(struct sexp_input *input, uint8_t *out) sexp_get_char(struct sexp_input *input, uint8_t *out)
{ {
if (input->mode & SEXP_TRANSPORT) switch (input->coding)
{ {
/* Base64 decode */ case SEXP_BASE64:
for (;;) for (;;)
{ {
int done; int done;
...@@ -132,22 +139,25 @@ sexp_get_char(struct sexp_input *input, uint8_t *out) ...@@ -132,22 +139,25 @@ sexp_get_char(struct sexp_input *input, uint8_t *out)
if (done) if (done)
return 1; return 1;
} }
} case SEXP_PLAIN:
else {
{ int c = getc(input->f);
int c = getc(input->f);
if (c < 0) if (c < 0)
{ {
if (ferror(input->f)) if (ferror(input->f))
die("Read error: %s\n", strerror(errno)); die("Read error: %s\n", strerror(errno));
input->token = SEXP_EOF; input->token = SEXP_EOF;
return 0; return 0;
} }
*out = c; *out = c;
return 1; return 1;
}
case SEXP_HEX:
/* Not yet implemented */
abort();
} }
} }
...@@ -189,7 +199,7 @@ sexp_get_token_char(struct sexp_input *input) ...@@ -189,7 +199,7 @@ sexp_get_token_char(struct sexp_input *input)
static int static int
sexp_get_quoted_char(struct sexp_input *input, uint8_t *c) sexp_get_quoted_char(struct sexp_input *input, uint8_t *c)
{ {
if (sexp_get_char(input, c) <= 0) if (!sexp_get_char(input, c))
die("Unexpected end of file in quoted string.\n"); die("Unexpected end of file in quoted string.\n");
for (;;) for (;;)
...@@ -234,10 +244,10 @@ sexp_get_quoted_char(struct sexp_input *input, uint8_t *c) ...@@ -234,10 +244,10 @@ sexp_get_quoted_char(struct sexp_input *input, uint8_t *c)
static void static void
sexp_get_quoted_string(struct sexp_input *input) sexp_get_quoted_string(struct sexp_input *input)
{ {
assert(input->mode == SEXP_ADVANCED);
uint8_t c; uint8_t c;
assert(input->coding == SEXP_PLAIN);
while (sexp_get_quoted_char(input, &c)) while (sexp_get_quoted_char(input, &c))
if (!NETTLE_BUFFER_PUTC(&input->string, c)) if (!NETTLE_BUFFER_PUTC(&input->string, c))
die("Virtual memory exhasuted.\n"); die("Virtual memory exhasuted.\n");
...@@ -255,7 +265,7 @@ sexp_get_base64_string(struct sexp_input *input) ...@@ -255,7 +265,7 @@ sexp_get_base64_string(struct sexp_input *input)
{ {
struct base64_decode_ctx ctx; struct base64_decode_ctx ctx;
assert(input->mode == SEXP_ADVANCED); assert(input->coding == SEXP_PLAIN);
base64_decode_init(&ctx); base64_decode_init(&ctx);
...@@ -283,7 +293,7 @@ sexp_get_base64_string(struct sexp_input *input) ...@@ -283,7 +293,7 @@ sexp_get_base64_string(struct sexp_input *input)
static void static void
sexp_get_token_string(struct sexp_input *input, uint8_t c) sexp_get_token_string(struct sexp_input *input, uint8_t c)
{ {
assert(input->mode == SEXP_ADVANCED); assert(input->coding == SEXP_PLAIN);
if (!TOKEN_CHAR(c) || ! NETTLE_BUFFER_PUTC(&input->string, c)) if (!TOKEN_CHAR(c) || ! NETTLE_BUFFER_PUTC(&input->string, c))
die("Invalid token.\n"); die("Invalid token.\n");
...@@ -300,7 +310,6 @@ sexp_get_token_string(struct sexp_input *input, uint8_t c) ...@@ -300,7 +310,6 @@ sexp_get_token_string(struct sexp_input *input, uint8_t c)
static void static void
sexp_get_string(struct sexp_input *input, uint8_t c) sexp_get_string(struct sexp_input *input, uint8_t c)
{ {
assert(input->mode == SEXP_ADVANCED);
input->string.size = 0; input->string.size = 0;
input->token = SEXP_STRING; input->token = SEXP_STRING;
...@@ -317,6 +326,7 @@ sexp_get_string(struct sexp_input *input, uint8_t c) ...@@ -317,6 +326,7 @@ sexp_get_string(struct sexp_input *input, uint8_t c)
case '|': case '|':
sexp_get_base64_string(input); sexp_get_base64_string(input);
break; break;
default: default:
sexp_get_token_string(input, c); sexp_get_token_string(input, c);
break; break;
...@@ -324,7 +334,8 @@ sexp_get_string(struct sexp_input *input, uint8_t c) ...@@ -324,7 +334,8 @@ sexp_get_string(struct sexp_input *input, uint8_t c)
} }
static void static void
sexp_get_string_length(struct sexp_input *input, unsigned length) sexp_get_string_length(struct sexp_input *input, enum sexp_mode mode,
unsigned length)
{ {
uint8_t c; uint8_t c;
...@@ -363,7 +374,7 @@ sexp_get_string_length(struct sexp_input *input, unsigned length) ...@@ -363,7 +374,7 @@ sexp_get_string_length(struct sexp_input *input, unsigned length)
return; return;
case '"': case '"':
if (input->mode != SEXP_ADVANCED) if (mode != SEXP_ADVANCED)
die("Encountered quoted string in canonical mode.\n"); die("Encountered quoted string in canonical mode.\n");
for (; length; length--) for (; length; length--)
...@@ -385,7 +396,7 @@ sexp_get_string_length(struct sexp_input *input, unsigned length) ...@@ -385,7 +396,7 @@ sexp_get_string_length(struct sexp_input *input, unsigned length)
} }
static void static void
sexp_get_token(struct sexp_input *input) sexp_get_token(struct sexp_input *input, enum sexp_mode mode)
{ {
uint8_t c; uint8_t c;
...@@ -397,7 +408,7 @@ sexp_get_token(struct sexp_input *input) ...@@ -397,7 +408,7 @@ sexp_get_token(struct sexp_input *input)
{ {
case '0': case '1': case '2': case '3': case '4': case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': case '5': case '6': case '7': case '8': case '9':
sexp_get_string_length(input, c - '0'); sexp_get_string_length(input, mode, c - '0');
return; return;
case '(': case '(':
...@@ -420,12 +431,12 @@ sexp_get_token(struct sexp_input *input) ...@@ -420,12 +431,12 @@ sexp_get_token(struct sexp_input *input)
case '\t': case '\t':
case '\n': case '\n':
case '\r': case '\r':
if (input->mode != SEXP_ADVANCED) if (mode == SEXP_CANONICAL)
die("Whitespace encountered in canonical mode.\n"); die("Whitespace encountered in canonical mode.\n");
break; break;
case ';': /* Comments */ case ';': /* Comments */
if (input->mode != SEXP_ADVANCED) if (mode == SEXP_CANONICAL)
die("Comment encountered in canonical mode.\n"); die("Comment encountered in canonical mode.\n");
for (;;) for (;;)
...@@ -448,7 +459,7 @@ sexp_get_token(struct sexp_input *input) ...@@ -448,7 +459,7 @@ sexp_get_token(struct sexp_input *input)
default: default:
/* Ought to be a string */ /* Ought to be a string */
if (input->mode != SEXP_ADVANCED) if (mode != SEXP_ADVANCED)
die("Encountered advanced string in canonical mode.\n"); die("Encountered advanced string in canonical mode.\n");
sexp_get_string(input, c); sexp_get_string(input, c);
...@@ -675,10 +686,10 @@ sexp_put_display_end(struct sexp_output *output, unsigned indent) ...@@ -675,10 +686,10 @@ sexp_put_display_end(struct sexp_output *output, unsigned indent)
} }
static void static void
sexp_convert_string(struct sexp_input *input, struct sexp_output *output, sexp_convert_string(struct sexp_input *input, enum sexp_mode mode,
unsigned indent) struct sexp_output *output, unsigned indent)
{ {
sexp_get_token(input); sexp_get_token(input, mode);
if (input->token == SEXP_STRING) if (input->token == SEXP_STRING)
sexp_put_string(output, indent, &input->string); sexp_put_string(output, indent, &input->string);
else else
...@@ -686,18 +697,19 @@ sexp_convert_string(struct sexp_input *input, struct sexp_output *output, ...@@ -686,18 +697,19 @@ sexp_convert_string(struct sexp_input *input, struct sexp_output *output,
} }
static int static int
sexp_convert_item(struct sexp_input *input, struct sexp_output *output, sexp_convert_item(struct sexp_input *input, enum sexp_mode mode,
unsigned indent); struct sexp_output *output, unsigned indent);
static void static void
sexp_convert_list(struct sexp_input *input, struct sexp_output *output, sexp_convert_list(struct sexp_input *input, enum sexp_mode mode,
struct sexp_output *output,
unsigned indent) unsigned indent)
{ {
unsigned item; unsigned item;
for (item = 0;; item++) for (item = 0;; item++)
{ {
sexp_get_token(input); sexp_get_token(input, mode);
/* Check for end of list */ /* Check for end of list */
if (input->token == SEXP_LIST_END if (input->token == SEXP_LIST_END
...@@ -718,7 +730,7 @@ sexp_convert_list(struct sexp_input *input, struct sexp_output *output, ...@@ -718,7 +730,7 @@ sexp_convert_list(struct sexp_input *input, struct sexp_output *output,
sexp_put_newline(output, indent); sexp_put_newline(output, indent);
} }
if (!sexp_convert_item(input, output, indent)) if (!sexp_convert_item(input, mode, output, indent))
/* Should be detected above */ /* Should be detected above */
abort(); abort();
} }
...@@ -727,15 +739,15 @@ sexp_convert_list(struct sexp_input *input, struct sexp_output *output, ...@@ -727,15 +739,15 @@ sexp_convert_list(struct sexp_input *input, struct sexp_output *output,
static void static void
sexp_convert_file(struct sexp_input *input, struct sexp_output *output) sexp_convert_file(struct sexp_input *input, struct sexp_output *output)
{ {
sexp_get_token(input); sexp_get_token(input, SEXP_ADVANCED);
while (input->token != SEXP_EOF) while (input->token != SEXP_EOF)
{ {
sexp_convert_item(input, output, 0); sexp_convert_item(input, SEXP_ADVANCED, output, 0);
if (output->mode == SEXP_ADVANCED) if (output->mode == SEXP_ADVANCED)
sexp_put_newline(output, 0); sexp_put_newline(output, 0);
sexp_get_token(input); sexp_get_token(input, SEXP_ADVANCED);
} }
if (fflush(output->f) < 0) if (fflush(output->f) < 0)
...@@ -745,9 +757,10 @@ sexp_convert_file(struct sexp_input *input, struct sexp_output *output) ...@@ -745,9 +757,10 @@ sexp_convert_file(struct sexp_input *input, struct sexp_output *output)
static void static void
sexp_skip_token(struct sexp_input *input, enum sexp_token token) sexp_skip_token(struct sexp_input *input, enum sexp_mode mode,
enum sexp_token token)
{ {
sexp_get_token(input); sexp_get_token(input, mode);
if (input->token != token) if (input->token != token)
die("Syntax error.\n"); die("Syntax error.\n");
} }
...@@ -756,8 +769,8 @@ sexp_skip_token(struct sexp_input *input, enum sexp_token token) ...@@ -756,8 +769,8 @@ sexp_skip_token(struct sexp_input *input, enum sexp_token token)
* *
* Should be called after getting the first token. */ * Should be called after getting the first token. */
static int static int
sexp_convert_item(struct sexp_input *input, struct sexp_output *output, sexp_convert_item(struct sexp_input *input, enum sexp_mode mode,
unsigned indent) struct sexp_output *output, unsigned indent)
{ {
switch(input->token) switch(input->token)
{ {
...@@ -765,7 +778,7 @@ sexp_convert_item(struct sexp_input *input, struct sexp_output *output, ...@@ -765,7 +778,7 @@ sexp_convert_item(struct sexp_input *input, struct sexp_output *output,
input->level++; input->level++;
sexp_put_list_start(output, indent); sexp_put_list_start(output, indent);
sexp_convert_list(input, output, indent); sexp_convert_list(input, mode, output, indent);
sexp_put_list_end(output, indent); sexp_put_list_end(output, indent);
if (input->level) if (input->level)
...@@ -796,32 +809,36 @@ sexp_convert_item(struct sexp_input *input, struct sexp_output *output, ...@@ -796,32 +809,36 @@ sexp_convert_item(struct sexp_input *input, struct sexp_output *output,
break; break;
case SEXP_DISPLAY_START: case SEXP_DISPLAY_START:
sexp_put_display_start(output, indent); sexp_put_display_start(output, indent);
sexp_convert_string(input, output, indent); sexp_convert_string(input, mode, output, indent);
sexp_skip_token(input, SEXP_DISPLAY_END); sexp_skip_token(input, mode, SEXP_DISPLAY_END);
sexp_put_display_end(output, indent); sexp_put_display_end(output, indent);
sexp_convert_string(input, output, indent); sexp_convert_string(input, mode, output, indent);
break; break;
case SEXP_TRANSPORT_START: case SEXP_TRANSPORT_START:
if (input->mode != SEXP_ADVANCED) if (mode != SEXP_ADVANCED)
die("Base64 not allowed in canonical mode.\n"); die("Base64 not allowed in canonical mode.\n");
else else
{ {
unsigned old_level = input->level; unsigned old_level = input->level;
input->mode = SEXP_TRANSPORT; assert(input->coding == SEXP_PLAIN);
input->coding = SEXP_BASE64;
input->level = 0; input->level = 0;
base64_decode_init(&input->base64); base64_decode_init(&input->base64);
/* FIXME: sexp_convert_list is wrong. */
sexp_convert_list(input, SEXP_CANONICAL, output, indent);
sexp_convert_list(input, output, indent); input->coding = SEXP_PLAIN;
input->mode = SEXP_ADVANCED;
input->level = old_level; input->level = old_level;
break; break;
} }
case SEXP_TRANSPORT_END: case SEXP_TRANSPORT_END:
if (input->mode != SEXP_TRANSPORT /* FIXME: Should be moved do sexp_convert_transport */
|| input->level || !base64_decode_status(&input->base64)) if ( (input->coding != SEXP_BASE64)
|| input->level || !base64_decode_status(&input->base64))
die("Invalid base64.\n"); die("Invalid base64.\n");
break; break;
...@@ -837,7 +854,7 @@ main(int argc, char **argv) ...@@ -837,7 +854,7 @@ main(int argc, char **argv)
struct sexp_input input; struct sexp_input input;
struct sexp_output output; struct sexp_output output;
sexp_input_init(&input, stdin, SEXP_ADVANCED); sexp_input_init(&input, stdin);
sexp_output_init(&output, stdout, SEXP_ADVANCED); sexp_output_init(&output, stdout, SEXP_ADVANCED);
sexp_convert_file(&input, &output); sexp_convert_file(&input, &output);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment