From 115e8fbfe3af0e0556a58b34b2a52c79536628e0 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 7 Jan 2014 20:48:25 +0000 Subject: Initial work for new SC processor --- src/sc_parse.c | 400 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 400 insertions(+) create mode 100644 src/sc_parse.c (limited to 'src/sc_parse.c') diff --git a/src/sc_parse.c b/src/sc_parse.c new file mode 100644 index 0000000..e4cb94c --- /dev/null +++ b/src/sc_parse.c @@ -0,0 +1,400 @@ +/* + * sc_parse.c + * + * Copyright © 2013-2014 Thomas White + * + * This file is part of Colloquium. + * + * Colloquium is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include "sc_parse.h" + + +struct _scblocklist +{ + int n_blocks; + int max_blocks; + + struct scblock *blocks; +}; + + +struct _scblocklistiterator +{ + int pos; +}; + + +static int allocate_blocks(SCBlockList *bl) +{ + struct scblock *blocks_new; + + blocks_new = realloc(bl->blocks, bl->max_blocks*sizeof(struct scblock)); + if ( blocks_new == NULL ) { + return 1; + } + bl->blocks = blocks_new; + + return 0; +} + + +SCBlockList *sc_block_list_new() +{ + SCBlockList *bl; + + bl = calloc(1, sizeof(SCBlockList)); + if ( bl == NULL ) return NULL; + + bl->n_blocks = 0; + bl->max_blocks = 64; + bl->blocks = NULL; + if ( allocate_blocks(bl) ) { + free(bl); + return NULL; + } + + return bl; +} + + +void sc_block_list_free(SCBlockList *bl) +{ + int i; + + for ( i=0; in_blocks; i++ ) { + free(bl->blocks[i].name); + free(bl->blocks[i].options); + free(bl->blocks[i].contents); + } + free(bl->blocks); + free(bl); +} + + +struct scblock *sc_block_list_first(SCBlockList *bl, + SCBlockListIterator **piter) +{ + SCBlockListIterator *iter; + + if ( bl->n_blocks == 0 ) return NULL; + + iter = calloc(1, sizeof(SCBlockListIterator)); + if ( iter == NULL ) return NULL; + + iter->pos = 0; + *piter = iter; + + return &bl->blocks[0]; +} + + +struct scblock *sc_block_list_next(SCBlockList *bl, SCBlockListIterator *iter) +{ + iter->pos++; + if ( iter->pos == bl->n_blocks ) { + free(iter); + return NULL; + } + + return &bl->blocks[iter->pos]; +} + + +static int sc_block_list_add(SCBlockList *bl, size_t offset, + char *name, char *options, char *contents) +{ + if ( bl->n_blocks == bl->max_blocks ) { + bl->max_blocks += 64; + if ( allocate_blocks(bl) ) return 1; + } + + bl->blocks[bl->n_blocks].name = name; + bl->blocks[bl->n_blocks].options = options; + bl->blocks[bl->n_blocks].contents = contents; + bl->blocks[bl->n_blocks].offset = offset; + bl->n_blocks++; + + return 0; +} + + +static int get_subexpr(const char *sc, char *bk, char **pcontents, int *err) +{ + size_t ml; + int i; + int bct = 1; + int found = 0; + char *contents; + + *err = 0; + + ml = strlen(sc); + contents = malloc(ml+1); + if ( contents == NULL ) { + *err = -1; + return 0; + } + *pcontents = contents; + + for ( i=0; i 0) ) { + + /* Leftover buffer is empty? */ + if ( (j==1) && (tbuf[0]=='\0') ) return bl; + + tbuf[j] = '\0'; + if ( sc_block_list_add(bl, start, NULL, NULL, tbuf) ) + { + fprintf(stderr, + "Failed to add block.\n"); + sc_block_list_free(bl); + free(tbuf); + return NULL; + } + j = 0; + } + + return bl; +} + + +char *remove_blocks(const char *in, const char *blockname) +{ + SCBlockList *bl; + SCBlockListIterator *iter; + char *out; + struct scblock *b; + + bl = sc_find_blocks(in, NULL); + if ( bl == NULL ) { + printf("Failed to find blocks.\n"); + return NULL; + } + + out = malloc(strlen(in)+1); + if ( out == NULL ) return NULL; + out[0] = '\0'; + + for ( b = sc_block_list_first(bl, &iter); + b != NULL; + b = sc_block_list_next(bl, iter) ) + { + if ( b->name == NULL ) { + strcat(out, b->contents); + } else { + + if ( strcmp(blockname, b->name) != 0 ) { + strcat(out, "\\"); + strcat(out, b->name); + if ( b->options != NULL ) { + strcat(out, "["); + strcat(out, b->options); + strcat(out, "]"); + } + if ( b->contents != NULL ) { + strcat(out, "{"); + strcat(out, b->contents); + strcat(out, "}"); + } + + if ( (b->options == NULL) + && (b->contents == NULL) ) { + strcat(out, " "); + } + + } + + } + } + sc_block_list_free(bl); + + return out; +} + -- cgit v1.2.3