commit ec7555903f9aa96f70cad05acd9c05e9a7098259
parent a4368b630d09cf6b5ba2631a93ce1f314d0387f4
Author: nibo <nibo@relim.de>
Date: Sun, 6 Oct 2024 11:05:06 +0200
Speed up enum to string conversion
Instead of having a switch statement for
getting the string represenation for an
enum now there is a character array for
each enum with the elements ordered the
same way as the enum variants. Then you
can access the string like this:
enum_variants[ENUM_VARIANT] => "ENUM_VARIANT"
Diffstat:
| M | chordpro.c | | | 703 | +++++++++++++++++++++++++++++++++++++++++-------------------------------------- |
| M | chordpro.h | | | 118 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------- |
| M | config.c | | | 47 | +++++++++++++++++++++++------------------------ |
| M | todo | | | 2 | +- |
4 files changed, 492 insertions(+), 378 deletions(-)
diff --git a/chordpro.c b/chordpro.c
@@ -29,12 +29,11 @@ static const char *metadata_directives[] = {
static const char *formatting_directives[] = {
"comment", "c", "highlight", "comment_italic", "ci",
- "comment_box", "cb", "image", NULL
+ "comment_box", "cb", NULL
};
-static const char *preamble_directives[] = {
- "new_song", "ns", NULL
-};
+static const char *image_directives[] = { "image", NULL };
+static const char *preamble_directives[] = { "new_song", "ns", NULL };
static const char *font_directives[] = {
"chordfont", "cf", "chordsize", "cs", "chordcolour",
@@ -55,6 +54,26 @@ static const char *output_directives[] = {
"new_page", "np", "column_break", "colb", NULL
};
+static const char *font_families[] = { "normal", "sans", "serif", "monospace", "empty" };
+static const char *font_styles[] = { "normal", "oblique", "italic", "empty" };
+static const char *font_weights[] = { "normal", "bold", "empty" };
+static const char *line_styles[] = { "single", "double", "none", "empty" };
+static const char *chord_qualifiers[] = { "", "m", "", "+", "°" };
+
+static const char *state_enums[] = {
+ "STATE_LYRICS",
+ "STATE_DIRECTIVE_NAME",
+ "STATE_DIRECTIVE_VALUE",
+ "STATE_CHORD",
+ "STATE_ANNOTATION",
+ "STATE_MARKUP_TAG_BEGIN",
+ "STATE_MARKUP_TAG_END",
+ "STATE_MARKUP_TAG",
+ "STATE_MARKUP_ATTR_NAME",
+ "STATE_MARKUP_ATTR_VALUE",
+ "STATE_COMMENT"
+};
+
struct StyleProperty default_style_properties[18] = {
{ SF_CHORD, SPT_FONT, { .font_name = NULL } },
{ SF_CHORD, SPT_SIZE, { .font_size = EMPTY } },
@@ -163,21 +182,65 @@ static int *g_transpose = NULL;
#ifdef DEBUG
-static const char *cho_debug_chord_qualifier_to_string(enum ChordQualifier qual)
-{
- switch (qual) {
- case CQ_MIN:
- return "CQ_MIN";
- case CQ_MAJ:
- return "CQ_MAJ";
- case CQ_AUG:
- return "CQ_AUG";
- case CQ_DIM:
- return "CQ_DIM";
- default:
- return "CQ_EMPTY";
- }
-}
+static char *chord_qualifier_enums[] = {
+ "CQ_EMPTY",
+ "CQ_MIN",
+ "CQ_MAJ",
+ "CQ_AUG",
+ "CQ_DIM"
+};
+
+const char *directive_type_enums[] = {
+ "DT_EMPTY",
+ "DT_ENVIRONMENT",
+ "DT_METADATA",
+ "DT_FORMATTING",
+ "DT_IMAGE",
+ "DT_PREAMBLE",
+ "DT_FONT",
+ "DT_CHORD",
+ "DT_OUTPUT",
+ "DT_CUSTOM"
+};
+
+const char *section_type_enums[] = {
+ "ST_EMPTY",
+ "ST_NEWSONG",
+ "ST_CHORUS",
+ "ST_VERSE",
+ "ST_BRIDGE",
+ "ST_TAB",
+ "ST_GRID",
+ "ST_CUSTOM"
+};
+
+const char *position_enums[] = {
+ "POS_EMPTY",
+ "POS_START",
+ "POS_END"
+};
+
+const char *song_fragment_type_enums[] = {
+ "SF_EMPTY",
+ "SF_CHORD",
+ "SF_ANNOT",
+ "SF_CHORUS",
+ "SF_FOOTER",
+ "SF_GRID",
+ "SF_TAB",
+ "SF_TOC",
+ "SF_TEXT",
+ "SF_TITLE",
+ "SF_SUBTITLE",
+ "SF_LABEL"
+};
+
+const char *style_property_type_enums[] = {
+ "SPT_EMPTY",
+ "SPT_FONT",
+ "SPT_SIZE",
+ "SPT_COLOR"
+};
static void cho_debug_chord_print(struct ChoChord *chord)
{
@@ -189,7 +252,7 @@ static void cho_debug_chord_print(struct ChoChord *chord)
} else {
printf("root: 'NULL'\n");
}
- printf("qual: '%s'\n", cho_debug_chord_qualifier_to_string(chord->qual));
+ printf("qual: '%s'\n", chord_qualifier_enums[chord->qual]);
if (chord->ext) {
printf("ext: '%s'\n", chord->ext);
} else {
@@ -205,35 +268,6 @@ static void cho_debug_chord_print(struct ChoChord *chord)
#endif /* DEBUG */
-static const char *cho_state_to_string(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";
- case STATE_ANNOTATION:
- return "STATE_ANNOTATION";
- case STATE_MARKUP_TAG_BEGIN:
- return "STATE_MARKUP_TAG_BEGIN";
- case STATE_MARKUP_TAG_END:
- return "STATE_MARKUP_TAG_END";
- case STATE_MARKUP_TAG:
- return "STATE_MARKUP_TAG";
- case STATE_MARKUP_ATTR_NAME:
- return "STATE_MARKUP_ATTR_NAME";
- case STATE_MARKUP_ATTR_VALUE:
- return "STATE_MARKUP_ATTR_VALUE";
- case STATE_COMMENT:
- return "STATE_COMMENT";
- }
- return "";
-}
-
static inline bool is_whitespace(char c)
{
if (
@@ -475,13 +509,13 @@ void cho_fonts_free(struct Font **fonts)
enum FontFamily cho_font_family_parse(const char *str)
{
- if (strcasecmp(str, "sans") == 0) {
+ if (!strcmp(str, font_families[FF_SANS])) {
return FF_SANS;
- } else if (strcasecmp(str, "serif") == 0) {
+ } else if (!strcmp(str, font_families[FF_SERIF])) {
return FF_SERIF;
- } else if (strcasecmp(str, "monospace") == 0) {
+ } else if (!strcmp(str, font_families[FF_MONOSPACE])) {
return FF_MONOSPACE;
- } else if (strcasecmp(str, "normal") == 0) {
+ } else if (!strcmp(str, font_families[FF_NORMAL])) {
return FF_NORMAL;
} else {
return FF_EMPTY;
@@ -490,25 +524,16 @@ enum FontFamily cho_font_family_parse(const char *str)
const char *cho_font_family_to_config_string(enum FontFamily font_family)
{
- switch (font_family) {
- case FF_SANS:
- return "sans";
- case FF_SERIF:
- return "serif";
- case FF_MONOSPACE:
- return "monospace";
- default:
- return "normal";
- }
+ return font_families[font_family];
}
enum FontStyle cho_font_style_parse(const char *str)
{
- if (strcasecmp(str, "italic") == 0) {
+ if (!strcmp(str, font_styles[FS_ITALIC])) {
return FS_ITALIC;
- } else if (strcasecmp(str, "oblique") == 0) {
+ } else if (!strcmp(str, font_styles[FS_OBLIQUE])) {
return FS_OBLIQUE;
- } else if (strcasecmp(str, "normal") == 0) {
+ } else if (!strcmp(str, font_styles[FS_ROMAN])) {
return FS_ROMAN;
} else {
return FS_EMPTY;
@@ -517,11 +542,7 @@ enum FontStyle cho_font_style_parse(const char *str)
const char *cho_font_style_to_config_string(enum FontStyle style)
{
- if (style == FS_ITALIC)
- return "italic";
- if (style == FS_OBLIQUE)
- return "oblique";
- return "normal";
+ return font_styles[style];
}
enum FontWeight cho_font_weight_parse(const char *str)
@@ -537,9 +558,7 @@ enum FontWeight cho_font_weight_parse(const char *str)
const char *cho_font_weight_to_config_string(enum FontWeight weight)
{
- if (weight == FW_BOLD)
- return "bold";
- return "normal";
+ return font_weights[weight];
}
void cho_font_print_as_toml(struct Font *font, const char *section)
@@ -583,16 +602,66 @@ enum LineStyle cho_linestyle_parse(const char *str)
const char *cho_linestyle_to_config_string(enum LineStyle linestyle)
{
- switch (linestyle) {
- case LS_SINGLE:
- return "single";
- case LS_DOUBLE:
- return "double";
- default:
- return "none";
+ return line_styles[linestyle];
+}
+
+#ifdef DEBUG
+
+static void cho_debug_the_default_style_properties(void)
+{
+ unsigned int i;
+ for (i = 0; i<LENGTH(default_style_properties); i++) {
+ printf(
+ "%s %s ",
+ song_fragment_type_enums[default_style_properties[i].ftype],
+ style_property_type_enums[default_style_properties[i].type]
+ );
+ switch (default_style_properties[i].type) {
+ case SPT_FONT:
+ if (default_style_properties[i].u.font_name)
+ printf("%s\n", default_style_properties[i].u.font_name);
+ else
+ printf("NULL\n");
+ break;
+ case SPT_SIZE:
+ printf("%.1f\n", default_style_properties[i].u.font_size);
+ break;
+ case SPT_COLOR:
+ if (default_style_properties[i].u.foreground_color)
+ printf("%s\n", cho_rgbcolor_to_string(default_style_properties[i].u.foreground_color));
+ else
+ printf("NULL\n");
+ break;
+ default:
+ printf("Invalid StylePropertyType value '%d'.\n", default_style_properties[i].type);
+ }
}
}
+void cho_debug_style_print(struct Style *style)
+{
+ printf("---- BEGIN STYLE ----\n");
+ cho_font_print(style->font);
+ printf("foreground_color: %s\n", cho_rgbcolor_to_string(style->foreground_color));
+ printf("background_color: %s\n", cho_rgbcolor_to_string(style->background_color));
+ printf("underline_style: %s\n", cho_linestyle_to_config_string(style->underline_style));
+ printf("underline_color: %s\n", cho_rgbcolor_to_string(style->underline_color));
+ printf("overline_style: %s\n", cho_linestyle_to_config_string(style->overline_style));
+ printf("overline_color: %s\n", cho_rgbcolor_to_string(style->overline_color));
+ printf("strikethrough: %d\n", style->strikethrough);
+ printf("strikethrough_color: %s\n", cho_rgbcolor_to_string(style->strikethrough_color));
+ printf("boxed: %d\n", style->boxed);
+ printf("boxed_color: %s\n", cho_rgbcolor_to_string(style->boxed_color));
+ printf("rise: %f\n", style->rise);
+ if (style->href)
+ printf("href: %s\n", style->href);
+ else
+ printf("href: NULL\n");
+ printf("---- END STYLE ------\n\n");
+}
+
+#endif /* DEBUG */
+
static bool cho_style_property_apply_default(enum SongFragmentType current_ftype, enum StylePropertyType ptype, struct Style *style)
{
unsigned int i;
@@ -1286,12 +1355,6 @@ static struct Style *cho_tag_style_inherit(struct Tag **tags, int prev_index)
return NULL;
}
-static void cho_directive_free(struct ChoDirective *directive)
-{
- cho_style_free(directive->style);
- free(directive);
-}
-
static struct ChoMetadata *cho_metadata_new(void)
{
struct ChoMetadata *meta = malloc(sizeof(struct ChoMetadata));
@@ -1539,20 +1602,6 @@ static char *cho_chord_qualifier_strip(const char *str)
return strdup(str);
}
-static const char *cho_chord_qualifier_to_string(enum ChordQualifier qual)
-{
- switch (qual) {
- case CQ_MIN:
- return "m";
- case CQ_AUG:
- return "+";
- case CQ_DIM:
- return "°";
- default:
- return "";
- }
-}
-
static int cho_chord_qualifier_and_extension_parse(const char *str, struct ChoChord *chord)
{
int i;
@@ -1674,7 +1723,7 @@ char *cho_chord_name_generate(struct ChoChord *chord)
name[n] = chord->root[i];
n++;
}
- const char *qual = cho_chord_qualifier_to_string(chord->qual);
+ const char *qual = chord_qualifiers[chord->qual];
name_len += strlen(qual);
name = realloc(name, name_len * sizeof(char));
for (i = 0; qual[i]; i++) {
@@ -1866,6 +1915,134 @@ void cho_songs_free(struct ChoSong **songs)
free(songs);
}
+static struct ChoImage *cho_image_new(void)
+{
+ struct ChoImage *image = malloc(sizeof(struct ChoImage));
+ image->id = NULL;
+ image->src = NULL;
+ image->width = EMPTY;
+ image->height = EMPTY;
+ image->scale = EMPTY;
+ image->align = A_CENTER;
+ image->border = EMPTY;
+ image->spread_space = EMPTY;
+ image->href = NULL;
+ image->x = EMPTY;
+ image->y = EMPTY;
+ image->anchor = AN_FLOAT;
+ image->dx = EMPTY;
+ image->dy = EMPTY;
+ image->w = EMPTY;
+ image->h = EMPTY;
+ return image;
+}
+
+static void cho_image_free(struct ChoImage *image)
+{
+ free(image->id);
+ free(image->src);
+ free(image->href);
+ free(image);
+}
+
+enum OptionState {
+ OS_NAME,
+ OS_VALUE
+};
+
+static struct ChoImage *cho_image_directive_parse(const char *str, size_t line_number)
+{
+ struct ChoImage *image = cho_image_new();
+ int i = 0;
+ while (is_whitespace(str[i])) {
+ i++;
+ }
+ char c;
+ enum OptionState state = OS_NAME;
+ enum AttrValueSyntax avs = AVS_NO;
+ char name[6+1];
+ char value[URL_MAX_LEN+1];
+ int n = 0;
+ int v = 0;
+ memset(name, 0, sizeof(name));
+ memset(value, 0, sizeof(value));
+ for (; str[i] != 0; i++) {
+ c = str[i];
+ switch (state) {
+ case OS_NAME:
+ if (is_whitespace(c)) {
+ if (n == 0) {
+ break;
+ } else {
+ name[n] = 0;
+ fprintf(stderr, "ERR: Option with name '%s' in image directive in line '%ld' has no value.\n", name, line_number);
+ return NULL;
+ }
+ }
+ if (c == '=') {
+ name[n] = 0;
+ memset(name, 0, n);
+ n = 0;
+ state = OS_VALUE;
+ break;
+ }
+ if (n > 5) {
+ fprintf(stderr, "ERR: Option name in image directive in line '%ld' is too long.\n", line_number);
+ return NULL;
+ }
+ name[n] = c;
+ n++;
+ break;
+ case OS_VALUE:
+ if (avs == AVS_NO) {
+ if (is_whitespace(c)) {
+ fprintf(stderr, "ERR: Whitespace character after equals sign in image directive in line '%ld' is invalid.\n", line_number);
+ return NULL;
+ }
+ if (c == '\'') {
+ avs = AVS_APOSTROPHE;
+ } else if (c == '"') {
+ avs = AVS_QUOTATION_MARK;
+ } else {
+ avs = AVS_UNQUOTED;
+ value[v] = c;
+ v++;
+ }
+ break;
+ }
+ if (c == '\n') {
+ fprintf(stderr, "ERR: Newline character inside an option value in image directive in line '%ld' is invalid.\n", line_number);
+ return NULL;
+ }
+ if (
+ (avs == AVS_APOSTROPHE && c == '\'') ||
+ (avs == AVS_QUOTATION_MARK && c == '"') ||
+ (avs == AVS_UNQUOTED && (c == ' ' || c == '\t'))
+ ) {
+ value[v] = 0;
+ printf("value: '%s'\n", value);
+ memset(value, 0, v);
+ v = 0;
+ avs = AVS_NO;
+ state = OS_NAME;
+ break;
+ }
+ value[v] = c;
+ v++;
+ break;
+ }
+ }
+ if (avs == AVS_UNQUOTED) {
+ value[v] = 0;
+ printf("value: '%s'\n", value);
+ }
+ return image;
+}
+
+/* static struct ChoImage *cho_image_tag_parse(const char *str)
+{
+} */
+
static struct ChoDirective *cho_directive_new(void)
{
struct ChoDirective *directive = malloc(sizeof(struct ChoDirective));
@@ -1879,13 +2056,19 @@ static struct ChoDirective *cho_directive_new(void)
return directive;
}
+static void cho_directive_free(struct ChoDirective *directive)
+{
+ cho_style_free(directive->style);
+ free(directive);
+}
+
static struct ChoDirective *cho_directive_parse(const char *name)
{
struct ChoDirective *directive = cho_directive_new();
int i = 0;
if (
- strcmp(name, environment_directives[0]) == 0 ||
- strcmp(name, environment_directives[1]) == 0
+ strcmp(name, environment_directives[START_OF_CHORUS]) == 0 ||
+ strcmp(name, environment_directives[SOC]) == 0
) {
directive->dtype = DT_ENVIRONMENT;
directive->position = POS_START;
@@ -1893,8 +2076,8 @@ static struct ChoDirective *cho_directive_parse(const char *name)
directive->ftype = SF_CHORUS;
goto END;
} else if (
- strcmp(name, environment_directives[2]) == 0 ||
- strcmp(name, environment_directives[3]) == 0
+ strcmp(name, environment_directives[END_OF_CHORUS]) == 0 ||
+ strcmp(name, environment_directives[EOC]) == 0
) {
directive->dtype = DT_ENVIRONMENT;
directive->position = POS_END;
@@ -1902,8 +2085,8 @@ static struct ChoDirective *cho_directive_parse(const char *name)
directive->ftype = SF_TEXT;
goto END;
} else if (
- strcmp(name, environment_directives[5]) == 0 ||
- strcmp(name, environment_directives[6]) == 0
+ strcmp(name, environment_directives[START_OF_VERSE]) == 0 ||
+ strcmp(name, environment_directives[SOV]) == 0
) {
directive->dtype = DT_ENVIRONMENT;
directive->position = POS_START;
@@ -1911,8 +2094,8 @@ static struct ChoDirective *cho_directive_parse(const char *name)
directive->ftype = SF_TEXT;
goto END;
} else if (
- strcmp(name, environment_directives[7]) == 0 ||
- strcmp(name, environment_directives[8]) == 0
+ strcmp(name, environment_directives[END_OF_VERSE]) == 0 ||
+ strcmp(name, environment_directives[EOV]) == 0
) {
directive->dtype = DT_ENVIRONMENT;
directive->position = POS_END;
@@ -1920,8 +2103,8 @@ static struct ChoDirective *cho_directive_parse(const char *name)
directive->ftype = SF_TEXT;
goto END;
} else if (
- strcmp(name, environment_directives[9]) == 0 ||
- strcmp(name, environment_directives[10]) == 0
+ strcmp(name, environment_directives[START_OF_BRIDGE]) == 0 ||
+ strcmp(name, environment_directives[SOB]) == 0
) {
directive->dtype = DT_ENVIRONMENT;
directive->position = POS_START;
@@ -1929,8 +2112,8 @@ static struct ChoDirective *cho_directive_parse(const char *name)
directive->ftype = SF_TEXT;
goto END;
} else if (
- strcmp(name, environment_directives[11]) == 0 ||
- strcmp(name, environment_directives[12]) == 0
+ strcmp(name, environment_directives[END_OF_BRIDGE]) == 0 ||
+ strcmp(name, environment_directives[EOB]) == 0
) {
directive->dtype = DT_ENVIRONMENT;
directive->position = POS_END;
@@ -1938,8 +2121,8 @@ static struct ChoDirective *cho_directive_parse(const char *name)
directive->ftype = SF_TEXT;
goto END;
} else if (
- strcmp(name, environment_directives[13]) == 0 ||
- strcmp(name, environment_directives[14]) == 0
+ strcmp(name, environment_directives[START_OF_TAB]) == 0 ||
+ strcmp(name, environment_directives[SOT]) == 0
) {
directive->dtype = DT_ENVIRONMENT;
directive->position = POS_START;
@@ -1947,8 +2130,8 @@ static struct ChoDirective *cho_directive_parse(const char *name)
directive->ftype = SF_TAB;
goto END;
} else if (
- strcmp(name, environment_directives[15]) == 0 ||
- strcmp(name, environment_directives[16]) == 0
+ strcmp(name, environment_directives[END_OF_TAB]) == 0 ||
+ strcmp(name, environment_directives[EOT]) == 0
) {
directive->dtype = DT_ENVIRONMENT;
directive->position = POS_END;
@@ -1956,8 +2139,8 @@ static struct ChoDirective *cho_directive_parse(const char *name)
directive->ftype = SF_TEXT;
goto END;
} else if (
- strcmp(name, environment_directives[17]) == 0 ||
- strcmp(name, environment_directives[18]) == 0
+ strcmp(name, environment_directives[START_OF_GRID]) == 0 ||
+ strcmp(name, environment_directives[SOG]) == 0
) {
directive->dtype = DT_ENVIRONMENT;
directive->position = POS_START;
@@ -1965,8 +2148,8 @@ static struct ChoDirective *cho_directive_parse(const char *name)
directive->ftype = SF_GRID;
goto END;
} else if (
- strcmp(name, environment_directives[19]) == 0 ||
- strcmp(name, environment_directives[20]) == 0
+ strcmp(name, environment_directives[END_OF_GRID]) == 0 ||
+ strcmp(name, environment_directives[EOG]) == 0
) {
directive->dtype = DT_ENVIRONMENT;
directive->position = POS_END;
@@ -1983,28 +2166,32 @@ static struct ChoDirective *cho_directive_parse(const char *name)
}
i = 0;
if (
- strcmp(formatting_directives[0], name) == 0 ||
- strcmp(formatting_directives[1], name) == 0 ||
- strcmp(formatting_directives[2], name) == 0
+ strcmp(formatting_directives[COMMENT], name) == 0 ||
+ strcmp(formatting_directives[C], name) == 0 ||
+ strcmp(formatting_directives[HIGHLIGHT], name) == 0
) {
directive->style->background_color = cho_rgbcolor_new(228, 228, 228);
directive->dtype = DT_FORMATTING;
goto END;
} else if (
- strcmp(formatting_directives[3], name) == 0 ||
- strcmp(formatting_directives[4], name) == 0
+ strcmp(formatting_directives[COMMENT_ITALIC], name) == 0 ||
+ strcmp(formatting_directives[CI], name) == 0
) {
directive->style->font->style = FS_ITALIC;
directive->dtype = DT_FORMATTING;
goto END;
} else if (
- strcmp(formatting_directives[5], name) == 0 ||
- strcmp(formatting_directives[6], name) == 0
+ strcmp(formatting_directives[COMMENT_BOX], name) == 0 ||
+ strcmp(formatting_directives[CB], name) == 0
) {
directive->style->boxed = true;
directive->dtype = DT_FORMATTING;
goto END;
}
+ if (strcmp(image_directives[IMAGE], name) == 0) {
+ directive->dtype = DT_IMAGE;
+ goto END;
+ }
while (preamble_directives[i] != NULL) {
if (strcmp(preamble_directives[i], name) == 0) {
directive->dtype = DT_PREAMBLE;
@@ -2014,122 +2201,122 @@ static struct ChoDirective *cho_directive_parse(const char *name)
i++;
}
if (
- strcmp(font_directives[0], name) == 0 ||
- strcmp(font_directives[1], name) == 0
+ strcmp(font_directives[CHORDFONT], name) == 0 ||
+ strcmp(font_directives[CF], name) == 0
) {
directive->dtype = DT_FONT;
directive->sprop = SPT_FONT;
directive->ftype = SF_CHORD;
goto END;
} else if (
- strcmp(font_directives[2], name) == 0 ||
- strcmp(font_directives[3], name) == 0
+ strcmp(font_directives[CHORDSIZE], name) == 0 ||
+ strcmp(font_directives[CS], name) == 0
) {
directive->dtype = DT_FONT;
directive->sprop = SPT_SIZE;
directive->ftype = SF_CHORD;
goto END;
- } else if (strcmp(font_directives[4], name) == 0) {
+ } else if (strcmp(font_directives[CHORDCOLOR], name) == 0) {
directive->dtype = DT_FONT;
directive->sprop = SPT_COLOR;
directive->ftype = SF_CHORD;
goto END;
- } else if (strcmp(font_directives[5], name) == 0) {
+ } else if (strcmp(font_directives[CHORUSFONT], name) == 0) {
directive->dtype = DT_FONT;
directive->sprop = SPT_FONT;
directive->ftype = SF_CHORUS;
goto END;
- } else if (strcmp(font_directives[6], name) == 0) {
+ } else if (strcmp(font_directives[CHORUSSIZE], name) == 0) {
directive->dtype = DT_FONT;
directive->sprop = SPT_SIZE;
directive->ftype = SF_CHORUS;
goto END;
- } else if (strcmp(font_directives[7], name) == 0) {
+ } else if (strcmp(font_directives[CHORUSCOLOR], name) == 0) {
directive->dtype = DT_FONT;
directive->sprop = SPT_COLOR;
directive->ftype = SF_CHORUS;
goto END;
- } else if (strcmp(font_directives[8], name) == 0) {
+ } else if (strcmp(font_directives[GRIDFONT], name) == 0) {
directive->dtype = DT_FONT;
directive->sprop = SPT_FONT;
directive->ftype = SF_GRID;
goto END;
- } else if (strcmp(font_directives[9], name) == 0) {
+ } else if (strcmp(font_directives[GRIDSIZE], name) == 0) {
directive->dtype = DT_FONT;
directive->sprop = SPT_SIZE;
directive->ftype = SF_GRID;
goto END;
- } else if (strcmp(font_directives[10], name) == 0) {
+ } else if (strcmp(font_directives[GRIDCOLOR], name) == 0) {
directive->dtype = DT_FONT;
directive->sprop = SPT_COLOR;
directive->ftype = SF_GRID;
goto END;
- } else if (strcmp(font_directives[11], name) == 0) {
+ } else if (strcmp(font_directives[TABFONT], name) == 0) {
directive->dtype = DT_FONT;
directive->sprop = SPT_FONT;
directive->ftype = SF_TAB;
goto END;
- } else if (strcmp(font_directives[12], name) == 0) {
+ } else if (strcmp(font_directives[TABSIZE], name) == 0) {
directive->dtype = DT_FONT;
directive->sprop = SPT_SIZE;
directive->ftype = SF_TAB;
goto END;
- } else if (strcmp(font_directives[13], name) == 0) {
+ } else if (strcmp(font_directives[TABCOLOR], name) == 0) {
directive->dtype = DT_FONT;
directive->sprop = SPT_COLOR;
directive->ftype = SF_TAB;
goto END;
} else if (
- strcmp(font_directives[14], name) == 0 ||
- strcmp(font_directives[15], name) == 0
+ strcmp(font_directives[TEXTFONT], name) == 0 ||
+ strcmp(font_directives[TF], name) == 0
) {
directive->dtype = DT_FONT;
directive->sprop = SPT_FONT;
directive->ftype = SF_TEXT;
goto END;
} else if (
- strcmp(font_directives[16], name) == 0 ||
- strcmp(font_directives[17], name) == 0
+ strcmp(font_directives[TEXTSIZE], name) == 0 ||
+ strcmp(font_directives[TS], name) == 0
) {
directive->dtype = DT_FONT;
directive->sprop = SPT_SIZE;
directive->ftype = SF_TEXT;
goto END;
- } else if (strcmp(font_directives[18], name) == 0) {
+ } else if (strcmp(font_directives[TEXTCOLOR], name) == 0) {
directive->dtype = DT_FONT;
directive->sprop = SPT_COLOR;
directive->ftype = SF_TEXT;
goto END;
- } else if (strcmp(font_directives[19], name) == 0) {
+ } else if (strcmp(font_directives[TITLEFONT], name) == 0) {
directive->dtype = DT_FONT;
directive->sprop = SPT_FONT;
directive->ftype = SF_TITLE;
goto END;
- } else if (strcmp(font_directives[20], name) == 0) {
+ } else if (strcmp(font_directives[TITLESIZE], name) == 0) {
directive->dtype = DT_FONT;
directive->sprop = SPT_SIZE;
directive->ftype = SF_TITLE;
goto END;
- } else if (strcmp(font_directives[21], name) == 0) {
+ } else if (strcmp(font_directives[TITLECOLOR], name) == 0) {
directive->dtype = DT_FONT;
directive->sprop = SPT_COLOR;
directive->ftype = SF_TITLE;
goto END;
}
- if (strcmp(chord_directives[0], name) == 0) {
+ if (strcmp(chord_directives[TRANSPOSE], name) == 0) {
directive->dtype = DT_CHORD;
goto END;
}
if (
- strcmp(output_directives[0], name) == 0 ||
- strcmp(output_directives[1], name) == 0
+ strcmp(output_directives[NEW_PAGE], name) == 0 ||
+ strcmp(output_directives[NP], name) == 0
) {
directive->dtype = DT_OUTPUT;
directive->btype = BT_PAGE;
goto END;
} else if (
- strcmp(output_directives[2], name) == 0 ||
- strcmp(output_directives[3], name) == 0
+ strcmp(output_directives[COLUMN_BREAK], name) == 0 ||
+ strcmp(output_directives[COLB], name) == 0
) {
directive->dtype = DT_OUTPUT;
directive->btype = BT_COLUMN;
@@ -2165,7 +2352,7 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
char custom_directive[64];
enum State state = STATE_LYRICS;
enum State prev_state = STATE_LYRICS;
- unsigned int line_number = 1;
+ size_t line_number = 1;
int dn = 0;
int dv = 0;
int ch = 0;
@@ -2205,6 +2392,7 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
struct Style *tag_style;
struct StyleProperty sprop;
struct ChoChord *tmp_chord;
+ struct ChoImage *image;
while (feof(fp) == 0) {
read = fread(&buf, 1, 1, fp);
if (read == 1) {
@@ -2357,6 +2545,9 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
case DT_FORMATTING:
fprintf(stderr, "WARN: Formatting directive '%s' has no value.\n", directive_name);
break;
+ case DT_IMAGE:
+ fprintf(stderr, "ERR: Directive 'image' has no value.\n");
+ return NULL;
case DT_PREAMBLE:
// INFO: The only preamble directive is 'new_song'
cho_line_item_free(songs[so]->sections[se]->lines[li]->lyrics[ly]);
@@ -2544,10 +2735,17 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
songs[so]->sections[se]->lines[li]->lyrics[ly]->text = trimmed_directive_value;
te += strlen(trimmed_directive_value);
break;
+ case DT_IMAGE:
+ image = cho_image_directive_parse(directive_value, line_number);
+ if (!image) {
+ fprintf(stderr, "cho_image_directive_parse failed.\n");
+ return NULL;
+ }
+ cho_image_free(image);
+ break;
case DT_PREAMBLE:
fprintf(stderr, "ERR: Preamble directive '%s' can't have a value.\n", directive_name);
return NULL;
- break;
case DT_FONT:
sprop.ftype = directive->ftype;
char *dir_value = str_remove_leading_whitespace(directive_value);
@@ -2631,7 +2829,7 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
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) {
- fprintf(stderr, "INFO: Didn't recognize the chord '%s' in line %d.\n", songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->name, line_number);
+ fprintf(stderr, "INFO: Didn't recognize the chord '%s' in line %ld.\n", songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->name, line_number);
}
cho_chord_free(tmp_chord);
is_chord_already_initialized = false;
@@ -2644,7 +2842,7 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
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) {
- fprintf(stderr, "INFO: Didn't recognize the chord '%s' in line %d.\n", songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->name, line_number);
+ fprintf(stderr, "INFO: Didn't recognize the chord '%s' in line %ld.\n", songs[so]->sections[se]->lines[li]->text_above[c]->u.chord->name, line_number);
}
// cho_debug_chord_print(songs[so]->sections[se]->lines[li]->text_above[c]->u.chord);
}
@@ -2737,7 +2935,7 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
songs[so]->sections[se]->lines[li]->text_above[c]->u.annot->style = cho_style_duplicate(tag_style);
break;
default:
- fprintf(stderr, "ERR: Invalid prev_state '%s'.\n", cho_state_to_string(prev_state));
+ fprintf(stderr, "ERR: Invalid prev_state '%s'.\n", state_enums[prev_state]);
return NULL;
}
memset(tag_begin, 0, strlen(tag_begin));
@@ -2807,7 +3005,7 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
} else {
tags[ta]->attrs[at]->name = realloc(tags[ta]->attrs[at]->name, (atn+1) * sizeof(char));
tags[ta]->attrs[at]->name[atn] = 0;
- fprintf(stderr, "ERR: Attribute with name '%s' of tag '%s' in line '%d' has no value.\n", tags[ta]->attrs[at]->name, tag_begin, line_number);
+ fprintf(stderr, "ERR: Attribute with name '%s' of tag '%s' in line '%ld' has no value.\n", tags[ta]->attrs[at]->name, tag_begin, line_number);
return NULL;
}
}
@@ -2819,7 +3017,7 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
}
tags[ta]->attrs[at]->name = realloc(tags[ta]->attrs[at]->name, (atn+1) * sizeof(char));
tags[ta]->attrs[at]->name[atn] = 0;
- fprintf(stderr, "ERR: Attribute with name '%s' of tag '%s' in line '%d' has no value.\n", tags[ta]->attrs[at]->name, tag_begin, line_number);
+ fprintf(stderr, "ERR: Attribute with name '%s' of tag '%s' in line '%ld' has no value.\n", tags[ta]->attrs[at]->name, tag_begin, line_number);
return NULL;
}
if (buf == '>') {
@@ -2846,7 +3044,7 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
songs[so]->sections[se]->lines[li]->text_above[c]->u.annot->style = cho_style_duplicate(tag_style);
break;
default:
- fprintf(stderr, "ERR: Invalid prev_state '%s'.\n", cho_state_to_string(prev_state));
+ fprintf(stderr, "ERR: Invalid prev_state '%s'.\n", state_enums[prev_state]);
return NULL;
}
at = 0;
@@ -2857,7 +3055,7 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
tags[ta]->attrs[at]->name = realloc(tags[ta]->attrs[at]->name, (atn+1) * sizeof(char));
tags[ta]->attrs[at]->name[atn] = 0;
atn = 0;
- fprintf(stderr, "ERR: Attribute with name '%s' of tag '%s' in line '%d' has no value.\n", tags[ta]->attrs[at]->name, tag_begin, line_number);
+ fprintf(stderr, "ERR: Attribute with name '%s' of tag '%s' in line '%ld' has no value.\n", tags[ta]->attrs[at]->name, tag_begin, line_number);
return NULL;
}
}
@@ -2868,11 +3066,11 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
case STATE_MARKUP_ATTR_VALUE:
if (avs == AVS_NO) {
if (is_whitespace(buf)) {
- fprintf(stderr, "ERR: Whitespace character after equals sign in line '%d' is invalid.\n", line_number);
+ fprintf(stderr, "ERR: Whitespace character after equals sign in line '%ld' is invalid.\n", line_number);
return NULL;
}
if (buf == '>') {
- fprintf(stderr, "ERR: Attribute with name '%s' of tag '%s' in line '%d' has no value.\n", tags[ta]->attrs[at]->name, tag_begin, line_number);
+ fprintf(stderr, "ERR: Attribute with name '%s' of tag '%s' in line '%ld' has no value.\n", tags[ta]->attrs[at]->name, tag_begin, line_number);
return NULL;
}
if (buf == '\'') {
@@ -2888,7 +3086,7 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
break;
}
if (buf == '\n') {
- fprintf(stderr, "ERR: Newline character inside an attribute value in line '%d' is invalid.\n", line_number);
+ fprintf(stderr, "ERR: Newline character inside an attribute value in line '%ld' is invalid.\n", line_number);
return NULL;
}
if (avs == AVS_UNQUOTED && buf == '>') {
@@ -2918,7 +3116,7 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
songs[so]->sections[se]->lines[li]->text_above[c]->u.annot->style = cho_style_duplicate(tag_style);
break;
default:
- fprintf(stderr, "ERR: Invalid prev_state '%s'.\n", cho_state_to_string(prev_state));
+ fprintf(stderr, "ERR: Invalid prev_state '%s'.\n", state_enums[prev_state]);
return NULL;
}
at = 0;
@@ -2958,8 +3156,9 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
fprintf(stderr, "fread failed.\n");
return NULL;
}
- if (buf == '\n')
+ if (buf == '\n') {
line_number++;
+ }
}
int e = 0;
while (e <= ta) {
@@ -3017,167 +3216,3 @@ struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config)
}
return songs;
}
-
-#ifdef DEBUG
-
-static const char *cho_debug_the_dtype(enum DirectiveType dtype)
-{
- switch (dtype) {
- case DT_EMPTY:
- return "DT_EMPTY";
- 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_FONT:
- return "DT_FONT";
- case DT_CHORD:
- return "DT_CHORD";
- case DT_OUTPUT:
- return "DT_OUTPUT";
- case DT_CUSTOM:
- return "DT_CUSTOM";
- }
- return "";
-}
-
-static const char *cho_debug_the_stype(enum SectionType stype)
-{
- switch (stype) {
- case ST_EMPTY:
- return "ST_EMPTY";
- 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";
- case ST_CUSTOM:
- return "ST_CUSTOM";
- }
- return "";
-}
-
-static const char *cho_debug_the_pos(enum Position pos)
-{
- switch (pos) {
- case POS_EMPTY:
- return "POS_EMPTY";
- case POS_START:
- return "POS_START";
- case POS_END:
- return "POS_END";
- }
- return "";
-}
-
-static const char *cho_debug_the_song_fragment_type(enum SongFragmentType ftype)
-{
- switch (ftype) {
- case SF_EMPTY:
- return "SF_EMPTY";
- case SF_CHORD:
- return "SF_CHORD";
- case SF_ANNOT:
- return "SF_ANNOT";
- case SF_CHORUS:
- return "SF_CHORUS";
- case SF_FOOTER:
- return "SF_FOOTER";
- case SF_GRID:
- return "SF_GRID";
- case SF_TAB:
- return "SF_TAB";
- case SF_TOC:
- return "SF_TOC";
- case SF_TEXT:
- return "SF_TEXT";
- case SF_TITLE:
- return "SF_TITLE";
- case SF_SUBTITLE:
- return "SF_SUBTITLE";
- case SF_LABEL:
- return "SF_LABEL";
- }
- return "";
-}
-
-static const char *cho_debug_style_property_type_to_string(enum StylePropertyType type)
-{
- switch (type) {
- case SPT_EMPTY:
- return "SPT_EMPTY";
- case SPT_FONT:
- return "SPT_FONT";
- case SPT_SIZE:
- return "SPT_SIZE";
- case SPT_COLOR:
- return "SPT_COLOR";
- }
- return "";
-}
-
-static void cho_debug_the_default_style_properties(void)
-{
- unsigned int i;
- for (i = 0; i<LENGTH(default_style_properties); i++) {
- printf(
- "%s %s ",
- cho_debug_the_song_fragment_type(default_style_properties[i].ftype),
- cho_debug_style_property_type_to_string(default_style_properties[i].type)
- );
- switch (default_style_properties[i].type) {
- case SPT_FONT:
- if (default_style_properties[i].u.font_name)
- printf("%s\n", default_style_properties[i].u.font_name);
- else
- printf("NULL\n");
- break;
- case SPT_SIZE:
- printf("%.1f\n", default_style_properties[i].u.font_size);
- break;
- case SPT_COLOR:
- if (default_style_properties[i].u.foreground_color)
- printf("%s\n", cho_rgbcolor_to_string(default_style_properties[i].u.foreground_color));
- else
- printf("NULL\n");
- break;
- default:
- printf("Invalid StylePropertyType value '%d'.\n", default_style_properties[i].type);
- }
- }
-}
-
-void cho_debug_style_print(struct Style *style)
-{
- printf("---- BEGIN STYLE ----\n");
- cho_font_print(style->font);
- printf("foreground_color: %s\n", cho_rgbcolor_to_string(style->foreground_color));
- printf("background_color: %s\n", cho_rgbcolor_to_string(style->background_color));
- printf("underline_style: %s\n", cho_linestyle_to_config_string(style->underline_style));
- printf("underline_color: %s\n", cho_rgbcolor_to_string(style->underline_color));
- printf("overline_style: %s\n", cho_linestyle_to_config_string(style->overline_style));
- printf("overline_color: %s\n", cho_rgbcolor_to_string(style->overline_color));
- printf("strikethrough: %d\n", style->strikethrough);
- printf("strikethrough_color: %s\n", cho_rgbcolor_to_string(style->strikethrough_color));
- printf("boxed: %d\n", style->boxed);
- printf("boxed_color: %s\n", cho_rgbcolor_to_string(style->boxed_color));
- printf("rise: %f\n", style->rise);
- if (style->href)
- printf("href: %s\n", style->href);
- else
- printf("href: NULL\n");
- printf("---- END STYLE ------\n\n");
-}
-
-#endif /* DEBUG */
diff --git a/chordpro.h b/chordpro.h
@@ -12,25 +12,74 @@
#define URL_MAX_LEN 2000
#define FONT_NAME_MAX 100
+enum EnvironmentDirective {
+ 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
+
+};
+
+/* enum MetadataDirective {
+ TITLE, SORTTITLE, SUBTITLE,
+ ARTIST, COMPOSER, LYRICIST,
+ COPYRIGHT, ALBUM, YEAR, KEY,
+ TIME, TEMPO, DURATION, CAPO,
+ META, ARRANGER
+}; */
+
+enum FormattingDirective {
+ COMMENT, C, HIGHLIGHT, COMMENT_ITALIC, CI,
+ COMMENT_BOX, CB
+};
+
+enum ImageDirectve {
+ IMAGE
+};
+
+/* enum PreabmleDirective {
+ NEW_SONG, NS
+}; */
+
+enum FontDirective {
+ CHORDFONT, CF, CHORDSIZE, CS, CHORDCOLOR,
+ CHORUSFONT, CHORUSSIZE, CHORUSCOLOR,
+ GRIDFONT, GRIDSIZE, GRIDCOLOR,
+ TABFONT, TABSIZE, TABCOLOR,
+ TEXTFONT, TF, TEXTSIZE, TS, TEXTCOLOR,
+ TITLEFONT, TITLESIZE, TITLECOLOR,
+ /* FOOTERFONT, FOOTERSIZE, FOOTERCOLOR,
+ TOCFONT, TOCSIZE, TOCCOLOR */
+};
+
+enum ChordDirective {
+ TRANSPOSE, /* DEFINE, CHORD */
+};
+
+enum OutputDirective {
+ NEW_PAGE, NP, COLUMN_BREAK, COLB
+};
+
enum FontFamily {
- FF_EMPTY = -1,
FF_NORMAL,
FF_SANS,
FF_SERIF,
- FF_MONOSPACE
+ FF_MONOSPACE,
+ FF_EMPTY,
};
enum FontStyle {
- FS_EMPTY = -1,
FS_ROMAN,
FS_OBLIQUE,
- FS_ITALIC
+ FS_ITALIC,
+ FS_EMPTY
};
enum FontWeight {
- FW_EMPTY = -1,
FW_REGULAR,
- FW_BOLD
+ FW_BOLD,
+ FW_EMPTY
};
struct Font {
@@ -42,10 +91,10 @@ struct Font {
};
enum LineStyle {
- LS_EMPTY = -1,
LS_SINGLE,
LS_DOUBLE,
- LS_NONE
+ LS_NONE,
+ LS_EMPTY
};
struct RGBColor {
@@ -82,6 +131,39 @@ struct Tag {
bool is_closed;
};
+enum Alignment {
+ A_LEFT,
+ A_CENTER,
+ A_RIGHT
+};
+
+enum Anchor {
+ AN_PAPER,
+ AN_PAGE,
+ AN_COLUMN,
+ AN_LINE,
+ AN_FLOAT
+};
+
+struct ChoImage {
+ char *id;
+ char *src;
+ double width;
+ double height;
+ double scale;
+ enum Alignment align;
+ double border;
+ double spread_space;
+ char *href;
+ double x;
+ double y;
+ enum Anchor anchor;
+ double dx;
+ double dy;
+ double w;
+ double h;
+};
+
enum AttrValueSyntax {
AVS_NO,
AVS_QUOTATION_MARK,
@@ -103,9 +185,8 @@ enum State {
STATE_COMMENT
};
-/* Similar to SectionType but different enough for a separate type */
enum SongFragmentType {
- SF_EMPTY = -1,
+ SF_EMPTY,
SF_CHORD,
SF_ANNOT,
SF_CHORUS,
@@ -120,7 +201,7 @@ enum SongFragmentType {
};
enum StylePropertyType {
- SPT_EMPTY = -1,
+ SPT_EMPTY,
SPT_FONT,
SPT_SIZE,
SPT_COLOR
@@ -139,10 +220,11 @@ struct StyleProperty {
};
enum DirectiveType {
- DT_EMPTY = -1,
+ DT_EMPTY,
DT_ENVIRONMENT,
DT_METADATA,
DT_FORMATTING,
+ DT_IMAGE,
DT_PREAMBLE,
DT_FONT,
DT_CHORD,
@@ -151,7 +233,7 @@ enum DirectiveType {
};
enum SectionType {
- ST_EMPTY = -1,
+ ST_EMPTY,
ST_NEWSONG,
ST_CHORUS,
ST_VERSE,
@@ -162,13 +244,13 @@ enum SectionType {
};
enum Position {
- POS_EMPTY = -1,
+ POS_EMPTY,
POS_START,
POS_END
};
enum ChordQualifier {
- CQ_EMPTY = -1,
+ CQ_EMPTY,
CQ_MIN,
CQ_MAJ,
CQ_AUG,
@@ -176,10 +258,10 @@ enum ChordQualifier {
};
enum BreakType {
- BT_EMPTY = -1,
BT_LINE,
BT_PAGE,
- BT_COLUMN
+ BT_COLUMN,
+ BT_EMPTY
};
struct ChoDirective {
@@ -282,8 +364,6 @@ enum FontWeight cho_font_weight_parse(const char *str);
const char *cho_font_weight_to_config_string(enum FontWeight weight);
void cho_font_print_as_toml(struct Font *font, const char *section);
-#ifdef DEBUG
void cho_debug_style_print(struct Style *style);
-#endif /* DEBUG */
#endif /* _CHORDPRO_H_ */
diff --git a/config.c b/config.c
@@ -5,6 +5,21 @@
#include "chordpro.h"
#include "config.h"
+static char *naming_systems[] = {
+ "common",
+ "german",
+ "scandinavian",
+ "latin",
+ "roman",
+ "nashville",
+ "custom" // TODO: Is this needed
+};
+
+static char *parse_modes[] = {
+ "strict",
+ "relaxed"
+};
+
static const char *g_valid_styles[] = {
"title",
"subtitle",
@@ -116,17 +131,17 @@ struct PrintableItem *config_printable_item_get(struct PrintableItem **items, co
static enum NamingSystem config_naming_system_parse(const char *str)
{
- if (strcmp(str, "common") == 0 || strcmp(str, "dutch") == 0) {
+ if (strcmp(str, naming_systems[NS_COMMON]) == 0 || strcmp(str, "dutch") == 0) {
return NS_COMMON;
- } else if (strcmp(str, "german") == 0) {
+ } else if (strcmp(str, naming_systems[NS_GERMAN]) == 0) {
return NS_GERMAN;
- } else if (strcmp(str, "scandinavian") == 0) {
+ } else if (strcmp(str, naming_systems[NS_SCANDINAVIAN]) == 0) {
return NS_SCANDINAVIAN;
- } else if (strcmp(str, "latin") == 0) {
+ } else if (strcmp(str, naming_systems[NS_LATIN]) == 0) {
return NS_LATIN;
- } else if (strcmp(str, "roman") == 0) {
+ } else if (strcmp(str, naming_systems[NS_ROMAN]) == 0) {
return NS_ROMAN;
- } else if (strcmp(str, "nashville") == 0) {
+ } else if (strcmp(str, naming_systems[NS_NASHVILLE]) == 0) {
return NS_NASHVILLE;
} else {
return NS_CUSTOM;
@@ -135,20 +150,7 @@ static enum NamingSystem config_naming_system_parse(const char *str)
static const char *config_naming_system_to_config_string(enum NamingSystem system)
{
- switch (system) {
- case NS_GERMAN:
- return "german";
- case NS_SCANDINAVIAN:
- return "scandinavian";
- case NS_LATIN:
- return "latin";
- case NS_ROMAN:
- return "roman";
- case NS_NASHVILLE:
- return "nashville";
- default:
- return "common";
- }
+ return naming_systems[system];
}
static struct Note *config_note_new(void)
@@ -288,10 +290,7 @@ static void config_notes_print_as_toml(enum NamingSystem system, struct Note **n
static const char *config_parse_mode_to_config_string(enum ParseMode mode)
{
- if (mode == PM_RELAXED) {
- return "relaxed";
- }
- return "strict";
+ return parse_modes[mode];
}
static struct Config *config_load_default(void)
diff --git a/todo b/todo
@@ -7,7 +7,6 @@ metadata directives
conditional metadata directives
don't forget key, key_actual, key_from
chords
- transpose
define chords
chord diagrams
strict and relaxed parsing makes no difference!?
@@ -23,3 +22,4 @@ render in two or more columns
find better name for PrintableItem, TextAbove
consider freeing memory in case of errors
+add line number to error, warning and info fprintf's.