Add missing C: (composer), R: (rhythm) and X: fields and return error (#21)

* Add configuration for CMake build system alongside autoconf

- Add a modern CMake build system (`CMakeLists.txt`, `CMakePresets.json`) that coexists with the legacy
autoconf/Makefile build
- Shared source files (`midifile.c`, `parseabc.c`, `music_utils.c`, `parser2.c`) are compiled once via OBJECT
libraries and linked into the 8 binaries
- Three presets: `default` (Release), `debug`, `sanitize` (ASan + UBSan)
- Generates `compile_commands.json` for clangd/LSP editor support
- Install rules match the legacy Makefile (binaries, doc files, man pages)
- Pinned to `-std=gnu89` because the codebase mixes K&R `()` and ANSI typed prototypes — in C23/gnu23 (GCC 15+
default), `()` means `(void)`, making these a hard error. Note: **the existing autoconf build is also broken with
GCC 15** for the same reason

```sh
cmake --preset debug
cmake --build --preset debug
cmake --install build/debug --prefix /usr/local

Documentation

- README.md: added Building section with both autoconf and CMake instructions
- doc/readme.txt: added build instructions in the existing preamble
- doc/CHANGES: added changelog entry

Test plan

- All 3 presets configure and build with GCC 15
- Smoke test: abc2midi samples/coleraine.abc produces valid MIDI through mftext
- Sanitizer build (--preset sanitize) runs clean on sample files
- Install layout verified: 8 binaries, 10 doc files, 8 man pages in correct paths
- Build on macOS (untested, should work with AppleClang)

* Implement basic testing infrastructure

The CMake build includes a test suite covering all 8 programs:

- **Smoke tests** verify each binary runs cleanly with `-ver`.
- **Golden-file tests** run each program on a sample input and compare the
  (normalized) output to a checked-in reference. Binary MIDI outputs are
  piped through `mftext` to produce diffable text. Volatile lines (version
  banners, dates, temporary paths) are stripped before comparison.

```sh
ctest --preset debug

ctest --preset debug -L golden
ctest --preset debug -L smoke
```

To regenerate the golden files after an intentional behavioural change,
review the diff, then commit:

```sh
cmake --build build/debug --target update-golden
git diff tests/golden/
```

* Factorize more the test CMake code

* Add GitHub Action to run the CI and output a status badge

* Add GitHub Action workflow dispatch to allow running from the UI

* Now abc2midi exits 1 if an error occurs

Before it was always returning 0, hiding failures complicated to track in
complex build systems.

* Output missing C:, R: and X: headers as MIDI text meta-events

* Update changelog and comments

---------

Co-authored-by: Seymour Shlien <fy733@ncf.ca>
This commit is contained in:
Ronan Keryell
2026-04-22 04:58:22 -07:00
committed by GitHub
parent c94cbbc062
commit ce70bc4d4e
5 changed files with 121 additions and 2 deletions

18
store.c
View File

@@ -296,6 +296,7 @@ int retuning = 0; /* [SS] 2012-04-01 */
int bend = 8192; /* [SS] 2012-04-01 */
int comma53 = 0; /* [SS] 2014-01-12 */
int silent = 0; /* [SS] 2014-10-16 */
int error_count = 0; /* number of errors reported by event_error() [RK] 2026-03-30 */
int no_more_free_channels; /* [SS] 2015-03-23 */
void init_p48toc53 (); /* [SS] 2014-01-12 */
void convert_to_comma53 (char acc, int *midipitch, int* midibend);
@@ -1536,6 +1537,7 @@ void event_fatal_error(char *s)
void event_error(char *s)
/* generic error handler */
{
error_count++; /* [RK] 2026-03-30 */
#ifdef NOFTELL
extern int nullpass;
@@ -2683,7 +2685,8 @@ void event_field(char k, char *f)
break;
case 'R':
{
char* p;
char* p;
char buff[258];
p = f;
/* strncpy(rhythmdesignator,f,32); [SS] 2011-08-19 */
snprintf(rhythmdesignator,sizeof(rhythmdesignator),"%s",f); /* [SEG] 2020-06-04 */
@@ -2695,6 +2698,11 @@ void event_field(char k, char *f)
ratio_a = 2; /* [SS] 2016-01-02 */
ratio_b = 4;
};
/* Also store as text feature for MIDI output [RK] 2026-03-31 */
if (strlen(f) < 256) {
sprintf(buff, "R:%s", f);
textfeature(TEXT, buff);
}
};
break;
default:
@@ -6230,6 +6238,12 @@ void event_refno(int n)
/* sprintf(outname, "%s%d.mid", outbase, n); */
};
startfile();
/* Store reference number as text feature for MIDI output [RK] 2026-03-31 */
{
char xbuf[40];
sprintf(xbuf, "X:%d", n);
textfeature(TEXT, xbuf);
}
};
}
@@ -6278,6 +6292,6 @@ int main(int argc, char *argv[])
parsefile(filename);
free_abbreviations();
};
return(0);
return(error_count > 0 ? 1 : 0); /* [RK] 2026-03-30 */
}