commit 2b7aede1b996d407008e432da94aaf535b79ad5a
parent 1372caa85cb72bba0e6d5e45153207fc102521e8
Author: nibo <nibo@relim.de>
Date: Sun, 29 Dec 2024 12:09:38 +0100
Refactor different things
Diffstat:
| M | chordpro.c | | | 487 | +++++++++++++++++++++++++++++++++++++++++-------------------------------------- |
| M | chordpro.h | | | 327 | ++++++++++++++++++++++++++++++++++++++++--------------------------------------- |
| M | out_pdf.h | | | 44 | ++++++++++++++++++++++---------------------- |
3 files changed, 437 insertions(+), 421 deletions(-)
diff --git a/chordpro.c b/chordpro.c
@@ -3036,7 +3036,7 @@ cho_line_free(struct ChoLine *line)
/* TODO: Does this still work? */
static int
-cho_line_compute_chord_position(struct ChoLine *line, int ly, int te)
+cho_line_compute_text_above_position(struct ChoLine *line, int ly, int te)
{
if (ly == 0) {
return te;
@@ -3697,7 +3697,7 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
int atn = 0;
int atv = 0;
int ann = 0;
- int chord_pos;
+ int text_above_pos;
int transpose;
int th = 0;
int dia = 0;
@@ -3709,14 +3709,16 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
enum AttrValueSyntax avs = AVS_NO;
struct ChoDirective *directive = NULL;
struct ChoMetadata *metadata = NULL;
+ struct ChoLine ***lines;
struct ChoSong **songs = emalloc(sizeof(struct ChoSong *));
songs[so] = cho_song_new();
songs[so]->sections = emalloc((se+1) * sizeof(struct ChoSection *));
songs[so]->sections[se] = cho_section_new();
songs[so]->sections[se]->lines = emalloc(sizeof(struct ChoLine *));
songs[so]->sections[se]->lines[li] = cho_line_new();
- songs[so]->sections[se]->lines[li]->items = emalloc(sizeof(struct ChoLineItem *));
- songs[so]->sections[se]->lines[li]->items[ly] = cho_line_item_new();
+ lines = &songs[so]->sections[se]->lines;
+ (*lines)[li]->items = emalloc(sizeof(struct ChoLineItem *));
+ (*lines)[li]->items[ly] = cho_line_item_new();
struct Tag **tags = NULL;
struct ChoStyle *tag_style;
struct StyleProperty sprop;
@@ -3750,11 +3752,11 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
break;
}
if (buf == '<') {
- if (songs[so]->sections[se]->lines[li]->items[ly]->is_text) {
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text = erealloc(songs[so]->sections[se]->lines[li]->items[ly]->u.text->text, (te+1) * sizeof(char));
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text[te] = 0;
- if (strlen(songs[so]->sections[se]->lines[li]->items[ly]->u.text->text) == 0) {
- cho_line_item_free(songs[so]->sections[se]->lines[li]->items[ly]);
+ if ((*lines)[li]->items[ly]->is_text) {
+ (*lines)[li]->items[ly]->u.text->text = erealloc((*lines)[li]->items[ly]->u.text->text, (te+1) * sizeof(char));
+ (*lines)[li]->items[ly]->u.text->text[te] = 0;
+ if (strlen((*lines)[li]->items[ly]->u.text->text) == 0) {
+ cho_line_item_free((*lines)[li]->items[ly]);
} else {
ly++;
}
@@ -3762,8 +3764,8 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
ly++;
}
te = 0;
- songs[so]->sections[se]->lines[li]->items = erealloc(songs[so]->sections[se]->lines[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
- songs[so]->sections[se]->lines[li]->items[ly] = cho_line_item_new();
+ (*lines)[li]->items = erealloc((*lines)[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
+ (*lines)[li]->items[ly] = cho_line_item_new();
prev_state = STATE_LYRICS;
state = STATE_MARKUP_TAG;
break;
@@ -3778,22 +3780,22 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
cho_log(LOG_ERR, "Tag has to be closed on same line.");
return NULL;
}
- if (songs[so]->sections[se]->lines[li]->items[ly]->is_text) {
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text = erealloc(songs[so]->sections[se]->lines[li]->items[ly]->u.text->text, (te+1) * sizeof(char));
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text[te] = 0;
- if (strlen(songs[so]->sections[se]->lines[li]->items[ly]->u.text->text) == 0) {
- cho_line_item_free(songs[so]->sections[se]->lines[li]->items[ly]);
+ if ((*lines)[li]->items[ly]->is_text) {
+ (*lines)[li]->items[ly]->u.text->text = erealloc((*lines)[li]->items[ly]->u.text->text, (te+1) * sizeof(char));
+ (*lines)[li]->items[ly]->u.text->text[te] = 0;
+ if (strlen((*lines)[li]->items[ly]->u.text->text) == 0) {
+ cho_line_item_free((*lines)[li]->items[ly]);
if (ly == 0) {
if (
- !songs[so]->sections[se]->lines[li]->text_above &&
- songs[so]->sections[se]->lines[li]->btype == BT_LINE
+ !(*lines)[li]->text_above &&
+ (*lines)[li]->btype == BT_LINE
) {
- free(songs[so]->sections[se]->lines[li]->items);
- free(songs[so]->sections[se]->lines[li]);
- songs[so]->sections[se]->lines = erealloc(songs[so]->sections[se]->lines, (li+1) * sizeof(struct ChoLine *));
- songs[so]->sections[se]->lines[li] = cho_line_new();
- songs[so]->sections[se]->lines[li]->items = erealloc(songs[so]->sections[se]->lines[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
- songs[so]->sections[se]->lines[li]->items[ly] = cho_line_item_new();
+ free((*lines)[li]->items);
+ free((*lines)[li]);
+ *lines = erealloc(*lines, (li+1) * sizeof(struct ChoLine *));
+ (*lines)[li] = cho_line_new();
+ (*lines)[li]->items = erealloc((*lines)[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
+ (*lines)[li]->items[ly] = cho_line_item_new();
break;
}
}
@@ -3803,22 +3805,22 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
} else {
ly++;
}
- songs[so]->sections[se]->lines[li]->items = erealloc(songs[so]->sections[se]->lines[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
- songs[so]->sections[se]->lines[li]->items[ly] = NULL;
+ (*lines)[li]->items = erealloc((*lines)[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
+ (*lines)[li]->items[ly] = NULL;
ly = 0;
te = 0;
- songs[so]->sections[se]->lines[li]->text_above = erealloc(songs[so]->sections[se]->lines[li]->text_above, (c+1) * sizeof(struct ChoLineItemAbove *));
- songs[so]->sections[se]->lines[li]->text_above[c] = NULL;
+ (*lines)[li]->text_above = erealloc((*lines)[li]->text_above, (c+1) * sizeof(struct ChoLineItemAbove *));
+ (*lines)[li]->text_above[c] = NULL;
c = 0;
li++;
- songs[so]->sections[se]->lines = erealloc(songs[so]->sections[se]->lines, (li+1) * sizeof(struct ChoLine *));
- songs[so]->sections[se]->lines[li] = cho_line_new();
- songs[so]->sections[se]->lines[li]->items = erealloc(songs[so]->sections[se]->lines[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
- songs[so]->sections[se]->lines[li]->items[ly] = cho_line_item_new();
+ *lines = erealloc(*lines, (li+1) * sizeof(struct ChoLine *));
+ (*lines)[li] = cho_line_new();
+ (*lines)[li]->items = erealloc((*lines)[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
+ (*lines)[li]->items[ly] = cho_line_item_new();
break;
}
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text = erealloc(songs[so]->sections[se]->lines[li]->items[ly]->u.text->text, (te+1) * sizeof(char));
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text[te] = buf;
+ (*lines)[li]->items[ly]->u.text->text = erealloc((*lines)[li]->items[ly]->u.text->text, (te+1) * sizeof(char));
+ (*lines)[li]->items[ly]->u.text->text[te] = buf;
te++;
break;
case STATE_DIRECTIVE_NAME:
@@ -3839,20 +3841,21 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
memset(custom_directive, 0, sizeof(custom_directive));
strcpy(custom_directive, &directive_name[9]);
}
- cho_line_item_free(songs[so]->sections[se]->lines[li]->items[ly]);
- free(songs[so]->sections[se]->lines[li]->items);
+ cho_line_item_free((*lines)[li]->items[ly]);
+ free((*lines)[li]->items);
ly = 0;
- free(songs[so]->sections[se]->lines[li]);
- songs[so]->sections[se]->lines[li] = NULL;
+ free((*lines)[li]);
+ (*lines)[li] = NULL;
se++;
songs[so]->sections = erealloc(songs[so]->sections, (se+1) * sizeof(struct ChoSection *));
songs[so]->sections[se] = cho_section_new();
songs[so]->sections[se]->type = directive->stype;
li = 0;
- songs[so]->sections[se]->lines = emalloc(sizeof(struct ChoLine *));
- songs[so]->sections[se]->lines[li] = cho_line_new();
- songs[so]->sections[se]->lines[li]->items = emalloc(sizeof(struct ChoLineItem *));
- songs[so]->sections[se]->lines[li]->items[ly] = cho_line_item_new();
+ lines = &songs[so]->sections[se]->lines;
+ *lines = emalloc(sizeof(struct ChoLine *));
+ (*lines)[li] = cho_line_new();
+ (*lines)[li]->items = emalloc(sizeof(struct ChoLineItem *));
+ (*lines)[li]->items[ly] = cho_line_item_new();
break;
case POS_END:
if (directive->stype == songs[so]->sections[se]->type) {
@@ -3861,19 +3864,20 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
break;
}
}
- cho_line_item_free(songs[so]->sections[se]->lines[li]->items[ly]);
- free(songs[so]->sections[se]->lines[li]->items);
+ cho_line_item_free((*lines)[li]->items[ly]);
+ free((*lines)[li]->items);
ly = 0;
- free(songs[so]->sections[se]->lines[li]);
- songs[so]->sections[se]->lines[li] = NULL;
+ free((*lines)[li]);
+ (*lines)[li] = NULL;
se++;
songs[so]->sections = erealloc(songs[so]->sections, (se+1) * sizeof(struct ChoSection *));
songs[so]->sections[se] = cho_section_new();
li = 0;
- songs[so]->sections[se]->lines = emalloc(sizeof(struct ChoLine *));
- songs[so]->sections[se]->lines[li] = cho_line_new();
- songs[so]->sections[se]->lines[li]->items = emalloc(sizeof(struct ChoLineItem *));
- songs[so]->sections[se]->lines[li]->items[ly] = cho_line_item_new();
+ lines = &songs[so]->sections[se]->lines;
+ *lines = emalloc(sizeof(struct ChoLine *));
+ (*lines)[li] = cho_line_new();
+ (*lines)[li]->items = emalloc(sizeof(struct ChoLineItem *));
+ (*lines)[li]->items[ly] = cho_line_item_new();
}
break;
case POS_EMPTY:
@@ -3881,20 +3885,20 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
chorus = cho_find_previous_chorus(songs[so]->sections, se);
if (chorus) {
if (config->output->chorus->quote) {
- if (songs[so]->sections[se]->lines[li]->items[ly]->is_text) {
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text = erealloc(songs[so]->sections[se]->lines[li]->items[ly]->u.text->text, (te+1) * sizeof(char));
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text[te] = 0;
+ if ((*lines)[li]->items[ly]->is_text) {
+ (*lines)[li]->items[ly]->u.text->text = erealloc((*lines)[li]->items[ly]->u.text->text, (te+1) * sizeof(char));
+ (*lines)[li]->items[ly]->u.text->text[te] = 0;
}
ly++;
- songs[so]->sections[se]->lines[li]->items = erealloc(songs[so]->sections[se]->lines[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
- songs[so]->sections[se]->lines[li]->items[ly] = NULL;
+ (*lines)[li]->items = erealloc((*lines)[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
+ (*lines)[li]->items[ly] = NULL;
ly = 0;
te = 0;
- songs[so]->sections[se]->lines[li]->text_above = erealloc(songs[so]->sections[se]->lines[li]->text_above, (c+1) * sizeof(struct ChoLineItemAbove *));
- songs[so]->sections[se]->lines[li]->text_above[c] = NULL;
+ (*lines)[li]->text_above = erealloc((*lines)[li]->text_above, (c+1) * sizeof(struct ChoLineItemAbove *));
+ (*lines)[li]->text_above[c] = NULL;
c = 0;
- cho_line_free(songs[so]->sections[se]->lines[li]);
- songs[so]->sections[se]->lines[li] = NULL;
+ cho_line_free((*lines)[li]);
+ (*lines)[li] = NULL;
li = 0;
se++;
songs[so]->sections = erealloc(songs[so]->sections, (se+1) * sizeof(struct ChoSection *));
@@ -3902,33 +3906,34 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
se++;
songs[so]->sections = erealloc(songs[so]->sections, (se+1) * sizeof(struct ChoSection *));
songs[so]->sections[se] = cho_section_new();
- songs[so]->sections[se]->lines = emalloc(sizeof(struct ChoLine *));
- songs[so]->sections[se]->lines[li] = cho_line_new();
- songs[so]->sections[se]->lines[li]->items = emalloc(sizeof(struct ChoLineItem *));
- songs[so]->sections[se]->lines[li]->items[ly] = cho_line_item_new();
+ lines = &songs[so]->sections[se]->lines;
+ *lines = emalloc(sizeof(struct ChoLine *));
+ (*lines)[li] = cho_line_new();
+ (*lines)[li]->items = emalloc(sizeof(struct ChoLineItem *));
+ (*lines)[li]->items[ly] = cho_line_item_new();
} else {
if (chorus->label) {
label = strdup(chorus->label->text);
} else {
label = strdup(config->output->chorus->label);
}
- if (songs[so]->sections[se]->lines[li]->items[ly]->is_text) {
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text = erealloc(songs[so]->sections[se]->lines[li]->items[ly]->u.text->text, (te+1) * sizeof(char));
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text[te] = 0;
- if (strlen(songs[so]->sections[se]->lines[li]->items[ly]->u.text->text) == 0) {
- cho_line_item_free(songs[so]->sections[se]->lines[li]->items[ly]);
+ if ((*lines)[li]->items[ly]->is_text) {
+ (*lines)[li]->items[ly]->u.text->text = erealloc((*lines)[li]->items[ly]->u.text->text, (te+1) * sizeof(char));
+ (*lines)[li]->items[ly]->u.text->text[te] = 0;
+ if (strlen((*lines)[li]->items[ly]->u.text->text) == 0) {
+ cho_line_item_free((*lines)[li]->items[ly]);
} else {
ly++;
}
} else {
ly++;
}
- songs[so]->sections[se]->lines[li]->items = erealloc(songs[so]->sections[se]->lines[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
- songs[so]->sections[se]->lines[li]->items[ly] = cho_line_item_new();
- cho_style_free(songs[so]->sections[se]->lines[li]->items[ly]->u.text->style);
+ (*lines)[li]->items = erealloc((*lines)[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
+ (*lines)[li]->items[ly] = cho_line_item_new();
+ cho_style_free((*lines)[li]->items[ly]->u.text->style);
g_current_ftype = SF_LABEL;
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->style = cho_style_new_default();
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text = label;
+ (*lines)[li]->items[ly]->u.text->style = cho_style_new_default();
+ (*lines)[li]->items[ly]->u.text->text = label;
te += strlen(label);
}
} else {
@@ -3936,23 +3941,23 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
cho_log(LOG_WARN, "Can't quote chorus because it's not defined previously.");
}
label = strdup(config->output->chorus->label);
- if (songs[so]->sections[se]->lines[li]->items[ly]->is_text) {
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text = erealloc(songs[so]->sections[se]->lines[li]->items[ly]->u.text->text, (te+1) * sizeof(char));
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text[te] = 0;
- if (strlen(songs[so]->sections[se]->lines[li]->items[ly]->u.text->text) == 0) {
- cho_line_item_free(songs[so]->sections[se]->lines[li]->items[ly]);
+ if ((*lines)[li]->items[ly]->is_text) {
+ (*lines)[li]->items[ly]->u.text->text = erealloc((*lines)[li]->items[ly]->u.text->text, (te+1) * sizeof(char));
+ (*lines)[li]->items[ly]->u.text->text[te] = 0;
+ if (strlen((*lines)[li]->items[ly]->u.text->text) == 0) {
+ cho_line_item_free((*lines)[li]->items[ly]);
} else {
ly++;
}
} else {
ly++;
}
- songs[so]->sections[se]->lines[li]->items = erealloc(songs[so]->sections[se]->lines[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
- songs[so]->sections[se]->lines[li]->items[ly] = cho_line_item_new();
- cho_style_free(songs[so]->sections[se]->lines[li]->items[ly]->u.text->style);
+ (*lines)[li]->items = erealloc((*lines)[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
+ (*lines)[li]->items[ly] = cho_line_item_new();
+ cho_style_free((*lines)[li]->items[ly]->u.text->style);
g_current_ftype = SF_LABEL;
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->style = cho_style_new_default();
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text = label;
+ (*lines)[li]->items[ly]->u.text->style = cho_style_new_default();
+ (*lines)[li]->items[ly]->u.text->text = label;
te += strlen(label);
}
break;
@@ -3972,10 +3977,10 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
return NULL;
case DT_PREAMBLE:
// INFO: The only preamble directive is 'new_song'
- cho_line_item_free(songs[so]->sections[se]->lines[li]->items[ly]);
- free(songs[so]->sections[se]->lines[li]->items);
- free(songs[so]->sections[se]->lines[li]);
- songs[so]->sections[se]->lines[li] = NULL;
+ cho_line_item_free((*lines)[li]->items[ly]);
+ free((*lines)[li]->items);
+ free((*lines)[li]);
+ (*lines)[li] = NULL;
songs[so]->metadata = erealloc(songs[so]->metadata, (m+1) * sizeof(struct ChoMetadata *));
songs[so]->metadata[m] = NULL;
se++;
@@ -3997,10 +4002,11 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
dia = 0;
songs[so]->sections = emalloc((se+1) * sizeof(struct ChoSection *));
songs[so]->sections[se] = cho_section_new();
- songs[so]->sections[se]->lines = erealloc(songs[so]->sections[se]->lines, (li+1) * sizeof(struct ChoLine *));
- songs[so]->sections[se]->lines[li] = cho_line_new();
- songs[so]->sections[se]->lines[li]->items = emalloc(sizeof(struct ChoLineItem *));
- songs[so]->sections[se]->lines[li]->items[ly] = cho_line_item_new();
+ lines = &songs[so]->sections[se]->lines;
+ *lines = erealloc(*lines, (li+1) * sizeof(struct ChoLine *));
+ (*lines)[li] = cho_line_new();
+ (*lines)[li]->items = emalloc(sizeof(struct ChoLineItem *));
+ (*lines)[li]->items[ly] = cho_line_item_new();
break;
case DT_FONT:
sprop.ftype = directive->ftype;
@@ -4037,7 +4043,7 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
break;
case DT_OUTPUT:
if (directive->btype != BT_EMPTY) {
- songs[so]->sections[se]->lines[li]->btype = directive->btype;
+ (*lines)[li]->btype = directive->btype;
}
break;
case DT_CUSTOM:
@@ -4088,11 +4094,11 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
memset(custom_directive, 0, sizeof(custom_directive));
strcpy(custom_directive, &directive_name[9]);
}
- cho_line_item_free(songs[so]->sections[se]->lines[li]->items[ly]);
- free(songs[so]->sections[se]->lines[li]->items);
+ cho_line_item_free((*lines)[li]->items[ly]);
+ free((*lines)[li]->items);
ly = 0;
- free(songs[so]->sections[se]->lines[li]);
- songs[so]->sections[se]->lines[li] = NULL;
+ free((*lines)[li]);
+ (*lines)[li] = NULL;
se++;
songs[so]->sections = erealloc(songs[so]->sections, (se+1) * sizeof(struct ChoSection *));
songs[so]->sections[se] = cho_section_new();
@@ -4111,26 +4117,28 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
}
songs[so]->sections[se]->label->style = cho_style_new_from_config(SF_LABEL);
li = 0;
- songs[so]->sections[se]->lines = emalloc(sizeof(struct ChoLine *));
- songs[so]->sections[se]->lines[li] = cho_line_new();
- songs[so]->sections[se]->lines[li]->items = emalloc(sizeof(struct ChoLineItem *));
- songs[so]->sections[se]->lines[li]->items[ly] = cho_line_item_new();
+ lines = &songs[so]->sections[se]->lines;
+ *lines = emalloc(sizeof(struct ChoLine *));
+ (*lines)[li] = cho_line_new();
+ (*lines)[li]->items = emalloc(sizeof(struct ChoLineItem *));
+ (*lines)[li]->items[ly] = cho_line_item_new();
break;
case POS_END:
if (directive->stype == songs[so]->sections[se]->type) {
- cho_line_item_free(songs[so]->sections[se]->lines[li]->items[ly]);
- free(songs[so]->sections[se]->lines[li]->items);
+ cho_line_item_free((*lines)[li]->items[ly]);
+ free((*lines)[li]->items);
ly = 0;
- free(songs[so]->sections[se]->lines[li]);
- songs[so]->sections[se]->lines[li] = NULL;
+ free((*lines)[li]);
+ (*lines)[li] = NULL;
se++;
songs[so]->sections = erealloc(songs[so]->sections, (se+1) * sizeof(struct ChoSection *));
songs[so]->sections[se] = cho_section_new();
li = 0;
- songs[so]->sections[se]->lines = emalloc(sizeof(struct ChoLine *));
- songs[so]->sections[se]->lines[li] = cho_line_new();
- songs[so]->sections[se]->lines[li]->items = emalloc(sizeof(struct ChoLineItem *));
- songs[so]->sections[se]->lines[li]->items[ly] = cho_line_item_new();
+ lines = &songs[so]->sections[se]->lines;
+ *lines = emalloc(sizeof(struct ChoLine *));
+ (*lines)[li] = cho_line_new();
+ (*lines)[li]->items = emalloc(sizeof(struct ChoLineItem *));
+ (*lines)[li]->items[ly] = cho_line_item_new();
}
break;
case POS_EMPTY:
@@ -4139,21 +4147,21 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
chorus = cho_find_previous_chorus(songs[so]->sections, se);
if (chorus) {
if (config->output->chorus->quote) {
- if (songs[so]->sections[se]->lines[li]->items[ly]->is_text) {
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text = erealloc(songs[so]->sections[se]->lines[li]->items[ly]->u.text->text, (te+1) * sizeof(char));
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text[te] = 0;
+ if ((*lines)[li]->items[ly]->is_text) {
+ (*lines)[li]->items[ly]->u.text->text = erealloc((*lines)[li]->items[ly]->u.text->text, (te+1) * sizeof(char));
+ (*lines)[li]->items[ly]->u.text->text[te] = 0;
}
ly++;
- songs[so]->sections[se]->lines[li]->items = erealloc(songs[so]->sections[se]->lines[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
- songs[so]->sections[se]->lines[li]->items[ly] = NULL;
+ (*lines)[li]->items = erealloc((*lines)[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
+ (*lines)[li]->items[ly] = NULL;
ly = 0;
te = 0;
- songs[so]->sections[se]->lines[li]->text_above = erealloc(songs[so]->sections[se]->lines[li]->text_above, (c+1) * sizeof(struct ChoLineItemAbove *));
- songs[so]->sections[se]->lines[li]->text_above[c] = NULL;
+ (*lines)[li]->text_above = erealloc((*lines)[li]->text_above, (c+1) * sizeof(struct ChoLineItemAbove *));
+ (*lines)[li]->text_above[c] = NULL;
c = 0;
- cho_line_free(songs[so]->sections[se]->lines[li]);
+ cho_line_free((*lines)[li]);
// songs[so]->sections[se]->lines = erealloc(songs[so]->sections[se]->lines, (li+1) * sizeof(struct ChoLine *));
- songs[so]->sections[se]->lines[li] = NULL;
+ (*lines)[li] = NULL;
li = 0;
se++;
songs[so]->sections = erealloc(songs[so]->sections, (se+1) * sizeof(struct ChoSection *));
@@ -4169,51 +4177,52 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
se++;
songs[so]->sections = erealloc(songs[so]->sections, (se+1) * sizeof(struct ChoSection *));
songs[so]->sections[se] = cho_section_new();
- songs[so]->sections[se]->lines = emalloc(sizeof(struct ChoLine *));
- songs[so]->sections[se]->lines[li] = cho_line_new();
- songs[so]->sections[se]->lines[li]->items = emalloc(sizeof(struct ChoLineItem *));
- songs[so]->sections[se]->lines[li]->items[ly] = cho_line_item_new();
+ lines = &songs[so]->sections[se]->lines;
+ *lines = emalloc(sizeof(struct ChoLine *));
+ (*lines)[li] = cho_line_new();
+ (*lines)[li]->items = emalloc(sizeof(struct ChoLineItem *));
+ (*lines)[li]->items[ly] = cho_line_item_new();
} else {
- if (songs[so]->sections[se]->lines[li]->items[ly]->is_text) {
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text = erealloc(songs[so]->sections[se]->lines[li]->items[ly]->u.text->text, (te+1) * sizeof(char));
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text[te] = 0;
- if (strlen(songs[so]->sections[se]->lines[li]->items[ly]->u.text->text) == 0) {
- cho_line_item_free(songs[so]->sections[se]->lines[li]->items[ly]);
+ if ((*lines)[li]->items[ly]->is_text) {
+ (*lines)[li]->items[ly]->u.text->text = erealloc((*lines)[li]->items[ly]->u.text->text, (te+1) * sizeof(char));
+ (*lines)[li]->items[ly]->u.text->text[te] = 0;
+ if (strlen((*lines)[li]->items[ly]->u.text->text) == 0) {
+ cho_line_item_free((*lines)[li]->items[ly]);
} else {
ly++;
}
} else {
ly++;
}
- songs[so]->sections[se]->lines[li]->items = erealloc(songs[so]->sections[se]->lines[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
- songs[so]->sections[se]->lines[li]->items[ly] = cho_line_item_new();
- cho_style_free(songs[so]->sections[se]->lines[li]->items[ly]->u.text->style);
+ (*lines)[li]->items = erealloc((*lines)[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
+ (*lines)[li]->items[ly] = cho_line_item_new();
+ cho_style_free((*lines)[li]->items[ly]->u.text->style);
g_current_ftype = SF_LABEL;
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->style = cho_style_new_default();
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text = label;
+ (*lines)[li]->items[ly]->u.text->style = cho_style_new_default();
+ (*lines)[li]->items[ly]->u.text->text = label;
te += strlen(label);
}
} else {
if (config->output->chorus->quote) {
cho_log(LOG_WARN, "Can't quote chorus because it's not defined previously.");
}
- if (songs[so]->sections[se]->lines[li]->items[ly]->is_text) {
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text = erealloc(songs[so]->sections[se]->lines[li]->items[ly]->u.text->text, (te+1) * sizeof(char));
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text[te] = 0;
- if (strlen(songs[so]->sections[se]->lines[li]->items[ly]->u.text->text) == 0) {
- cho_line_item_free(songs[so]->sections[se]->lines[li]->items[ly]);
+ if ((*lines)[li]->items[ly]->is_text) {
+ (*lines)[li]->items[ly]->u.text->text = erealloc((*lines)[li]->items[ly]->u.text->text, (te+1) * sizeof(char));
+ (*lines)[li]->items[ly]->u.text->text[te] = 0;
+ if (strlen((*lines)[li]->items[ly]->u.text->text) == 0) {
+ cho_line_item_free((*lines)[li]->items[ly]);
} else {
ly++;
}
} else {
ly++;
}
- songs[so]->sections[se]->lines[li]->items = erealloc(songs[so]->sections[se]->lines[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
- songs[so]->sections[se]->lines[li]->items[ly] = cho_line_item_new();
- cho_style_free(songs[so]->sections[se]->lines[li]->items[ly]->u.text->style);
+ (*lines)[li]->items = erealloc((*lines)[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
+ (*lines)[li]->items[ly] = cho_line_item_new();
+ cho_style_free((*lines)[li]->items[ly]->u.text->style);
g_current_ftype = SF_LABEL;
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->style = cho_style_new_default();
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text = label;
+ (*lines)[li]->items[ly]->u.text->style = cho_style_new_default();
+ (*lines)[li]->items[ly]->u.text->text = label;
te += strlen(label);
}
break;
@@ -4269,23 +4278,23 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
}
break;
case DT_FORMATTING:
- if (songs[so]->sections[se]->lines[li]->items[ly]->is_text) {
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text = erealloc(songs[so]->sections[se]->lines[li]->items[ly]->u.text->text, (te+1) * sizeof(char));
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text[te] = 0;
- if (strlen(songs[so]->sections[se]->lines[li]->items[ly]->u.text->text) == 0) {
- cho_line_item_free(songs[so]->sections[se]->lines[li]->items[ly]);
+ if ((*lines)[li]->items[ly]->is_text) {
+ (*lines)[li]->items[ly]->u.text->text = erealloc((*lines)[li]->items[ly]->u.text->text, (te+1) * sizeof(char));
+ (*lines)[li]->items[ly]->u.text->text[te] = 0;
+ if (strlen((*lines)[li]->items[ly]->u.text->text) == 0) {
+ cho_line_item_free((*lines)[li]->items[ly]);
} else {
ly++;
}
} else {
ly++;
}
- songs[so]->sections[se]->lines[li]->items = erealloc(songs[so]->sections[se]->lines[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
- songs[so]->sections[se]->lines[li]->items[ly] = cho_line_item_new();
- cho_style_free(songs[so]->sections[se]->lines[li]->items[ly]->u.text->style);
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->style = cho_style_copy(directive->style);
+ (*lines)[li]->items = erealloc((*lines)[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
+ (*lines)[li]->items[ly] = cho_line_item_new();
+ cho_style_free((*lines)[li]->items[ly]->u.text->style);
+ (*lines)[li]->items[ly]->u.text->style = cho_style_copy(directive->style);
char *trimmed_directive_value = str_remove_leading_whitespace(directive_value);
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text = trimmed_directive_value;
+ (*lines)[li]->items[ly]->u.text->text = trimmed_directive_value;
te += strlen(trimmed_directive_value);
break;
case DT_IMAGE:
@@ -4304,17 +4313,17 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
g_image_assets[g_ia] = image;
g_ia++;
} else {
- if (songs[so]->sections[se]->lines[li]->items[ly]->is_text) {
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text = erealloc(songs[so]->sections[se]->lines[li]->items[ly]->u.text->text, (te+1) * sizeof(char));
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text[te] = 0;
+ if ((*lines)[li]->items[ly]->is_text) {
+ (*lines)[li]->items[ly]->u.text->text = erealloc((*lines)[li]->items[ly]->u.text->text, (te+1) * sizeof(char));
+ (*lines)[li]->items[ly]->u.text->text[te] = 0;
te = 0;
}
ly++;
- songs[so]->sections[se]->lines[li]->items = erealloc(songs[so]->sections[se]->lines[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
- songs[so]->sections[se]->lines[li]->items[ly] = cho_line_item_new();
- cho_text_free(songs[so]->sections[se]->lines[li]->items[ly]->u.text);
- songs[so]->sections[se]->lines[li]->items[ly]->is_text = false;
- songs[so]->sections[se]->lines[li]->items[ly]->u.image = image;
+ (*lines)[li]->items = erealloc((*lines)[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
+ (*lines)[li]->items[ly] = cho_line_item_new();
+ cho_text_free((*lines)[li]->items[ly]->u.text);
+ (*lines)[li]->items[ly]->is_text = false;
+ (*lines)[li]->items[ly]->u.image = image;
}
break;
case DT_PREAMBLE:
@@ -4425,24 +4434,24 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
g_prev_ftype = g_current_ftype;
g_current_ftype = SF_CHORD;
if (is_chord_already_initialized) {
- chord_pos = cho_line_compute_chord_position(songs[so]->sections[se]->lines[li], ly, te);
- songs[so]->sections[se]->lines[li]->text_above[c]->position = chord_pos;
+ text_above_pos = cho_line_compute_text_above_position(songs[so]->sections[se]->lines[li], ly, te);
+ (*lines)[li]->text_above[c]->position = text_above_pos;
tmp_chord = cho_chord_parse(chord);
- cho_chord_complete(songs[so]->sections[se]->lines[li]->text_above[c]->u.chord, tmp_chord);
- if (!songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->is_canonical) {
- cho_log(LOG_INFO, "Didn't recognize the chord '%s'.", songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->name);
+ cho_chord_complete((*lines)[li]->text_above[c]->u.chord, tmp_chord);
+ if (!(*lines)[li]->text_above[c]->u.chord->is_canonical) {
+ cho_log(LOG_INFO, "Didn't recognize the chord '%s'.", (*lines)[li]->text_above[c]->u.chord->name);
}
cho_chord_free(tmp_chord);
is_chord_already_initialized = false;
} else {
- songs[so]->sections[se]->lines[li]->text_above = erealloc(songs[so]->sections[se]->lines[li]->text_above, (c+1) * sizeof(struct ChoLineItemAbove *));
- songs[so]->sections[se]->lines[li]->text_above[c] = emalloc(sizeof(struct ChoLineItemAbove));
- songs[so]->sections[se]->lines[li]->text_above[c]->is_chord = true;
- chord_pos = cho_line_compute_chord_position(songs[so]->sections[se]->lines[li], ly, te);
- songs[so]->sections[se]->lines[li]->text_above[c]->position = chord_pos;
- songs[so]->sections[se]->lines[li]->text_above[c]->u.chord = cho_chord_parse(chord);
- if (!songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->is_canonical) {
- cho_log(LOG_INFO, "Didn't recognize the chord '%s'.", songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->name);
+ (*lines)[li]->text_above = erealloc((*lines)[li]->text_above, (c+1) * sizeof(struct ChoLineItemAbove *));
+ (*lines)[li]->text_above[c] = emalloc(sizeof(struct ChoLineItemAbove));
+ (*lines)[li]->text_above[c]->is_chord = true;
+ text_above_pos = cho_line_compute_text_above_position((*lines)[li], ly, te);
+ (*lines)[li]->text_above[c]->position = text_above_pos;
+ (*lines)[li]->text_above[c]->u.chord = cho_chord_parse(chord);
+ if (!(*lines)[li]->text_above[c]->u.chord->is_canonical) {
+ cho_log(LOG_INFO, "Didn't recognize the chord '%s'.", (*lines)[li]->text_above[c]->u.chord->name);
}
}
memset(chord, 0, strlen(chord));
@@ -4454,12 +4463,12 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
if (prev_buf == '[' && buf == '*') {
g_prev_ftype = g_current_ftype;
g_current_ftype = SF_ANNOT;
- songs[so]->sections[se]->lines[li]->text_above = erealloc(songs[so]->sections[se]->lines[li]->text_above, (c+1) * sizeof(struct ChoLineItemAbove *));
- songs[so]->sections[se]->lines[li]->text_above[c] = emalloc(sizeof(struct ChoLineItemAbove));
- songs[so]->sections[se]->lines[li]->text_above[c]->is_chord = false;
- chord_pos = cho_line_compute_chord_position(songs[so]->sections[se]->lines[li], ly, te);
- songs[so]->sections[se]->lines[li]->text_above[c]->position = chord_pos;
- songs[so]->sections[se]->lines[li]->text_above[c]->u.annot = cho_text_new();
+ (*lines)[li]->text_above = erealloc((*lines)[li]->text_above, (c+1) * sizeof(struct ChoLineItemAbove *));
+ (*lines)[li]->text_above[c] = emalloc(sizeof(struct ChoLineItemAbove));
+ (*lines)[li]->text_above[c]->is_chord = false;
+ text_above_pos = cho_line_compute_text_above_position((*lines)[li], ly, te);
+ (*lines)[li]->text_above[c]->position = text_above_pos;
+ (*lines)[li]->text_above[c]->u.annot = cho_text_new();
state = STATE_ANNOTATION;
break;
}
@@ -4473,10 +4482,10 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
}
if (buf == '<') {
if (prev_buf == '[') {
- songs[so]->sections[se]->lines[li]->text_above = erealloc(songs[so]->sections[se]->lines[li]->text_above, (c+1) * sizeof(struct ChoLineItemAbove *));
- songs[so]->sections[se]->lines[li]->text_above[c] = emalloc(sizeof(struct ChoLineItemAbove));
- songs[so]->sections[se]->lines[li]->text_above[c]->is_chord = true;
- songs[so]->sections[se]->lines[li]->text_above[c]->u.chord = cho_chord_new();
+ (*lines)[li]->text_above = erealloc((*lines)[li]->text_above, (c+1) * sizeof(struct ChoLineItemAbove *));
+ (*lines)[li]->text_above[c] = emalloc(sizeof(struct ChoLineItemAbove));
+ (*lines)[li]->text_above[c]->is_chord = true;
+ (*lines)[li]->text_above[c]->u.chord = cho_chord_new();
is_chord_already_initialized = true;
}
prev_state = STATE_CHORD;
@@ -4488,8 +4497,8 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
break;
case STATE_ANNOTATION:
if (buf == ']') {
- songs[so]->sections[se]->lines[li]->text_above[c]->u.annot->text = erealloc(songs[so]->sections[se]->lines[li]->text_above[c]->u.annot->text, (ann+1) * sizeof(char));
- songs[so]->sections[se]->lines[li]->text_above[c]->u.annot->text[ann] = 0;
+ (*lines)[li]->text_above[c]->u.annot->text = erealloc((*lines)[li]->text_above[c]->u.annot->text, (ann+1) * sizeof(char));
+ (*lines)[li]->text_above[c]->u.annot->text[ann] = 0;
ann = 0;
c++;
g_current_ftype = g_prev_ftype;
@@ -4505,8 +4514,8 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
cho_log(LOG_ERR, "Newline character inside an annotation is invalid.");
return NULL;
}
- songs[so]->sections[se]->lines[li]->text_above[c]->u.annot->text = erealloc(songs[so]->sections[se]->lines[li]->text_above[c]->u.annot->text, (ann+1) * sizeof(char));
- songs[so]->sections[se]->lines[li]->text_above[c]->u.annot->text[ann] = buf;
+ (*lines)[li]->text_above[c]->u.annot->text = erealloc((*lines)[li]->text_above[c]->u.annot->text, (ann+1) * sizeof(char));
+ (*lines)[li]->text_above[c]->u.annot->text[ann] = buf;
ann++;
break;
case STATE_MARKUP_TAG_START:
@@ -4527,27 +4536,27 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
tags[ta]->style = tag_style;
switch (prev_state) {
case STATE_LYRICS:
- cho_style_free(songs[so]->sections[se]->lines[li]->items[ly]->u.text->style);
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->style = cho_style_copy(tag_style);
+ cho_style_free((*lines)[li]->items[ly]->u.text->style);
+ (*lines)[li]->items[ly]->u.text->style = cho_style_copy(tag_style);
break;
case STATE_CHORD:
- cho_style_free(songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->style);
- songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->style = cho_style_copy(tag_style);
+ cho_style_free((*lines)[li]->text_above[c]->u.chord->style);
+ (*lines)[li]->text_above[c]->u.chord->style = cho_style_copy(tag_style);
break;
case STATE_ANNOTATION:
if (ann > 0) {
- songs[so]->sections[se]->lines[li]->text_above[c]->u.annot->text = erealloc(songs[so]->sections[se]->lines[li]->text_above[c]->u.annot->text, (ann+1) * sizeof(char));
- songs[so]->sections[se]->lines[li]->text_above[c]->u.annot->text[ann] = 0;
+ (*lines)[li]->text_above[c]->u.annot->text = erealloc((*lines)[li]->text_above[c]->u.annot->text, (ann+1) * sizeof(char));
+ (*lines)[li]->text_above[c]->u.annot->text[ann] = 0;
ann = 0;
c++;
- songs[so]->sections[se]->lines[li]->text_above = erealloc(songs[so]->sections[se]->lines[li]->text_above, (c+1) * sizeof(struct ChoLineItemAbove *));
- songs[so]->sections[se]->lines[li]->text_above[c] = emalloc(sizeof(struct ChoLineItemAbove));
- songs[so]->sections[se]->lines[li]->text_above[c]->is_chord = false;
- songs[so]->sections[se]->lines[li]->text_above[c]->position = chord_pos;
- songs[so]->sections[se]->lines[li]->text_above[c]->u.annot = cho_text_new();
+ (*lines)[li]->text_above = erealloc((*lines)[li]->text_above, (c+1) * sizeof(struct ChoLineItemAbove *));
+ (*lines)[li]->text_above[c] = emalloc(sizeof(struct ChoLineItemAbove));
+ (*lines)[li]->text_above[c]->is_chord = false;
+ (*lines)[li]->text_above[c]->position = text_above_pos;
+ (*lines)[li]->text_above[c]->u.annot = cho_text_new();
}
- cho_style_free(songs[so]->sections[se]->lines[li]->text_above[c]->u.annot->style);
- songs[so]->sections[se]->lines[li]->text_above[c]->u.annot->style = cho_style_copy(tag_style);
+ cho_style_free((*lines)[li]->text_above[c]->u.annot->style);
+ (*lines)[li]->text_above[c]->u.annot->style = cho_style_copy(tag_style);
break;
default:
cho_log(LOG_ERR, "Invalid prev_state '%s'.", state_enums[prev_state]);
@@ -4646,17 +4655,17 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
cho_tag_attr_free(tags[ta]->attrs[at]);
tags[ta]->attrs[at] = NULL;
if (!strcmp(tags[ta]->name, "img")) {
- cho_text_free(songs[so]->sections[se]->lines[li]->items[ly]->u.text);
- songs[so]->sections[se]->lines[li]->items[ly]->is_text = false;
+ cho_text_free((*lines)[li]->items[ly]->u.text);
+ (*lines)[li]->items[ly]->is_text = false;
image = cho_image_tag_parse(tags[ta]->attrs);
if (!image) {
LOG_DEBUG("cho_image_tag_parse failed.");
return NULL;
}
- songs[so]->sections[se]->lines[li]->items[ly]->u.image = image;
+ (*lines)[li]->items[ly]->u.image = image;
ly++;
- songs[so]->sections[se]->lines[li]->items = erealloc(songs[so]->sections[se]->lines[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
- songs[so]->sections[se]->lines[li]->items[ly] = cho_line_item_new();
+ (*lines)[li]->items = erealloc((*lines)[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
+ (*lines)[li]->items[ly] = cho_line_item_new();
} else {
tag_style = cho_style_parse(tag_start, tags[ta]->attrs, cho_tag_style_inherit(tags, ta-1));
if (!tag_style) {
@@ -4666,16 +4675,16 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
tags[ta]->style = tag_style;
switch (prev_state) {
case STATE_LYRICS:
- cho_style_free(songs[so]->sections[se]->lines[li]->items[ly]->u.text->style);
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->style = cho_style_copy(tag_style);
+ cho_style_free((*lines)[li]->items[ly]->u.text->style);
+ (*lines)[li]->items[ly]->u.text->style = cho_style_copy(tag_style);
break;
case STATE_CHORD:
- cho_style_free(songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->style);
- songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->style = cho_style_copy(tag_style);
+ cho_style_free((*lines)[li]->text_above[c]->u.chord->style);
+ (*lines)[li]->text_above[c]->u.chord->style = cho_style_copy(tag_style);
break;
case STATE_ANNOTATION:
- cho_style_free(songs[so]->sections[se]->lines[li]->text_above[c]->u.annot->style);
- songs[so]->sections[se]->lines[li]->text_above[c]->u.annot->style = cho_style_copy(tag_style);
+ cho_style_free((*lines)[li]->text_above[c]->u.annot->style);
+ (*lines)[li]->text_above[c]->u.annot->style = cho_style_copy(tag_style);
break;
default:
cho_log(LOG_ERR, "Invalid prev_state '%s'.", state_enums[prev_state]);
@@ -4736,17 +4745,17 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
tags[ta]->attrs = erealloc(tags[ta]->attrs, (at+1) * sizeof(struct Attr *));
tags[ta]->attrs[at] = NULL;
if (!strcmp(tags[ta]->name, "img")) {
- cho_text_free(songs[so]->sections[se]->lines[li]->items[ly]->u.text);
- songs[so]->sections[se]->lines[li]->items[ly]->is_text = false;
+ cho_text_free((*lines)[li]->items[ly]->u.text);
+ (*lines)[li]->items[ly]->is_text = false;
image = cho_image_tag_parse(tags[ta]->attrs);
if (!image) {
LOG_DEBUG("cho_image_tag_parse failed.");
return NULL;
}
- songs[so]->sections[se]->lines[li]->items[ly]->u.image = image;
+ (*lines)[li]->items[ly]->u.image = image;
ly++;
- songs[so]->sections[se]->lines[li]->items = erealloc(songs[so]->sections[se]->lines[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
- songs[so]->sections[se]->lines[li]->items[ly] = cho_line_item_new();
+ (*lines)[li]->items = erealloc((*lines)[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
+ (*lines)[li]->items[ly] = cho_line_item_new();
} else {
tag_style = cho_style_parse(tag_start, tags[ta]->attrs, cho_tag_style_inherit(tags, ta-1));
if (!tag_style) {
@@ -4756,16 +4765,16 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
tags[ta]->style = tag_style;
switch (prev_state) {
case STATE_LYRICS:
- cho_style_free(songs[so]->sections[se]->lines[li]->items[ly]->u.text->style);
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->style = cho_style_copy(tag_style);
+ cho_style_free((*lines)[li]->items[ly]->u.text->style);
+ (*lines)[li]->items[ly]->u.text->style = cho_style_copy(tag_style);
break;
case STATE_CHORD:
- cho_style_free(songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->style);
- songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->style = cho_style_copy(tag_style);
+ cho_style_free((*lines)[li]->text_above[c]->u.chord->style);
+ (*lines)[li]->text_above[c]->u.chord->style = cho_style_copy(tag_style);
break;
case STATE_ANNOTATION:
- cho_style_free(songs[so]->sections[se]->lines[li]->text_above[c]->u.annot->style);
- songs[so]->sections[se]->lines[li]->text_above[c]->u.annot->style = cho_style_copy(tag_style);
+ cho_style_free((*lines)[li]->text_above[c]->u.annot->style);
+ (*lines)[li]->text_above[c]->u.annot->style = cho_style_copy(tag_style);
break;
default:
cho_log(LOG_ERR, "Invalid prev_state '%s'.", state_enums[prev_state]);
@@ -4815,24 +4824,24 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
e++;
}
free(tags);
- if (songs[so]->sections[se]->lines[li]->items[ly]->is_text) {
- if (songs[so]->sections[se]->lines[li]->items[ly]->u.text->text) {
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text = erealloc(songs[so]->sections[se]->lines[li]->items[ly]->u.text->text, (te+1) * sizeof(char));
- songs[so]->sections[se]->lines[li]->items[ly]->u.text->text[te] = 0;
+ if ((*lines)[li]->items[ly]->is_text) {
+ if ((*lines)[li]->items[ly]->u.text->text) {
+ (*lines)[li]->items[ly]->u.text->text = erealloc((*lines)[li]->items[ly]->u.text->text, (te+1) * sizeof(char));
+ (*lines)[li]->items[ly]->u.text->text[te] = 0;
ly++;
- songs[so]->sections[se]->lines[li]->items = erealloc(songs[so]->sections[se]->lines[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
- songs[so]->sections[se]->lines[li]->items[ly] = NULL;
- songs[so]->sections[se]->lines[li]->text_above = erealloc(songs[so]->sections[se]->lines[li]->text_above, (c+1) * sizeof(struct ChoLineItemAbove *));
- songs[so]->sections[se]->lines[li]->text_above[c] = NULL;
+ (*lines)[li]->items = erealloc((*lines)[li]->items, (ly+1) * sizeof(struct ChoLineItem *));
+ (*lines)[li]->items[ly] = NULL;
+ (*lines)[li]->text_above = erealloc((*lines)[li]->text_above, (c+1) * sizeof(struct ChoLineItemAbove *));
+ (*lines)[li]->text_above[c] = NULL;
li++;
- songs[so]->sections[se]->lines = erealloc(songs[so]->sections[se]->lines, (li+1) * sizeof(struct ChoLine *));
- songs[so]->sections[se]->lines[li] = NULL;
+ *lines = erealloc(*lines, (li+1) * sizeof(struct ChoLine *));
+ (*lines)[li] = NULL;
} else {
- cho_line_item_free(songs[so]->sections[se]->lines[li]->items[ly]);
- free(songs[so]->sections[se]->lines[li]->items);
- free(songs[so]->sections[se]->lines[li]->text_above);
- free(songs[so]->sections[se]->lines[li]);
- songs[so]->sections[se]->lines[li] = NULL;
+ cho_line_item_free((*lines)[li]->items[ly]);
+ free((*lines)[li]->items);
+ free((*lines)[li]->text_above);
+ free((*lines)[li]);
+ (*lines)[li] = NULL;
}
}
if (!cho_style_reset_default()) {
@@ -4849,13 +4858,19 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
so++;
songs = erealloc(songs, (so+1) * sizeof(struct ChoSong *));
songs[so] = NULL;
+ g_current_ftype = SF_TEXT;
+ g_prev_ftype = SF_TEXT;
+ g_config = NULL;
+ g_chordpro_filepath = NULL;
free(g_transpose_history);
g_transpose_history = NULL;
+ g_transpose = NULL;
g_line_number = 1;
for (e = 0; e<g_ia; e++) {
cho_image_free(g_image_assets[e]);
}
free(g_image_assets);
+ g_image_assets = NULL;
g_ia = 0;
bool exist_title = false;
for (so = 0; songs[so]; so++) {
diff --git a/chordpro.h b/chordpro.h
@@ -12,6 +12,40 @@
#define URL_MAX_LEN 2000
#define FONT_NAME_MAX 100
+enum Alignment {
+ A_LEFT,
+ A_CENTER,
+ A_RIGHT
+};
+
+enum Anchor {
+ AN_PAPER,
+ AN_PAGE,
+ AN_COLUMN,
+ AN_LINE,
+ AN_FLOAT
+};
+
+enum AttrValueSyntax {
+ AVS_NO,
+ AVS_QUOTATION_MARK,
+ AVS_APOSTROPHE,
+ AVS_UNQUOTED
+};
+
+enum BreakType {
+ BT_EMPTY,
+ BT_LINE,
+ BT_PAGE,
+ BT_COLUMN
+};
+
+enum ChordDiagramContent {
+ CDC_EMPTY,
+ CDC_STRING,
+ CDC_KEYBOARD
+};
+
enum ChordDiagramState {
CDS_NAME,
CDS_OPTION_NAME,
@@ -21,19 +55,29 @@ enum ChordDiagramState {
CDS_KEYS
};
-enum ChordDiagramContent {
- CDC_EMPTY,
- CDC_STRING,
- CDC_KEYBOARD
+enum ChordDirective {
+ TRANSPOSE, DEFINE /* , CHORD */
};
-enum MetadataDirective {
- TITLE,
- SUBTITLE
+enum ChordQualifier {
+ CQ_EMPTY,
+ CQ_MIN,
+ CQ_MAJ,
+ CQ_AUG,
+ CQ_DIM
};
-enum ChordDirective {
- TRANSPOSE, DEFINE /* , CHORD */
+enum DirectiveType {
+ DT_EMPTY,
+ DT_ENVIRONMENT,
+ DT_METADATA,
+ DT_FORMATTING,
+ DT_IMAGE,
+ DT_PREAMBLE,
+ DT_FONT,
+ DT_CHORD,
+ DT_OUTPUT,
+ DT_CUSTOM
};
enum FontFamily {
@@ -57,14 +101,6 @@ enum FontWeight {
FW_EMPTY
};
-struct Font {
- char *name;
- enum FontFamily family;
- enum FontStyle style;
- enum FontWeight weight;
- double size;
-};
-
enum LineStyle {
LS_SINGLE,
LS_DOUBLE,
@@ -72,52 +108,9 @@ enum LineStyle {
LS_EMPTY
};
-struct RGBColor {
- uint8_t red;
- uint8_t green;
- uint8_t blue;
-};
-
-struct ChoStyle {
- struct Font *font;
- struct RGBColor *foreground_color;
- struct RGBColor *background_color;
- enum LineStyle underline_style;
- struct RGBColor *underline_color;
- enum LineStyle overline_style;
- struct RGBColor *overline_color;
- bool strikethrough;
- struct RGBColor *strikethrough_color;
- bool boxed;
- struct RGBColor *boxed_color;
- double rise;
- char *href;
-};
-
-struct Attr {
- char *name;
- char *value;
-};
-
-struct Tag {
- char *name;
- struct ChoStyle *style;
- struct Attr **attrs;
- bool is_closed;
-};
-
-enum Alignment {
- A_LEFT,
- A_CENTER,
- A_RIGHT
-};
-
-enum Anchor {
- AN_PAPER,
- AN_PAGE,
- AN_COLUMN,
- AN_LINE,
- AN_FLOAT
+enum MetadataDirective {
+ TITLE,
+ SUBTITLE
};
enum OptionState {
@@ -125,47 +118,21 @@ enum OptionState {
OS_VALUE
};
-struct ChoImage {
- bool is_asset;
- char *id;
- char *src;
- struct Size *width;
- struct Size *height;
- struct Size *width_scale;
- struct Size *height_scale;
- enum Alignment align;
- double border;
- struct Size *spread_space;
- char *href;
- struct Size *x;
- struct Size *y;
- enum Anchor anchor;
- struct Size *dx;
- struct Size *dy;
- struct Size *w;
- struct Size *h;
- bool bbox;
-};
-
-enum AttrValueSyntax {
- AVS_NO,
- AVS_QUOTATION_MARK,
- AVS_APOSTROPHE,
- AVS_UNQUOTED
+enum Position {
+ POS_EMPTY,
+ POS_START,
+ POS_END
};
-enum State {
- STATE_LYRICS,
- STATE_DIRECTIVE_NAME,
- STATE_DIRECTIVE_VALUE,
- STATE_CHORD,
- STATE_ANNOTATION,
- STATE_MARKUP_TAG_START,
- STATE_MARKUP_TAG_END,
- STATE_MARKUP_TAG,
- STATE_MARKUP_ATTR_NAME,
- STATE_MARKUP_ATTR_VALUE,
- STATE_COMMENT
+enum SectionType {
+ ST_EMPTY,
+ ST_NEWSONG,
+ ST_CHORUS,
+ ST_VERSE,
+ ST_BRIDGE,
+ ST_TAB,
+ ST_GRID,
+ ST_CUSTOM
};
enum SongFragmentType {
@@ -183,6 +150,20 @@ enum SongFragmentType {
SF_LABEL
};
+enum State {
+ STATE_LYRICS,
+ STATE_DIRECTIVE_NAME,
+ STATE_DIRECTIVE_VALUE,
+ STATE_CHORD,
+ STATE_ANNOTATION,
+ STATE_MARKUP_TAG_START,
+ STATE_MARKUP_TAG_END,
+ STATE_MARKUP_TAG,
+ STATE_MARKUP_ATTR_NAME,
+ STATE_MARKUP_ATTR_VALUE,
+ STATE_COMMENT
+};
+
enum StylePropertyType {
SPT_EMPTY,
SPT_FONT,
@@ -190,61 +171,49 @@ enum StylePropertyType {
SPT_COLOR
};
-union StylePropertyValue {
- char *font_name;
- double font_size;
- struct RGBColor *foreground_color;
-};
-
-struct StyleProperty {
- enum SongFragmentType ftype;
- enum StylePropertyType type;
- union StylePropertyValue u;
-};
-
-enum DirectiveType {
- DT_EMPTY,
- DT_ENVIRONMENT,
- DT_METADATA,
- DT_FORMATTING,
- DT_IMAGE,
- DT_PREAMBLE,
- DT_FONT,
- DT_CHORD,
- DT_OUTPUT,
- DT_CUSTOM
+struct Attr {
+ char *name;
+ char *value;
};
-enum SectionType {
- ST_EMPTY,
- ST_NEWSONG,
- ST_CHORUS,
- ST_VERSE,
- ST_BRIDGE,
- ST_TAB,
- ST_GRID,
- ST_CUSTOM
+struct Font {
+ char *name;
+ enum FontFamily family;
+ enum FontStyle style;
+ enum FontWeight weight;
+ double size;
};
-enum Position {
- POS_EMPTY,
- POS_START,
- POS_END
+struct RGBColor {
+ uint8_t red;
+ uint8_t green;
+ uint8_t blue;
};
-enum ChordQualifier {
- CQ_EMPTY,
- CQ_MIN,
- CQ_MAJ,
- CQ_AUG,
- CQ_DIM
+struct ChoStyle {
+ struct Font *font;
+ struct RGBColor *foreground_color;
+ struct RGBColor *background_color;
+ enum LineStyle underline_style;
+ struct RGBColor *underline_color;
+ enum LineStyle overline_style;
+ struct RGBColor *overline_color;
+ bool strikethrough;
+ struct RGBColor *strikethrough_color;
+ bool boxed;
+ struct RGBColor *boxed_color;
+ double rise;
+ char *href;
};
-enum BreakType {
- BT_EMPTY,
- BT_LINE,
- BT_PAGE,
- BT_COLUMN
+struct ChoChord {
+ struct ChoStyle *style;
+ bool is_canonical;
+ char *name;
+ char *root;
+ enum ChordQualifier qual;
+ char *ext;
+ char *bass;
};
/*
@@ -264,20 +233,26 @@ struct ChoDirective {
struct ChoStyle *style;
};
-struct ChoMetadata {
- char *name;
- char *value;
- struct ChoStyle *style;
-};
-
-struct ChoChord {
- struct ChoStyle *style;
- bool is_canonical;
- char *name;
- char *root;
- enum ChordQualifier qual;
- char *ext;
- char *bass;
+struct ChoImage {
+ bool is_asset;
+ char *id;
+ char *src;
+ struct Size *width;
+ struct Size *height;
+ struct Size *width_scale;
+ struct Size *height_scale;
+ enum Alignment align;
+ double border;
+ struct Size *spread_space;
+ char *href;
+ struct Size *x;
+ struct Size *y;
+ enum Anchor anchor;
+ struct Size *dx;
+ struct Size *dy;
+ struct Size *w;
+ struct Size *h;
+ bool bbox;
};
struct ChoText {
@@ -308,6 +283,12 @@ struct ChoLine {
enum BreakType btype;
};
+struct ChoMetadata {
+ char *name;
+ char *value;
+ struct ChoStyle *style;
+};
+
struct ChoSection {
enum SectionType type;
struct ChoText *label;
@@ -320,6 +301,26 @@ struct ChoSong {
struct ChordDiagram **diagrams;
};
+union StylePropertyValue {
+ char *font_name;
+ double font_size;
+ struct RGBColor *foreground_color;
+};
+
+struct StyleProperty {
+ enum SongFragmentType ftype;
+ enum StylePropertyType type;
+ union StylePropertyValue u;
+};
+
+struct Tag {
+ char *name;
+ struct ChoStyle *style;
+ struct Attr **attrs;
+ bool is_closed;
+};
+
+
struct ChoSong **cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config);
int cho_song_count(struct ChoSong **songs);
int cho_song_compare(const void *a, const void *b);
diff --git a/out_pdf.h b/out_pdf.h
@@ -19,27 +19,21 @@ enum LineLocation {
LL_UNDER
};
-struct Obj {
- char *name;
- pdfio_obj_t *value;
-};
-
-struct SpaceNeeded {
+struct CharPosition {
int line_item_index;
int text_index;
- int text_above_index;
- double amount;
};
-struct CharPosition {
- int line_item_index;
- int text_index;
+struct Obj {
+ char *name;
+ pdfio_obj_t *value;
};
-struct TocEntry {
- int page_index;
- double page_y;
- char *title;
+struct PDFText {
+ char *text;
+ struct ChoStyle *style;
+ double x;
+ double y;
};
struct PDFImage {
@@ -51,13 +45,6 @@ struct PDFImage {
pdfio_obj_t *obj;
};
-struct PDFText {
- char *text;
- struct ChoStyle *style;
- double x;
- double y;
-};
-
struct PDFPage {
struct PDFText **texts;
struct PDFImage **images;
@@ -65,11 +52,24 @@ struct PDFPage {
struct ChordDiagram **diagrams;
};
+struct TocEntry {
+ int page_index;
+ double page_y;
+ char *title;
+};
+
struct PDFContent {
struct PDFPage **pages;
struct TocEntry **toc;
};
+struct SpaceNeeded {
+ int line_item_index;
+ int text_index;
+ int text_above_index;
+ double amount;
+};
+
struct PDFContext {
struct PDFContent *content;
double x;