aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2012-11-23 23:20:45 +0100
committerThomas White <taw@bitwiz.org.uk>2012-11-23 23:20:45 +0100
commit26b9654f1090cbe02915a501c3976192e7f029d3 (patch)
treebb027eefd8259045f317fbb0045c1411b1c767d8
parentc127216f2f7bc6e33252e08ee98782fefcaf7b8b (diff)
Break storycode stuff off into a separate library
-rw-r--r--.gitmodules3
-rw-r--r--Makefile.am11
m---------libstorycode0
-rw-r--r--src/frame.c59
-rw-r--r--src/frame.h1
-rw-r--r--src/storycode.c452
-rw-r--r--src/storycode.h49
-rw-r--r--tests/storycode_test.c74
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;
-}