aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/storycode.c171
-rw-r--r--src/storycode.h9
-rw-r--r--tests/storycode_test.c13
3 files changed, 189 insertions, 4 deletions
diff --git a/src/storycode.c b/src/storycode.c
index 446d277..4adfe1b 100644
--- a/src/storycode.c
+++ b/src/storycode.c
@@ -27,19 +27,186 @@
#include <assert.h>
#include <stdlib.h>
+#include <string.h>
#include "storycode.h"
#include "presentation.h"
-struct frame *unpack_storycode(const char *sc)
+struct _scblocklist
+{
+ int n_blocks;
+ char **blocks;
+ int max_blocks;
+};
+
+
+struct _scblocklistiterator
+{
+ int pos;
+};
+
+
+static int allocate_blocks(SCBlockList *bl)
+{
+ char **blocks_new;
+
+ blocks_new = realloc(bl->blocks, bl->max_blocks*sizeof(char *));
+ 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)
+{
+ free(bl->blocks);
+ free(bl);
+}
+
+
+char *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];
+}
+
+
+char *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 *text)
+{
+ if ( bl->n_blocks == bl->max_blocks ) {
+ bl->max_blocks += 64;
+ if ( allocate_blocks(bl) ) return 1;
+ }
+
+ bl->blocks[bl->n_blocks] = text;
+ bl->n_blocks++;
+ return 0;
+}
+
+
+SCBlockList *sc_find_blocks(const char *sc, const char *blockname)
+{
+ SCBlockList *bl;
+ const char *pos;
+ char label[1024];
+
+ bl = sc_block_list_new();
+ if ( bl == NULL ) return NULL;
+
+ if ( strlen(blockname) > 1021 ) {
+ fprintf(stderr, "Block name '%s' too long.\n", blockname);
+ return NULL;
+ }
+
+ strcat(label, "\\");
+ strcat(label, blockname);
+ strcat(label, "{");
+
+ pos = sc;
+ do {
+
+ pos = strstr(pos, label);
+
+ if ( pos != NULL ) {
+
+ int i;
+ int bct = 1;
+ int found = 0;
+ int ml = strlen(pos);
+
+ pos += strlen(label);
+
+ for ( i=0; i<ml; i++ ) {
+ if ( pos[i] == '{' ) {
+ bct++;
+ } else if ( pos[i] == '}' ) {
+ bct--;
+ }
+ if ( bct == 0 ) {
+ found = 1;
+ break;
+ }
+ }
+
+ if ( (!found) || (bct != 0) ) {
+ fprintf(stderr, "Parse error while looking for"
+ " block '%s'\n", blockname);
+ sc_block_list_free(bl);
+ return NULL;
+ }
+
+ if ( sc_block_list_add(bl, strndup(pos, i)) ) {
+ fprintf(stderr, "Failed to add block.\n");
+ sc_block_list_free(bl);
+ return NULL;
+ }
+
+ pos += i+1;
+ printf("Remaining text '%s'\n", pos);
+
+ }
+
+ } while ( pos != NULL );
+
+ return bl;
+}
+
+
+/* Unpack level 2 StoryCode (content + subframes) into frames */
+struct frame *sc_unpack(const char *sc)
{
struct frame *fr;
fr = calloc(1, sizeof(struct frame));
if ( fr == NULL ) return NULL;
-
+
return fr;
}
diff --git a/src/storycode.h b/src/storycode.h
index 6e106e3..240900d 100644
--- a/src/storycode.h
+++ b/src/storycode.h
@@ -27,8 +27,13 @@
#include <config.h>
#endif
+typedef struct _scblocklist SCBlockList;
+typedef struct _scblocklistiterator SCBlockListIterator;
-extern char *sc_get_final_font(const char *sc);
-extern char *sc_get_final_text_colour(const char *sc);
+char *sc_block_list_first(SCBlockList *bl, SCBlockListIterator **piter);
+char *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);
#endif /* STORYCODE_H */
diff --git a/tests/storycode_test.c b/tests/storycode_test.c
index 4ff4977..4ffc08c 100644
--- a/tests/storycode_test.c
+++ b/tests/storycode_test.c
@@ -32,6 +32,19 @@
int main(int argc, char *argv[])
{
+ SCBlockList *bl;
+ SCBlockListIterator *iter;
+ char *b;
+
+ bl = sc_find_blocks("\\bg{wibble \\f{wobble}}\\bg{rwawr}Wobble", "bg");
+
+ for ( b = sc_block_list_first(bl, &iter);
+ b != NULL;
+ b = sc_block_list_next(bl, iter) )
+ {
+ printf("'%s'\n", b);
+ }
+ sc_block_list_free(bl);
return 0;
}