commit 9ec1d5d00ac60396aedb12f15213b61406c716ab
parent c209d8b19163cd56d98b14717618010c2d4ec246
Author: nibo <nibo@relim.de>
Date: Wed, 19 Feb 2025 16:25:55 +0100
Add standard metadata
Diffstat:
4 files changed, 85 insertions(+), 30 deletions(-)
diff --git a/src/chordpro.c b/src/chordpro.c
@@ -8,6 +8,7 @@
#include <ctype.h>
#include <errno.h>
#include <limits.h>
+#include <time.h>
#include "types.h"
#include "chordpro.h"
#include "util.h"
@@ -1569,9 +1570,7 @@ cho_tag_free(struct Tag *tag)
return;
}
free(tag->name);
- if (tag->style) {
- cho_style_free(tag->style);
- }
+ cho_style_free(tag->style);
if (tag->attrs) {
cho_tag_attrs_free(tag->attrs);
}
@@ -1627,9 +1626,7 @@ cho_metadata_free(struct ChoMetadata *meta)
}
free(meta->name);
free(meta->value);
- if (meta->style) {
- cho_style_free(meta->style);
- }
+ cho_style_free(meta->style);
free(meta);
}
@@ -1690,6 +1687,12 @@ cho_metadata_load_default(void)
{
struct ChoMetadata **meta = NULL;
char *filename;
+ char *logged_in_user = getenv("USER");
+ if (!logged_in_user) {
+ LOG_DEBUG("getenv(USER) failed.");
+ return NULL;
+ }
+ struct InstrumentInfo ins_info = config_instrument_get(g_config->output->diagram->instrument);
int i = 0;
meta = erealloc(meta, (i+1) * sizeof(struct ChoMetadata *));
meta[i] = emalloc(sizeof(struct ChoMetadata));
@@ -1703,27 +1706,69 @@ cho_metadata_load_default(void)
meta[i] = emalloc(sizeof(struct ChoMetadata));
meta[i]->name = strdup("chordpro.songsource");
meta[i]->value = filename;
+ meta[i]->style = cho_style_new_default();
i++;
}
meta = erealloc(meta, (i+1) * sizeof(struct ChoMetadata *));
meta[i] = emalloc(sizeof(struct ChoMetadata));
meta[i]->name = strdup("chordpro.version");
meta[i]->value = strdup("6");
+ meta[i]->style = cho_style_new_default();
i++;
meta = erealloc(meta, (i+1) * sizeof(struct ChoMetadata *));
meta[i] = emalloc(sizeof(struct ChoMetadata));
meta[i]->name = strdup("instrument");
- meta[i]->value = strdup(config_instrument_to_config_string(g_config->output->diagram->instrument));
+ meta[i]->value = strdup(ins_info.name);
+ meta[i]->style = cho_style_new_default();
i++;
meta = erealloc(meta, (i+1) * sizeof(struct ChoMetadata *));
meta[i] = emalloc(sizeof(struct ChoMetadata));
meta[i]->name = strdup("instrument.type");
- meta[i]->value = strdup(config_instrument_to_config_string(g_config->output->diagram->instrument));
+ meta[i]->value = strdup(ins_info.name);
+ meta[i]->style = cho_style_new_default();
i++;
meta = erealloc(meta, (i+1) * sizeof(struct ChoMetadata *));
meta[i] = emalloc(sizeof(struct ChoMetadata));
meta[i]->name = strdup("instrument.description");
- meta[i]->value = strdup(config_instrument_description(g_config->output->diagram->instrument));
+ meta[i]->value = strdup(ins_info.description);
+ meta[i]->style = cho_style_new_default();
+ i++;
+ const time_t t = time(NULL);
+ struct tm *tt = localtime(&t);
+ char time_str[64];
+ if (strftime((char *)&time_str, 64, "%a, %d. %b %H:%M", tt) == 0) {
+ LOG_DEBUG("strftime failed.");
+ return NULL;
+ }
+ meta = erealloc(meta, (i+1) * sizeof(struct ChoMetadata *));
+ meta[i] = emalloc(sizeof(struct ChoMetadata));
+ meta[i]->name = strdup("today");
+ meta[i]->value = strdup(time_str);
+ meta[i]->style = cho_style_new_default();
+ i++;
+ meta = erealloc(meta, (i+1) * sizeof(struct ChoMetadata *));
+ meta[i] = emalloc(sizeof(struct ChoMetadata));
+ meta[i]->name = strdup("tuning");
+ meta[i]->value = strdup(ins_info.tuning);
+ meta[i]->style = cho_style_new_default();
+ i++;
+ meta = erealloc(meta, (i+1) * sizeof(struct ChoMetadata *));
+ meta[i] = emalloc(sizeof(struct ChoMetadata));
+ meta[i]->name = strdup("user");
+ meta[i]->value = strdup(logged_in_user);
+ meta[i]->style = cho_style_new_default();
+ i++;
+ meta = erealloc(meta, (i+1) * sizeof(struct ChoMetadata *));
+ meta[i] = emalloc(sizeof(struct ChoMetadata));
+ meta[i]->name = strdup("user.name");
+ meta[i]->value = strdup(logged_in_user);
+ meta[i]->style = cho_style_new_default();
+ i++;
+ meta = erealloc(meta, (i+1) * sizeof(struct ChoMetadata *));
+ meta[i] = emalloc(sizeof(struct ChoMetadata));
+ meta[i]->name = strdup("user.fullname");
+ meta[i]->value = strdup(logged_in_user);
+ meta[i]->style = cho_style_new_default();
i++;
return meta;
}
@@ -3407,6 +3452,10 @@ cho_song_new(void)
{
struct ChoSong *song = emalloc(sizeof(struct ChoSong));
song->metadata = cho_metadata_load_default();
+ if (!song->metadata) {
+ LOG_DEBUG("cho_metadata_load_default failed.");
+ return NULL;
+ }
song->sections = NULL;
song->diagrams = NULL;
memset(song->present_text_types, 0, TT_LENGTH);
@@ -4005,7 +4054,7 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
int ch = 0;
int c = 0;
// Not zero by default because there are default metadata entries
- int m = 1;
+ int m = 11;
int ly = 0;
int t = 0;
int so = 0;
@@ -4034,6 +4083,10 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
struct ChoLine ***lines;
struct ChoSong **songs = emalloc(sizeof(struct ChoSong *));
songs[so] = cho_song_new();
+ if (!songs[so]) {
+ LOG_DEBUG("cho_song_new failed.");
+ return NULL;
+ }
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 *));
@@ -4341,10 +4394,14 @@ cho_songs_parse(FILE *fp, const char *chordpro_filepath, struct Config *config)
so++;
songs = erealloc(songs, (so+1) * sizeof(struct ChoSong *));
songs[so] = cho_song_new();
+ if (!songs[so]) {
+ LOG_DEBUG("cho_song_new failed.");
+ return NULL;
+ }
se = 0;
li = 0;
ly = 0;
- m = 0;
+ m = 11;
dia = 0;
songs[so]->sections = emalloc((se+1) * sizeof(struct ChoSection *));
songs[so]->sections[se] = cho_section_new();
diff --git a/src/config.c b/src/config.c
@@ -23,18 +23,11 @@ static const char *parse_modes[] = {
"relaxed"
};
-static const char *instruments[] = {
- "guitar",
- "keyboard",
- "mandolin",
- "ukulele"
-};
-
-static const char *instrument_descriptions[] = {
- "Guitar, 6 strings, standard tuning",
- "Piano",
- "Mandolin, 4 strings, standard tuning",
- "Ukulele, 4 strings, standard tuning"
+static const struct InstrumentInfo instruments[] = {
+ { .name = "guitar", .description = "Guitar, 6 strings, standard tuning", .tuning = "E2 A2 D3 G3 B3 E4" },
+ { .name = "keyboard", .description = "Piano", .tuning = "" },
+ { .name = "mandolin", .description = "Mandolin, 4 strings, standard tuning", .tuning = "G D A E" },
+ { .name = "ukulele", .description = "Ukulele, 4 strings, standard tuning", .tuning = "G C E A" }
};
static const char *text_types[] = {
@@ -225,16 +218,16 @@ config_instrument_parse(const char *str)
return -1;
}
-const char *
+static const char *
config_instrument_to_config_string(enum Instrument ins)
{
- return instruments[ins];
+ return instruments[ins].name;
}
-const char *
-config_instrument_description(enum Instrument ins)
+struct InstrumentInfo
+config_instrument_get(enum Instrument ins)
{
- return instrument_descriptions[ins];
+ return instruments[ins];
}
static struct Note *
diff --git a/src/config.h b/src/config.h
@@ -13,7 +13,6 @@ struct Config *config_load(const char *filepath);
void config_free(struct Config *config);
void config_print_default(void);
-const char *config_instrument_to_config_string(enum Instrument ins);
-const char *config_instrument_description(enum Instrument ins);
+struct InstrumentInfo config_instrument_get(enum Instrument ins);
#endif /* _CONFIG_H_ */
diff --git a/src/types.h b/src/types.h
@@ -283,6 +283,12 @@ enum Instrument : int8_t {
INS_UKULELE
};
+struct InstrumentInfo {
+ char *name;
+ char *description;
+ char *tuning;
+};
+
struct Note {
char *note;
char *sharp;