lorid

convert chordpro to pdf
git clone git://git.relim.de/lorid.git
Log | Files | Refs | README | LICENSE

commit 9e08b6cb16c8a7d76cdacae1bab328df2cd0e091
parent e50e80b8700cdb60c19e1b349f531acb6a9b4015
Author: nibo <nibo@relim.de>
Date:   Mon, 14 Oct 2024 13:49:20 +0200

Finish cho_image_option_parse()

Diffstat:
Mchordpro.c | 112++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Mchordpro.h | 12++++++------
Mutil.c | 27+++++++++++++++++++++++++++
Mutil.h | 9+++++++++
4 files changed, 136 insertions(+), 24 deletions(-)

diff --git a/chordpro.c b/chordpro.c @@ -1982,15 +1982,15 @@ 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->width = NULL; + image->height = NULL; + image->scale = NULL; image->align = A_CENTER; image->border = EMPTY; - image->spread_space = EMPTY; + image->spread_space = NULL; image->href = NULL; - image->x = EMPTY; - image->y = EMPTY; + image->x = NULL; + image->y = NULL; image->anchor = AN_FLOAT; image->dx = EMPTY; image->dy = EMPTY; @@ -2003,13 +2003,32 @@ static void cho_image_free(struct ChoImage *image) { free(image->id); free(image->src); + if (image->width) { + free(image->width); + } + if (image->height) { + free(image->height); + } + if (image->scale) { + free(image->scale); + } + if (image->spread_space) { + free(image->spread_space); + } + if (image->x) { + free(image->x); + } + if (image->y) { + free(image->y); + } free(image->href); free(image); } -static bool cho_image_option_check(struct ChoImage *image, const char *name, const char *value) +static bool cho_image_option_parse(struct ChoImage *image, const char *name, const char *value) { - size_t value_len = strlen(value); + char *endptr; + // size_t value_len = strlen(value); if (!strcmp(name, "id")) { image->id = strdup(value); } else @@ -2017,33 +2036,90 @@ static bool cho_image_option_check(struct ChoImage *image, const char *name, con image->src = strdup(value); } else if (!strcmp(name, "width")) { - if (value[value_len-1] == '%') { - short p = str_parse_as_percent(value); - if (p == -1) { - LOG_DEBUG("str_parse_as_percent failed."); - cho_log(LOG_ERR, "Invalid percentage."); - return false; - } - printf("p: %d\n", p); + image->width = double_or_percent_create(value); + if (!image->width) { + cho_log(LOG_ERR, "Invalid value in option 'width' in image directive."); + return false; } } else if (!strcmp(name, "height")) { + image->height = double_or_percent_create(value); + if (!image->height) { + cho_log(LOG_ERR, "Invalid value in option 'height' in image directive."); + return false; + } } else if (!strcmp(name, "scale")) { + image->scale = double_or_percent_create(value); + if (!image->scale) { + cho_log(LOG_ERR, "Invalid value in option 'scale' in image directive."); + return false; + } } else if (!strcmp(name, "align")) { + if (!strcmp(value, "left")) { + image->align = A_LEFT; + } else + if (!strcmp(value, "right")) { + image->align = A_RIGHT; + } else + if (!strcmp(value, "center")) { + image->align = A_CENTER; + } else { + cho_log(LOG_ERR, "Invalid value in option 'align' in image directive."); + return false; + } } else if (!strcmp(name, "border")) { + image->border = strtod(value, &endptr); + if (value == endptr || errno == ERANGE) { + LOG_DEBUG("strtod failed."); + return false; + } } else if (!strcmp(name, "spread")) { + image->spread_space = double_or_percent_create(value); + if (!image->spread_space) { + cho_log(LOG_ERR, "Invalid value in option 'spread' in image directive."); + return false; + } } else if (!strcmp(name, "href")) { + image->href = strdup(value); } else if (!strcmp(name, "x")) { + image->x = double_or_percent_create(value); + if (!image->x) { + cho_log(LOG_ERR, "Invalid value in option 'x' in image directive."); + return false; + } } else if (!strcmp(name, "y")) { + image->y = double_or_percent_create(value); + if (!image->y) { + cho_log(LOG_ERR, "Invalid value in option 'y' in image directive."); + return false; + } } else if (!strcmp(name, "anchor")) { + if (!strcmp(value, "paper")) { + image->anchor = AN_PAPER; + } else + if (!strcmp(value, "page")) { + image->anchor = AN_PAGE; + } else + if (!strcmp(value, "column")) { + image->anchor = AN_COLUMN; + } else + if (!strcmp(value, "line")) { + image->anchor = AN_LINE; + } else + if (!strcmp(value, "float")) { + image->anchor = AN_FLOAT; + } else { + cho_log(LOG_ERR, "Invalid value in option 'anchor' in image directive."); + return false; + } } return true; } @@ -2116,7 +2192,7 @@ static struct ChoImage *cho_image_directive_parse(const char *str) ) { value[v] = 0; printf("'%s' -> '%s'\n", name, value); - if (!cho_image_option_check(image, name, value)) { + if (!cho_image_option_parse(image, name, value)) { LOG_DEBUG("cho_image_option_check failed."); return NULL; } @@ -2136,7 +2212,7 @@ static struct ChoImage *cho_image_directive_parse(const char *str) if (avs == AVS_UNQUOTED) { value[v] = 0; printf("'%s' -> '%s'\n", name, value); - if (!cho_image_option_check(image, name, value)) { + if (!cho_image_option_parse(image, name, value)) { LOG_DEBUG("cho_image_option_check failed."); return NULL; } diff --git a/chordpro.h b/chordpro.h @@ -141,15 +141,15 @@ enum OptionState { struct ChoImage { char *id; char *src; - double width; - double height; - double scale; + struct DoubleOrPercent *width; + struct DoubleOrPercent *height; + struct DoubleOrPercent *scale; enum Alignment align; double border; - double spread_space; + struct DoubleOrPercent *spread_space; char *href; - double x; - double y; + struct DoubleOrPercent *x; + struct DoubleOrPercent *y; enum Anchor anchor; double dx; double dy; diff --git a/util.c b/util.c @@ -264,3 +264,30 @@ char *filepath_dirname(const char *path) dirname[i] = 0; return dirname; } + +struct DoubleOrPercent * +double_or_percent_create(const char *str) +{ + struct DoubleOrPercent *dop = malloc(sizeof(struct DoubleOrPercent)); + size_t len = strlen(str); + if (str[len-1] == '%') { + short p = str_parse_as_percent(str); + if (p == -1) { + LOG_DEBUG("str_parse_as_percent failed."); + return NULL; + } + dop->u.p = p; + dop->is_percent = true; + } else { + char *endptr; + double d; + d = strtod(str, &endptr); + if (str == endptr || errno == ERANGE) { + LOG_DEBUG("strtod failed."); + return NULL; + } + dop->u.d = d; + dop->is_percent = false; + } + return dop; +} diff --git a/util.h b/util.h @@ -17,6 +17,14 @@ enum FileType { F_OTHER }; +struct DoubleOrPercent { + bool is_percent; + union { + double d; + short p; + } u; +}; + void util_log(enum LogLevel level, const char *msg, ...); bool str_starts_with(const char *str, const char *part); @@ -32,3 +40,4 @@ char *filepath_add_ending_slash_if_missing(const char *path); char *filepath_basename(const char *path); char *filepath_dirname(const char *path); +struct DoubleOrPercent *double_or_percent_create(const char *str);