commit b0e41e3f6bfe7a4033153c633a7e7f719978c806
Author: nibo <nibo@relim.de>
Date: Sun, 26 May 2024 17:33:14 +0200
Initial commit
Diffstat:
| A | Makefile | | | 2 | ++ |
| A | chordpro.c | | | 606 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | chordpro.h | | | 77 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | lorid.c | | | 89 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
4 files changed, 774 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -0,0 +1,2 @@
+all:
+ $(CC) -Wall -Wextra -O2 chordpro.c lorid.c -o lorid
diff --git a/chordpro.c b/chordpro.c
@@ -0,0 +1,606 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include "chordpro.h"
+
+char *string_remove_leading_whitespace(const char *str)
+{
+ int i = 0;
+ while (str[i] == ' ' || str[i] == '\t') {
+ i++;
+ }
+ return strdup(&str[i]);
+}
+
+
+static const char *environment_directives[] = {
+ "start_of_chorus", "soc", "end_of_chorus", "eoc", "chorus",
+ "start_of_verse", "sov", "end_of_verse", "eov",
+ "start_of_bridge", "sob", "end_of_bridge", "eob",
+ "start_of_tab", "sot", "end_of_tab", "eot",
+ "start_of_grid", "sog", "end_of_grid", "eog", NULL
+};
+
+static const char *metadata_directives[] = {
+ "title", "sorttitle", "subtitle",
+ "artist", "composer", "lyricist",
+ "copyright", "album", "year", "key",
+ "time", "tempo", "duration", "capo",
+ "meta", NULL
+};
+
+static const char *formatting_directives[] = {
+ "comment", "c", "highlight", "comment_italic", "ci",
+ "comment_box", "cb", "image", NULL
+};
+
+static const char *preamble_directives[] = {
+ "new_song", "ns", NULL
+};
+
+static const char *the_state(enum State state)
+{
+ switch (state) {
+ case STATE_LYRICS:
+ return "STATE_LYRICS";
+ case STATE_DIRECTIVE_NAME:
+ return "STATE_DIRECTIVE_NAME";
+ case STATE_DIRECTIVE_VALUE:
+ return "STATE_DIRECTIVE_VALUE";
+ case STATE_CHORD:
+ return "STATE_CHORD";
+ }
+ return "";
+}
+
+static const char *dtype(enum DirectiveType dtype)
+{
+ switch (dtype) {
+ case DT_ENVIRONMENT:
+ return "DT_ENVIRONMENT";
+ case DT_METADATA:
+ return "DT_METADATA";
+ case DT_FORMATTING:
+ return "DT_FORMATTING";
+ case DT_PREAMBLE:
+ return "DT_PREAMBLE";
+ case DT_CUSTOM:
+ return "DT_CUSTOM";
+ }
+ return "";
+}
+
+const char *the_stype(enum SectionType stype)
+{
+ switch (stype) {
+ case ST_NOTHING:
+ return "ST_NOTHING";
+ case ST_CHORUS:
+ return "ST_CHORUS";
+ case ST_VERSE:
+ return "ST_VERSE";
+ case ST_BRIDGE:
+ return "ST_BRIDGE";
+ case ST_TAB:
+ return "ST_TAB";
+ case ST_GRID:
+ return "ST_GRID";
+ case ST_NEWSONG:
+ return "ST_NEWSONG";
+ }
+ return "";
+}
+
+static const char *pos(enum Position pos)
+{
+ switch (pos) {
+ case POS_NOTHING:
+ return "POS_NOTHING";
+ case POS_BEGIN:
+ return "POS_BEGIN";
+ case POS_END:
+ return "POS_END";
+ }
+ return "";
+}
+
+const char *the_style(enum LineStyle style)
+{
+ switch (style) {
+ case LS_NORMAL:
+ return "LS_NORMAL";
+ case LS_GREY_BACKGROUND:
+ return "LS_GREY_BACKGROUND";
+ case LS_ITALIC:
+ return "LS_ITALIC";
+ case LS_BOX:
+ return "LS_BOX";
+ }
+ return "";
+}
+
+struct ChoMetadata *cho_metadata_new(void)
+{
+ struct ChoMetadata *meta = malloc(sizeof(struct ChoMetadata));
+ meta->name = NULL;
+ meta->value = NULL;
+ return meta;
+}
+
+struct ChoMetadata *cho_metadata_split(const char *directive_value)
+{
+ struct ChoMetadata *meta = cho_metadata_new();
+ char *value = string_remove_leading_whitespace(directive_value);
+ int i = 0;
+ int n = 0;
+ int v = 0;
+ bool is_name = true;
+ while (value[i] != 0) {
+ if (value[i] == ' ') {
+ meta->name = realloc(meta->name, (n+1) * sizeof(char));
+ meta->name[n] = 0;
+ is_name = false;
+ } else {
+ if (is_name) {
+ meta->name = realloc(meta->name, (n+1) * sizeof(char));
+ meta->name[n] = value[i];
+ n++;
+ } else {
+ meta->value = realloc(meta->value, (v+1) * sizeof(char));
+ meta->value[v] = value[i];
+ v++;
+ }
+ }
+ i++;
+ }
+ meta->value = realloc(meta->value, (v+1) * sizeof(char));
+ meta->value[v] = 0;
+ free(value);
+ if (v > 1) {
+ return meta;
+ } else {
+ free(meta->name);
+ free(meta->value);
+ free(meta);
+ fprintf(stderr, "INFO: Failed to parse directive 'meta'.\n");
+ return NULL;
+ }
+}
+
+struct ChoChord *cho_chord_new(void)
+{
+ struct ChoChord *chord = malloc(sizeof(struct ChoChord));
+ chord->index_in_lyrics = -1;
+ chord->chord = NULL;
+ return chord;
+}
+
+struct ChoLine *cho_line_new(void)
+{
+ struct ChoLine *line = malloc(sizeof(struct ChoLine));
+ line->style = LS_NORMAL;
+ line->chords = NULL;
+ line->lyrics = NULL;
+ return line;
+}
+
+struct ChoSection *cho_section_new(void)
+{
+ struct ChoSection *section = malloc(sizeof(struct ChoSection));
+ section->type = ST_NOTHING;
+ section->name = NULL;
+ section->lines = NULL;
+ return section;
+}
+
+struct ChoSong *cho_song_new(void)
+{
+ struct ChoSong *song = malloc(sizeof(struct ChoSong));
+ song->metadata = NULL;
+ song->sections = NULL;
+ return song;
+}
+
+void cho_song_free(struct ChoSong *song)
+{
+ int i = 0;
+ int k = 0;
+ int c = 0;
+ while (song->metadata[i] != NULL) {
+ free(song->metadata[i]->name);
+ free(song->metadata[i]->value);
+ free(song->metadata[i]);
+ i++;
+ }
+ free(song->metadata);
+ i = 0;
+ while (song->sections[i] != NULL) {
+ free(song->sections[i]->name);
+ while (song->sections[i]->lines[k] != NULL) {
+ free(song->sections[i]->lines[k]->lyrics);
+ while (song->sections[i]->lines[k]->chords[c] != NULL) {
+ free(song->sections[i]->lines[k]->chords[c]->chord);
+ free(song->sections[i]->lines[k]->chords[c]);
+ c++;
+ }
+ free(song->sections[i]->lines[k]->chords);
+ free(song->sections[i]->lines[k]);
+ c = 0;
+ k++;
+ }
+ free(song->sections[i]->lines);
+ free(song->sections[i]);
+ k = 0;
+ i++;
+ }
+ free(song->sections);
+ free(song);
+}
+
+struct ChoDirective *directive_parse(const char *name)
+{
+ struct ChoDirective *directive = malloc(sizeof(struct ChoDirective));
+ directive->style = LS_NORMAL;
+ int i = 0;
+ if (
+ strcmp(name, environment_directives[0]) == 0 ||
+ strcmp(name, environment_directives[1]) == 0
+ ) {
+ directive->dtype = DT_ENVIRONMENT;
+ directive->position = POS_BEGIN;
+ directive->stype = ST_CHORUS;
+ goto END;
+ } else if (
+ strcmp(name, environment_directives[2]) == 0 ||
+ strcmp(name, environment_directives[3]) == 0
+ ) {
+ directive->dtype = DT_ENVIRONMENT;
+ directive->position = POS_END;
+ directive->stype = ST_CHORUS;
+ goto END;
+ } else if (
+ strcmp(name, environment_directives[5]) == 0 ||
+ strcmp(name, environment_directives[6]) == 0
+ ) {
+ directive->dtype = DT_ENVIRONMENT;
+ directive->position = POS_BEGIN;
+ directive->stype = ST_VERSE;
+ goto END;
+ } else if (
+ strcmp(name, environment_directives[7]) == 0 ||
+ strcmp(name, environment_directives[8]) == 0
+ ) {
+ directive->dtype = DT_ENVIRONMENT;
+ directive->position = POS_END;
+ directive->stype = ST_VERSE;
+ goto END;
+ } else if (
+ strcmp(name, environment_directives[9]) == 0 ||
+ strcmp(name, environment_directives[10]) == 0
+ ) {
+ directive->dtype = DT_ENVIRONMENT;
+ directive->position = POS_BEGIN;
+ directive->stype = ST_BRIDGE;
+ goto END;
+ } else if (
+ strcmp(name, environment_directives[11]) == 0 ||
+ strcmp(name, environment_directives[12]) == 0
+ ) {
+ directive->dtype = DT_ENVIRONMENT;
+ directive->position = POS_END;
+ directive->stype = ST_BRIDGE;
+ goto END;
+ } else if (
+ strcmp(name, environment_directives[13]) == 0 ||
+ strcmp(name, environment_directives[14]) == 0
+ ) {
+ directive->dtype = DT_ENVIRONMENT;
+ directive->position = POS_BEGIN;
+ directive->stype = ST_TAB;
+ goto END;
+ } else if (
+ strcmp(name, environment_directives[15]) == 0 ||
+ strcmp(name, environment_directives[16]) == 0
+ ) {
+ directive->dtype = DT_ENVIRONMENT;
+ directive->position = POS_END;
+ directive->stype = ST_TAB;
+ goto END;
+ } else if (
+ strcmp(name, environment_directives[17]) == 0 ||
+ strcmp(name, environment_directives[18]) == 0
+ ) {
+ directive->dtype = DT_ENVIRONMENT;
+ directive->position = POS_BEGIN;
+ directive->stype = ST_GRID;
+ goto END;
+ } else if (
+ strcmp(name, environment_directives[19]) == 0 ||
+ strcmp(name, environment_directives[20]) == 0
+ ) {
+ directive->dtype = DT_ENVIRONMENT;
+ directive->position = POS_END;
+ directive->stype = ST_GRID;
+ goto END;
+ }
+ while (metadata_directives[i] != NULL) {
+ if (strcmp(metadata_directives[i], name) == 0) {
+ directive->dtype = DT_METADATA;
+ directive->stype = ST_NOTHING;
+ directive->position = POS_NOTHING;
+ goto END;
+ }
+ i++;
+ }
+ i = 0;
+ if (
+ strcmp(formatting_directives[0], name) == 0 ||
+ strcmp(formatting_directives[1], name) == 0 ||
+ strcmp(formatting_directives[2], name) == 0
+ ) {
+ directive->style = LS_GREY_BACKGROUND;
+ directive->dtype = DT_FORMATTING;
+ directive->stype = ST_NOTHING;
+ directive->position = POS_NOTHING;
+ goto END;
+ } else if (
+ strcmp(formatting_directives[3], name) == 0 ||
+ strcmp(formatting_directives[4], name) == 0
+ ) {
+ directive->style = LS_ITALIC;
+ directive->dtype = DT_FORMATTING;
+ directive->stype = ST_NOTHING;
+ directive->position = POS_NOTHING;
+ goto END;
+ } else if (
+ strcmp(formatting_directives[5], name) == 0 ||
+ strcmp(formatting_directives[4], name) == 0
+ ) {
+ directive->style = LS_BOX;
+ directive->dtype = DT_FORMATTING;
+ directive->stype = ST_NOTHING;
+ directive->position = POS_NOTHING;
+ goto END;
+ }
+ while (preamble_directives[i] != NULL) {
+ if (strcmp(preamble_directives[i], name) == 0) {
+ directive->dtype = DT_PREAMBLE;
+ directive->stype = ST_NEWSONG;
+ directive->position = POS_NOTHING;
+ goto END;
+ }
+ i++;
+ }
+ directive->dtype = DT_CUSTOM;
+ directive->stype = ST_NOTHING;
+ directive->position = POS_NOTHING;
+END:
+ return directive;
+}
+
+struct ChoSong *cho_parse(FILE *fp)
+{
+ struct ChoSong *song = cho_song_new();
+ int s = 0;
+ song->sections = malloc((s+1) * sizeof(struct ChoSection *));
+ song->sections[s] = cho_section_new();
+ int li = 0;
+ song->sections[s]->lines = realloc(song->sections[s]->lines, (li+1) * sizeof(struct ChoLine *));
+ song->sections[s]->lines[li] = cho_line_new();
+ int dn = 0;
+ int dv = 0;
+ int ch = 0;
+ int c = 0;
+ int m = 0;
+ int ly = 0;
+ char buf;
+ size_t read;
+ char directive_name[16];
+ char directive_value[512];
+ char chord[15];
+ enum State state = STATE_LYRICS;
+ struct ChoDirective *directive = NULL;
+ struct ChoMetadata *metadata = NULL;
+ while (feof(fp) == 0) {
+ read = fread(&buf, 1, 1, fp);
+ if (read == 1) {
+ // printf("state: %s, buf: %c\n", the_state(state), buf);
+ switch (state) {
+ case STATE_LYRICS:
+ if (buf == '{') {
+ state = STATE_DIRECTIVE_NAME;
+ break;
+ }
+ if (buf == '[') {
+ state = STATE_CHORD;
+ break;
+ }
+ if (buf == '\n') {
+ song->sections[s]->lines[li]->lyrics = realloc(song->sections[s]->lines[li]->lyrics, (ly+1) * sizeof(char));
+ song->sections[s]->lines[li]->lyrics[ly] = 0;
+ ly = 0;
+ song->sections[s]->lines[li]->chords = realloc(song->sections[s]->lines[li]->chords, (c+1) * sizeof(struct ChoChord *));
+ song->sections[s]->lines[li]->chords[c] = NULL;
+ c = 0;
+ li++;
+ song->sections[s]->lines = realloc(song->sections[s]->lines, (li+1) * sizeof(struct ChoLine *));
+ song->sections[s]->lines[li] = cho_line_new();
+ break;
+ }
+ song->sections[s]->lines[li]->lyrics = realloc(song->sections[s]->lines[li]->lyrics, (ly+1) * sizeof(char));
+ song->sections[s]->lines[li]->lyrics[ly] = buf;
+ ly++;
+ break;
+ case STATE_DIRECTIVE_NAME:
+ if (buf == '}') {
+ directive_name[dn] = 0;
+ dn = 0;
+ directive = directive_parse(directive_name);
+ /* printf(
+ "directive: '%s'\ndtype: %s, stype: %s, position: %s\n",
+ directive_name, dtype(directive->dtype), the_stype(directive->stype), pos(directive->position)
+ ); */
+ switch (directive->dtype) {
+ case DT_ENVIRONMENT:
+ switch (directive->position) {
+ case POS_BEGIN:
+ free(song->sections[s]->lines[li]);
+ song->sections[s]->lines[li] = NULL;
+ s++;
+ song->sections = realloc(song->sections, (s+1) * sizeof(struct ChoSection *));
+ song->sections[s] = cho_section_new();
+ song->sections[s]->type = directive->stype;
+ li = 0;
+ song->sections[s]->lines = malloc(sizeof(struct ChoLine *));
+ song->sections[s]->lines[li] = cho_line_new();
+ break;
+ case POS_END:
+ if (directive->stype == song->sections[s]->type) {
+ free(song->sections[s]->lines[li]);
+ song->sections[s]->lines[li] = NULL;
+ s++;
+ song->sections = realloc(song->sections, (s+1) * sizeof(struct ChoSection *));
+ song->sections[s] = cho_section_new();
+ li = 0;
+ song->sections[s]->lines = malloc(sizeof(struct ChoLine *));
+ song->sections[s]->lines[li] = cho_line_new();
+ }
+ break;
+ }
+ break;
+ case DT_METADATA:
+ fprintf(stderr, "INFO: Metadata directive '%s' has no value.\n", directive_name);
+ song->metadata = realloc(song->metadata, (m+1) * sizeof(struct ChoMetadata *));
+ song->metadata[m] = cho_metadata_new();
+ song->metadata[m]->name = strdup(directive_name);
+ m++;
+ memset(directive_name, 0, strlen(directive_name));
+ break;
+ case DT_FORMATTING:
+ fprintf(stderr, "INFO: Formatting directive '%s' has no value.\n", directive_name);
+ break;
+ case DT_PREAMBLE:
+ break;
+ case DT_CUSTOM:
+ break;
+ }
+ free(directive);
+ directive = NULL;
+ state = STATE_LYRICS;
+ break;
+ }
+ if (buf == ':') {
+ directive_name[dn] = 0;
+ dn = 0;
+ state = STATE_DIRECTIVE_VALUE;
+ break;
+ }
+ directive_name[dn] = buf;
+ dn++;
+ break;
+ case STATE_DIRECTIVE_VALUE:
+ if (buf == '}') {
+ directive_value[dv] = 0;
+ dv = 0;
+ directive = directive_parse(directive_name);
+ /* printf(
+ "directive: '%s'\ndtype: %s, stype: %s, position: %s\n",
+ directive_name, dtype(directive->dtype), the_stype(directive->stype), pos(directive->position)
+ ); */
+ switch (directive->dtype) {
+ case DT_ENVIRONMENT:
+ switch (directive->position) {
+ case POS_BEGIN:
+ free(song->sections[s]->lines[li]);
+ song->sections[s]->lines[li] = NULL;
+ s++;
+ song->sections = realloc(song->sections, (s+1) * sizeof(struct ChoSection *));
+ song->sections[s] = cho_section_new();
+ song->sections[s]->type = directive->stype;
+ song->sections[s]->name = string_remove_leading_whitespace(directive_value);
+ li = 0;
+ song->sections[s]->lines = malloc(sizeof(struct ChoLine *));
+ song->sections[s]->lines[li] = cho_line_new();
+ break;
+ case POS_END:
+ if (directive->stype == song->sections[s]->type) {
+ free(song->sections[s]->lines[li]);
+ song->sections[s]->lines[li] = NULL;
+ s++;
+ song->sections = realloc(song->sections, (s+1) * sizeof(struct ChoSection *));
+ song->sections[s] = cho_section_new();
+ li = 0;
+ song->sections[s]->lines = malloc(sizeof(struct ChoLine *));
+ song->sections[s]->lines[li] = cho_line_new();
+ }
+ break;
+ }
+ break;
+ case DT_METADATA:
+ if (strcmp(directive_name, "meta") == 0) {
+ metadata = cho_metadata_split(directive_value);
+ if (metadata != NULL) {
+ song->metadata = realloc(song->metadata, (m+1) * sizeof(struct ChoMetadata *));
+ song->metadata[m] = metadata;
+ m++;
+ }
+ } else {
+ song->metadata = realloc(song->metadata, (m+1) * sizeof(struct ChoMetadata *));
+ song->metadata[m] = cho_metadata_new();
+ song->metadata[m]->name = strdup(directive_name);
+ song->metadata[m]->value = string_remove_leading_whitespace(directive_value);
+ m++;
+ }
+ break;
+ case DT_FORMATTING:
+ song->sections[s]->lines[li]->style = directive->style;
+ song->sections[s]->lines[li]->lyrics = string_remove_leading_whitespace(directive_value);
+ ly = strlen(song->sections[s]->lines[li]->lyrics);
+ break;
+ case DT_PREAMBLE:
+ break;
+ case DT_CUSTOM:
+ break;
+ }
+ memset(directive_value, 0, strlen(directive_value));
+ free(directive);
+ directive = NULL;
+ state = STATE_LYRICS;
+ break;
+ }
+ directive_value[dv] = buf;
+ dv++;
+ break;
+ case STATE_CHORD:
+ if (buf == ']') {
+ chord[ch] = 0;
+ ch = 0;
+ song->sections[s]->lines[li]->chords = realloc(song->sections[s]->lines[li]->chords, (c+1) * sizeof(struct ChoChord *));
+ song->sections[s]->lines[li]->chords[c] = cho_chord_new();
+ song->sections[s]->lines[li]->chords[c]->index_in_lyrics = ly;
+ song->sections[s]->lines[li]->chords[c]->chord = strdup(chord);
+ memset(chord, 0, strlen(chord));
+ c++;
+ state = STATE_LYRICS;
+ break;
+ }
+ chord[ch] = buf;
+ ch++;
+ break;
+ }
+ } else if (ferror(fp) != 0) {
+ fprintf(stderr, "fread failed.\n");
+ return NULL;
+ }
+ }
+ free(song->sections[s]->lines[li]);
+ song->sections[s]->lines[li] = NULL;
+ song->metadata = realloc(song->metadata, (m+1) * sizeof(struct ChoMetadata *));
+ song->metadata[m] = NULL;
+ s++;
+ song->sections = realloc(song->sections, (s+1) * sizeof(struct ChoSection *));
+ song->sections[s] = NULL;
+ return song;
+}
+
diff --git a/chordpro.h b/chordpro.h
@@ -0,0 +1,77 @@
+enum State {
+ STATE_LYRICS,
+ STATE_DIRECTIVE_NAME,
+ STATE_DIRECTIVE_VALUE,
+ STATE_CHORD
+};
+
+enum DirectiveType {
+ DT_ENVIRONMENT,
+ DT_METADATA,
+ DT_FORMATTING,
+ DT_PREAMBLE,
+ DT_CUSTOM
+};
+
+enum SectionType {
+ ST_NEWSONG,
+ ST_NOTHING,
+ ST_CHORUS,
+ ST_VERSE,
+ ST_BRIDGE,
+ ST_TAB,
+ ST_GRID
+};
+
+enum Position {
+ POS_NOTHING,
+ POS_BEGIN,
+ POS_END
+};
+
+enum LineStyle {
+ LS_NORMAL,
+ LS_GREY_BACKGROUND,
+ LS_ITALIC,
+ LS_BOX
+};
+
+struct ChoDirective {
+ enum DirectiveType dtype;
+ enum SectionType stype;
+ enum Position position;
+ enum LineStyle style;
+};
+
+struct ChoMetadata {
+ char *name;
+ char *value;
+};
+
+struct ChoChord {
+ int index_in_lyrics;
+ char *chord;
+};
+
+struct ChoLine {
+ enum LineStyle style;
+ struct ChoChord **chords;
+ char *lyrics;
+};
+
+struct ChoSection {
+ enum SectionType type;
+ char *name;
+ struct ChoLine **lines;
+};
+
+struct ChoSong {
+ struct ChoMetadata **metadata;
+ struct ChoSection **sections;
+};
+
+struct ChoSong *cho_parse(FILE *fp);
+void cho_song_free(struct ChoSong *song);
+char *string_remove_leading_whitespace(const char *str);
+const char *the_stype(enum SectionType stype);
+const char *the_style(enum LineStyle style);
diff --git a/lorid.c b/lorid.c
@@ -0,0 +1,89 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include "chordpro.h"
+
+void print_hex(const char *str)
+{
+ int i = 0;
+ while (str[i] != 0) {
+ printf("%02X ", str[i]);
+ i++;
+ }
+ putchar('\n');
+}
+
+int main(int argc, char *argv[])
+{
+ if (argc != 2) {
+ fprintf(stderr, "Provide a file.\n");
+ return 1;
+ }
+ FILE *fp = fopen(argv[1], "r");
+ if (fp == NULL) {
+ fprintf(stderr, "fopen failed.\n");
+ return 1;
+ }
+ struct ChoSong *song = cho_parse(fp);
+ if (song == NULL) {
+ fprintf(stderr, "chordpro_parse failed.\n");
+ return 1;
+ }
+ /*int m = 0;*/
+ /*printf("---- BEGIN METADATA ----\n");*/
+ /*while (song->metadata[m] != NULL) {*/
+ /* if (song->metadata[m]->name) {*/
+ /* printf("name: %s", song->metadata[m]->name);*/
+ /* }*/
+ /* if (song->metadata[m]->value) {*/
+ /* printf(", value: %s\n", song->metadata[m]->value);*/
+ /* } else {*/
+ /* printf("\n");*/
+ /* }*/
+ /* m++;*/
+ /*}*/
+ /*printf("---- END METADATA ------\n");*/
+ char *lyrics;
+ struct ChoChord **chords;
+ enum SectionType stype;
+ enum LineStyle style;
+ int s = 0;
+ int li = 0;
+ int c = 0;
+ while (song->sections[s] != NULL) {
+ printf("---- BEGIN SECTION ----\n");
+ stype = song->sections[s]->type;
+ printf("stype: %s\n", the_stype(stype));
+ if (song->sections[s]->name) {
+ printf("name: %s\n", song->sections[s]->name);
+ }
+ while (song->sections[s]->lines[li] != NULL) {
+ /*chords = song->sections[s]->lines[li]->chords;*/
+ /*while (chords[c] != NULL) {*/
+ /* printf("index: %d, chord: %s | ", chords[c]->index_in_lyrics, chords[c]->chord);*/
+ /* c++;*/
+ /*}*/
+ /*printf("\n");*/
+ /*c = 0;*/
+ /*lyrics = song->sections[s]->lines[li]->lyrics;*/
+ /*if (strlen(lyrics) > 0) {*/
+ /* printf("lyrics: %s\n", lyrics);*/
+ /* style = song->sections[s]->lines[li]->style;*/
+ /* printf("style: %s\n", the_style(style));*/
+ /*}*/
+ style = song->sections[s]->lines[li]->style;
+ lyrics = song->sections[s]->lines[li]->lyrics;
+ if (strlen(lyrics) > 0) {
+ printf("style %s, line %s\n", the_style(style), lyrics);
+ }
+ li++;
+ }
+ li = 0;
+ s++;
+ printf("---- END SECTION ------\n");
+ }
+ cho_song_free(song);
+ fclose(fp);
+ return 0;
+}