diff --git a/src/cli.cc b/src/cli.cc index 1d8cef8..84a66a0 100644 --- a/src/cli.cc +++ b/src/cli.cc @@ -2,6 +2,8 @@ #include +#include + static struct option getopt_options[] = { {"help", no_argument, 0, 'h'}, {"output", required_argument, 0, 'o'}, @@ -79,3 +81,38 @@ int ot::parse_options(int argc, char** argv, ot::options& opt) } return EXIT_SUCCESS; } + +/** + * \todo Use an std::istream or getline. Lift the 16 KiB limitation and whatever's hardcoded here. + */ +std::list ot::read_tags(FILE* file) +{ + std::list comments; + auto raw_tags = std::make_unique(16383); + size_t raw_len = fread(raw_tags.get(), 1, 16382, stdin); + if (raw_len == 16382) + fputs("warning: truncating comment to 16 KiB\n", stderr); + raw_tags[raw_len] = '\0'; + size_t field_len = 0; + bool caught_eq = false; + char* cursor = raw_tags.get(); + for (size_t i = 0; i <= raw_len; ++i) { + if (raw_tags[i] == '\n' || raw_tags[i] == '\0') { + raw_tags[i] = '\0'; + if (field_len == 0) + continue; + if (caught_eq) + comments.emplace_back(cursor); + else + fputs("warning: skipping malformed tag\n", stderr); + cursor = raw_tags.get() + i + 1; + field_len = 0; + caught_eq = false; + continue; + } + if (raw_tags[i] == '=') + caught_eq = true; + ++field_len; + } + return comments; +} diff --git a/src/opustags.cc b/src/opustags.cc index 2b06cf3..5e706be 100644 --- a/src/opustags.cc +++ b/src/opustags.cc @@ -187,47 +187,8 @@ int main(int argc, char **argv){ for (const std::string& name : opt.to_delete) ot::delete_tags(&tags, name.c_str()); } - char *raw_tags = NULL; - if (opt.set_all) { - raw_tags = static_cast(malloc(16384)); - if(raw_tags == NULL){ - error = "malloc: not enough memory for buffering stdin"; - free(raw_tags); - break; - } - else{ - char *raw_comment[256]; - size_t raw_len = fread(raw_tags, 1, 16383, stdin); - if(raw_len == 16383) - fputs("warning: truncating comment to 16 KiB\n", stderr); - raw_tags[raw_len] = '\0'; - uint32_t raw_count = 0; - size_t field_len = 0; - int caught_eq = 0; - size_t i = 0; - char *cursor = raw_tags; - for(i=0; i <= raw_len && raw_count < 256; i++){ - if(raw_tags[i] == '\n' || raw_tags[i] == '\0'){ - if(field_len == 0) - continue; - if(caught_eq) - raw_comment[raw_count++] = cursor; - else - fputs("warning: skipping malformed tag\n", stderr); - cursor = raw_tags + i + 1; - field_len = 0; - caught_eq = 0; - raw_tags[i] = '\0'; - continue; - } - if(raw_tags[i] == '=') - caught_eq = 1; - field_len++; - } - for (size_t i = 0; i < raw_count; ++i) - tags.comments.emplace_back(raw_comment[i]); - } - } + if (opt.set_all) + tags.comments = ot::read_tags(stdin); for (const std::string& comment : opt.to_add) tags.comments.emplace_back(comment); if(writer.file){ @@ -239,8 +200,6 @@ int main(int argc, char **argv){ } else print_tags(tags); - if(raw_tags) - free(raw_tags); if(error || !writer.file) break; else diff --git a/src/opustags.h b/src/opustags.h index 988d075..eef0342 100644 --- a/src/opustags.h +++ b/src/opustags.h @@ -204,6 +204,7 @@ struct options { }; int parse_options(int argc, char** argv, options& opt); +std::list read_tags(FILE* file); /** \} */