diff options
-rw-r--r-- | .gitmodules | 3 | ||||
-rw-r--r-- | Makefile.am | 11 | ||||
m--------- | libstorycode | 0 | ||||
-rw-r--r-- | src/frame.c | 59 | ||||
-rw-r--r-- | src/frame.h | 1 | ||||
-rw-r--r-- | src/storycode.c | 452 | ||||
-rw-r--r-- | src/storycode.h | 49 | ||||
-rw-r--r-- | tests/storycode_test.c | 74 |
8 files changed, 67 insertions, 582 deletions
diff --git a/.gitmodules b/.gitmodules index f6fb2fb..93a5aa7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "harfatum"] path = harfatum url = ssh://git@git.bitwiz.org.uk/harfatum.git +[submodule "libstorycode"] + path = libstorycode + url = ssh://git@git.bitwiz.org.uk/libstorycode.git diff --git a/Makefile.am b/Makefile.am index b655539..12e3208 100644 --- a/Makefile.am +++ b/Makefile.am @@ -9,13 +9,13 @@ AM_CPPFLAGS = -DDATADIR=\""$(datadir)"\" -I$(top_builddir)/lib \ -I$(top_srcdir)/lib LDADD = $(top_builddir)/lib/libgnu.a @IGNORE_UNUSED_LIBRARIES_CFLAGS@ -src_colloquium_SOURCES = src/colloquium.c src/storycode.c src/render.c \ +src_colloquium_SOURCES = src/colloquium.c src/render.c \ src/layout.c src/mainwindow.c src/presentation.c \ src/stylesheet.c src/loadsave.c src/frame.c INCLUDES = "-I$(top_srcdir)/data" -EXTRA_DIST += src/layout.h src/presentation.h src/render.h src/storycode.h \ +EXTRA_DIST += src/layout.h src/presentation.h src/render.h \ src/stylesheet.h src/loadsave.h colloquiumdir = $(datadir)/colloquium @@ -27,11 +27,8 @@ icons_DATA = data/colloquium-select.svg data/colloquium-text.svg \ EXTRA_DIST += $(colloquium_DATA) -noinst_PROGRAMS = tests/storycode_test tests/render_test tests/render_test_sc1 -TESTS = tests/storycode_test tests/render_test tests/render_test_sc1 - -tests_storycode_test_SOURCES = tests/storycode_test.c src/storycode.c \ - src/frame.c +noinst_PROGRAMS = tests/render_test tests/render_test_sc1 +TESTS = tests/render_test tests/render_test_sc1 tests_render_test_SOURCES = tests/render_test.c src/storycode.c src/render.c \ src/layout.c src/frame.c diff --git a/libstorycode b/libstorycode new file mode 160000 +Subproject 4edc5a791fdb30662f5a37e75fba1ea1821cc2c diff --git a/src/frame.c b/src/frame.c index 637fff1..75a9810 100644 --- a/src/frame.c +++ b/src/frame.c @@ -82,3 +82,62 @@ struct frame *add_subframe(struct frame *fr) return n; } + +static void show_heirarchy(struct frame *fr, const char *t) +{ + int i; + char tn[1024]; + + strcpy(tn, t); + strcat(tn, " |-> "); + + printf("%s%p %s\n", t, fr, fr->sc); + + for ( i=0; i<fr->num_ro; i++ ) { + if ( fr->rendering_order[i] != fr ) { + show_heirarchy(fr->rendering_order[i], tn); + } else { + printf("%s<this frame>\n", tn); + } + } + +} + + +static void recursive_unpack(struct frame *fr, const char *sc) +{ + SCBlockList *bl; + SCBlockListIterator *iter; + struct scblock *b; + + bl = sc_find_blocks(sc, "f"); + + for ( b = sc_block_list_first(bl, &iter); + b != NULL; + b = sc_block_list_next(bl, iter) ) + { + struct frame *sfr; + sfr = add_subframe(fr); + sfr->sc = remove_blocks(b->contents, "f"); + recursive_unpack(sfr, b->contents); + } + sc_block_list_free(bl); +} + + +/* Unpack level 2 StoryCode (content + subframes) into frames */ +struct frame *sc_unpack(const char *sc) +{ + struct frame *fr; + + fr = frame_new(); + if ( fr == NULL ) return NULL; + + fr->sc = remove_blocks(sc, "f"); + recursive_unpack(fr, sc); + + show_heirarchy(fr, ""); + + return fr; +} + diff --git a/src/frame.h b/src/frame.h index 7f56889..8c1797f 100644 --- a/src/frame.h +++ b/src/frame.h @@ -58,5 +58,6 @@ struct frame extern struct frame *frame_new(void); extern struct frame *add_subframe(struct frame *fr); +extern struct frame *sc_unpack(const char *sc); #endif /* FRAME_H */ diff --git a/src/storycode.c b/src/storycode.c deleted file mode 100644 index 1ef01d7..0000000 --- a/src/storycode.c +++ /dev/null @@ -1,452 +0,0 @@ -/* - * storycode.c - * - * Colloquium - A tiny presentation program - * - * Copyright (c) 2012 Thomas White <taw@bitwiz.org.uk> - * - * This program 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 <http://www.gnu.org/licenses/>. - * - */ - - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <assert.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> - -#include "storycode.h" -#include "frame.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; i<bl->n_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, - 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->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<ml; i++ ) { - if ( sc[i] == bk[0] ) { - bct++; - } else if ( sc[i] == bk[1] ) { - bct--; - } - if ( bct == 0 ) { - found = 1; - break; - } - contents[i] = sc[i]; - } - - if ( (!found) || (bct != 0) ) { - *err = 1; - return 0; - } - - contents[i] = '\0'; - return i+1; -} - - -static size_t read_block(const char *sc, char **pname, char **options, - char **contents, int *err) -{ - size_t l, i, j; - char *name; - int done; - - *err = 0; - - l = strlen(sc); - i = 0; j = 0; - name = malloc(l+1); - if ( name == NULL ) { - *err = 1; - return 0; - } - - done = 0; - do { - - char c = sc[i]; - - if ( isalnum(c) ) { - name[j++] = c; - i++; - } else { - /* Found the end of the name */ - done = 1; - } - - } while ( !done && (i<l) ); - - name[j] = '\0'; - - if ( !done ) { - *err = 1; - printf("Couldn't find end of block beginning '%s'\n", sc); - return 0; - } - *pname = name; - - if ( sc[i] == '[' ) { - - i += get_subexpr(sc+i+1, "[]", options, err) + 1; - if ( *err ) { - printf("Couldn't find end of options '%s'\n", sc+i); - return 0; - } - - } else { - *options = NULL; - } - - if ( sc[i] == '{' ) { - - i += get_subexpr(sc+i+1, "{}", contents, err) + 1; - if ( *err ) { - printf("Couldn't find end of content '%s'\n", sc+i); - return 0; - } - - } else { - *contents = NULL; - } - - return i+1; -} - - -SCBlockList *sc_find_blocks(const char *sc, const char *blockname) -{ - SCBlockList *bl; - char *tbuf; - size_t len, i, j; - - bl = sc_block_list_new(); - if ( bl == NULL ) return NULL; - - len = strlen(sc); - tbuf = malloc(len+1); - if ( tbuf == NULL ) { - sc_block_list_free(bl); - return NULL; - } - - i = 0; j = 0; - do { - - if ( sc[i] == '\\' ) { - - int err; - char *name = NULL; - char *options = NULL; - char *contents = NULL; - - if ( (blockname == NULL) && (j != 0) ) { - tbuf[j] = '\0'; - if ( sc_block_list_add(bl, NULL, NULL, - strdup(tbuf)) ) - { - fprintf(stderr, - "Failed to add block.\n"); - sc_block_list_free(bl); - free(tbuf); - return NULL; - } - j = 0; - } - - i += read_block(sc+i+1, &name, &options, &contents, - &err); - if ( err ) { - printf("Parse error\n"); - sc_block_list_free(bl); - free(tbuf); - return NULL; - } - - if ( (blockname == NULL) - || ((blockname != NULL) && !strcmp(blockname, name)) ) - { - if ( sc_block_list_add(bl, name, options, - contents) ) - { - fprintf(stderr, - "Failed to add block.\n"); - sc_block_list_free(bl); - free(tbuf); - return NULL; - } - } - - } else { - - tbuf[j++] = sc[i++]; - } - - } while ( i<len ); - - if ( (blockname == NULL) && (j != 0) ) { - tbuf[j] = '\0'; - if ( sc_block_list_add(bl, NULL, NULL, tbuf) ) - { - fprintf(stderr, - "Failed to add block.\n"); - sc_block_list_free(bl); - free(tbuf); - return NULL; - } - j = 0; - } - - return bl; -} - - -static 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; -} - - -static void recursive_unpack(struct frame *fr, const char *sc) -{ - SCBlockList *bl; - SCBlockListIterator *iter; - struct scblock *b; - - bl = sc_find_blocks(sc, "f"); - - for ( b = sc_block_list_first(bl, &iter); - b != NULL; - b = sc_block_list_next(bl, iter) ) - { - struct frame *sfr; - sfr = add_subframe(fr); - sfr->sc = remove_blocks(b->contents, "f"); - recursive_unpack(sfr, b->contents); - } - sc_block_list_free(bl); -} - - -static void show_heirarchy(struct frame *fr, const char *t) -{ - int i; - char tn[1024]; - - strcpy(tn, t); - strcat(tn, " |-> "); - - printf("%s%p %s\n", t, fr, fr->sc); - - for ( i=0; i<fr->num_ro; i++ ) { - if ( fr->rendering_order[i] != fr ) { - show_heirarchy(fr->rendering_order[i], tn); - } else { - printf("%s<this frame>\n", tn); - } - } - -} - - -/* Unpack level 2 StoryCode (content + subframes) into frames */ -struct frame *sc_unpack(const char *sc) -{ - struct frame *fr; - - fr = frame_new(); - if ( fr == NULL ) return NULL; - - fr->sc = remove_blocks(sc, "f"); - recursive_unpack(fr, sc); - - show_heirarchy(fr, ""); - - return fr; -} diff --git a/src/storycode.h b/src/storycode.h deleted file mode 100644 index 8f02d48..0000000 --- a/src/storycode.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * storycode.h - * - * Colloquium - A tiny presentation program - * - * Copyright (c) 2012 Thomas White <taw@bitwiz.org.uk> - * - * This program 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 <http://www.gnu.org/licenses/>. - * - */ - -#ifndef STORYCODE_H -#define STORYCODE_H - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -typedef struct _scblocklist SCBlockList; -typedef struct _scblocklistiterator SCBlockListIterator; - -struct scblock -{ - char *name; - char *options; - char *contents; -}; - -struct scblock *sc_block_list_first(SCBlockList *bl, - SCBlockListIterator **piter); -struct scblock *sc_block_list_next(SCBlockList *bl, SCBlockListIterator *iter); - -extern SCBlockList *sc_find_blocks(const char *sc, const char *blockname); -extern void sc_block_list_free(SCBlockList *bl); - -extern struct frame *sc_unpack(const char *sc); - -#endif /* STORYCODE_H */ diff --git a/tests/storycode_test.c b/tests/storycode_test.c deleted file mode 100644 index 5fbde5a..0000000 --- a/tests/storycode_test.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * storycode_test.c - * - * Colloquium - A tiny presentation program - * - * Copyright (c) 2012 Thomas White <taw@bitwiz.org.uk> - * - * This program 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 <http://www.gnu.org/licenses/>. - * - */ - - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> - -#include "../src/storycode.h" - - -int main(int argc, char *argv[]) -{ - SCBlockList *bl; - SCBlockListIterator *iter; - struct scblock *b; - const char *tt = "\\bg[a=b]{wibble \\f{wobble}}\\bg{rwawr}\\muhu Wobble" - "\\wibble{}\\f{wibble \\bg[muhu]{wobble}}\\frib[\\f] f"; - - printf("'%s' ->\n", tt); - bl = sc_find_blocks(tt, "bg"); - - if ( bl == NULL ) { - printf("Failed to find blocks.\n"); - return 1; - } - - for ( b = sc_block_list_first(bl, &iter); - b != NULL; - b = sc_block_list_next(bl, iter) ) - { - printf(" \\%s [%s] {%s}\n", b->name, b->options, b->contents); - } - sc_block_list_free(bl); - - printf("->\n"); - bl = sc_find_blocks(tt, NULL); - - if ( bl == NULL ) { - printf("Failed to find blocks.\n"); - return 1; - } - - for ( b = sc_block_list_first(bl, &iter); - b != NULL; - b = sc_block_list_next(bl, iter) ) - { - printf(" \\%s [%s] {%s}\n", b->name, b->options, b->contents); - } - sc_block_list_free(bl); - - return 0; -} |