From a233f54d7c7222b57ec8a35a6dd54c6c9502e777 Mon Sep 17 00:00:00 2001 From: Stefan Reinauer Date: Mon, 7 Sep 2026 01:07:10 -0700 Subject: [PATCH 1/2] amiga: omit unused helpers from handler builds Limit host-only core utilities to non-Amiga builds and keep their public declarations consistent with those guards. Make the ISO directory stub private, retain external linkage for OS4 vector operations, and omit OS4-only wrappers from the classic handler. This lets release builds drop unused code without removing any operations used by the current OS3 or OS4 frontends. --- backends/iso9660/iso9660.c | 4 +-- backends/iso9660/iso9660.h | 4 --- core/cache_block.c | 4 +++ core/charset.c | 2 ++ core/mount.c | 8 ++++-- include/odfs/api.h | 4 ++- include/odfs/cache.h | 3 +++ include/odfs/charset.h | 4 ++- platform/amiga/handler.h | 10 ++++++- platform/amiga/handler_main.c | 49 ++++++++++++++++++++++++----------- 10 files changed, 66 insertions(+), 26 deletions(-) diff --git a/backends/iso9660/iso9660.c b/backends/iso9660/iso9660.c index 9f32a2f..a8cdf87 100644 --- a/backends/iso9660/iso9660.c +++ b/backends/iso9660/iso9660.c @@ -942,8 +942,8 @@ odfs_err_t odfs_iso_merge_multi_extent(odfs_cache_t *cache, } /* synthesize the minimal node needed to enumerate a directory extent */ -odfs_node_t odfs_iso_dir_stub(odfs_backend_type_t backend, - uint32_t lba, uint32_t size) +static odfs_node_t odfs_iso_dir_stub(odfs_backend_type_t backend, + uint32_t lba, uint32_t size) { odfs_node_t n; memset(&n, 0, sizeof(n)); diff --git a/backends/iso9660/iso9660.h b/backends/iso9660/iso9660.h index e75924e..2dacd51 100644 --- a/backends/iso9660/iso9660.h +++ b/backends/iso9660/iso9660.h @@ -186,10 +186,6 @@ odfs_err_t odfs_iso_read_parent_extent(odfs_cache_t *cache, uint32_t *parent_lba_out, uint32_t *parent_size_out); -/* synthesize the minimal directory node needed to enumerate an extent */ -odfs_node_t odfs_iso_dir_stub(odfs_backend_type_t backend, - uint32_t lba, uint32_t size); - /* * Merge the continuation records of a multi-extent file (ISO 9660 Level 3, * ECMA-119 6.5.1). Called after parsing a directory record whose diff --git a/core/cache_block.c b/core/cache_block.c index 617dfee..140a11e 100644 --- a/core/cache_block.c +++ b/core/cache_block.c @@ -283,6 +283,7 @@ void odfs_cache_destroy(odfs_cache_t *cache) memset(cache, 0, sizeof(*cache)); } +#if !defined(AMIGA) void odfs_cache_flush(odfs_cache_t *cache) { if (!cache || !cache->entries) @@ -293,6 +294,7 @@ void odfs_cache_flush(odfs_cache_t *cache) cache->valid_count = 0; cache_reset_indices(cache); } +#endif static int32_t cache_reserve(const odfs_cache_t *cache) { @@ -568,7 +570,9 @@ odfs_err_t odfs_cache_read_bytes(odfs_cache_t *cache, return ODFS_OK; } +#if !defined(AMIGA) const odfs_cache_stats_t *odfs_cache_get_stats(const odfs_cache_t *cache) { return &cache->stats; } +#endif diff --git a/core/charset.c b/core/charset.c index 451e49a..49fb773 100644 --- a/core/charset.c +++ b/core/charset.c @@ -151,6 +151,7 @@ odfs_err_t odfs_iso_name_to_display(const char *src, size_t src_len, return ODFS_OK; } +#if !defined(AMIGA) void odfs_sanitize_name(char *name, size_t len, char replacement) { for (size_t i = 0; i < len && name[i] != '\0'; i++) { @@ -160,6 +161,7 @@ void odfs_sanitize_name(char *name, size_t len, char replacement) name[i] = replacement; } } +#endif #define ODFS_PATH_MAX_COMPONENTS 32 diff --git a/core/mount.c b/core/mount.c index d398691..246c22b 100644 --- a/core/mount.c +++ b/core/mount.c @@ -266,6 +266,7 @@ static int mount_backend_for_type(const odfs_mount_t *mnt, return 0; } +#if !defined(AMIGA) static int mount_virtual_root_by_name(const odfs_mount_t *mnt, const odfs_node_t *dir, const char *name, @@ -287,6 +288,7 @@ static int mount_virtual_root_by_name(const odfs_mount_t *mnt, return 0; } +#endif void odfs_mount_opts_default(odfs_mount_opts_t *opts) { @@ -629,9 +631,10 @@ odfs_err_t odfs_resolve_parent_node(odfs_mount_t *mnt, return odfs_resolve_parent_search(mnt, node, parent_out, grandparent_out); } +#if !defined(AMIGA) odfs_err_t odfs_resolve_path(odfs_mount_t *mnt, - const char *path, - odfs_node_t *out) + const char *path, + odfs_node_t *out) { odfs_node_t current; char component[ODFS_NAME_MAX]; @@ -689,3 +692,4 @@ odfs_err_t odfs_resolve_path(odfs_mount_t *mnt, *out = current; return ODFS_OK; } +#endif diff --git a/include/odfs/api.h b/include/odfs/api.h index 131fa25..7e9221b 100644 --- a/include/odfs/api.h +++ b/include/odfs/api.h @@ -101,10 +101,12 @@ odfs_err_t odfs_readlink(odfs_mount_t *mnt, char *buf, size_t buf_size); -/* resolve full path from root */ +#if !defined(AMIGA) +/* Host path resolver; Amiga frontends resolve paths through DOS locks. */ odfs_err_t odfs_resolve_path(odfs_mount_t *mnt, const char *path, odfs_node_t *out); +#endif /* multisession: find last session start LBA */ odfs_err_t odfs_find_last_session(odfs_media_t *media, diff --git a/include/odfs/cache.h b/include/odfs/cache.h index 10b61a3..6938364 100644 --- a/include/odfs/cache.h +++ b/include/odfs/cache.h @@ -75,10 +75,13 @@ odfs_err_t odfs_cache_read_bytes(odfs_cache_t *cache, void *buf, size_t *len); +#if !defined(AMIGA) +/* Host tools/tests only; Amiga mounts own the cache lifetime. */ /* invalidate all entries */ void odfs_cache_flush(odfs_cache_t *cache); /* get current stats */ const odfs_cache_stats_t *odfs_cache_get_stats(const odfs_cache_t *cache); +#endif #endif /* ODFS_CACHE_H */ diff --git a/include/odfs/charset.h b/include/odfs/charset.h index cbfc6a2..5769ba2 100644 --- a/include/odfs/charset.h +++ b/include/odfs/charset.h @@ -54,11 +54,13 @@ odfs_err_t odfs_iso_name_to_display(const char *src, size_t src_len, char *dst, size_t dst_size, int lowercase); +#if !defined(AMIGA) /* - * Fallback substitution: replace non-printable / non-Amiga-safe + * Host-only fallback: replace non-printable / non-Amiga-safe * characters in a UTF-8 string with a replacement char. */ void odfs_sanitize_name(char *name, size_t len, char replacement); +#endif /* * Convert a POSIX-style symlink target to AmigaDOS path syntax. diff --git a/platform/amiga/handler.h b/platform/amiga/handler.h index 5b761a4..1272130 100644 --- a/platform/amiga/handler.h +++ b/platform/amiga/handler.h @@ -332,9 +332,11 @@ typedef struct odfs_handler_node_info { } odfs_handler_node_info_t; /* shared operations used by packet and OS4 vector frontends */ +#if ODFS_AMIGA_OS4 void odfs_handler_fill_node_info(handler_global_t *g, const odfs_node_t *node, odfs_handler_node_info_t *info); +#endif /* * Resolve the soft link that `path` (relative to parent_lock, or the @@ -357,13 +359,13 @@ LONG odfs_handler_resolve_object_node(handler_global_t *g, const char *path, odfs_node_t *node_out, odfs_node_t *parent_out); -#endif LONG odfs_handler_lock_object(handler_global_t *g, odfs_lock_t *parent_lock, const char *path, LONG access, odfs_lock_t **out); LONG odfs_handler_free_lock_object(handler_global_t *g, odfs_lock_t *ol); +#endif LONG odfs_handler_dup_lock_object(handler_global_t *g, odfs_lock_t *src, odfs_lock_t **out); @@ -380,6 +382,7 @@ LONG odfs_handler_same_lock_object(handler_global_t *g, odfs_lock_t *l1, odfs_lock_t *l2, LONG *same_result); +#if ODFS_AMIGA_OS4 LONG odfs_handler_same_file_object(handler_global_t *g, odfs_fh_t *fh1, odfs_fh_t *fh2, @@ -389,6 +392,7 @@ LONG odfs_handler_open_object(handler_global_t *g, const char *path, LONG mode, odfs_fh_t **out); +#endif LONG odfs_handler_open_from_lock_object(handler_global_t *g, odfs_lock_t *ol, odfs_fh_t **out); @@ -403,6 +407,7 @@ LONG odfs_handler_seek_object(handler_global_t *g, int64_t offset, LONG mode, int64_t *oldpos_out); +#if ODFS_AMIGA_OS4 LONG odfs_handler_change_lock_mode(handler_global_t *g, odfs_lock_t *ol, LONG mode); @@ -415,9 +420,11 @@ LONG odfs_handler_get_file_position(handler_global_t *g, LONG odfs_handler_get_file_size(handler_global_t *g, odfs_fh_t *fh, int64_t *size_out); +#endif LONG odfs_handler_fill_info(handler_global_t *g, odfs_lock_t *ol, struct InfoData *info); +#if ODFS_AMIGA_OS4 LONG odfs_handler_get_lock_node(handler_global_t *g, odfs_lock_t *ol, const odfs_node_t **node_out); @@ -431,6 +438,7 @@ LONG odfs_handler_next_dir_entry(handler_global_t *g, odfs_node_t *entry_out, ULONG *key_out); LONG odfs_handler_inhibit(handler_global_t *g, LONG state); +#endif /* handler entry point (called from startup.S) */ void handler_main(void); diff --git a/platform/amiga/handler_main.c b/platform/amiga/handler_main.c index 406ed0e..1e3e942 100644 --- a/platform/amiga/handler_main.c +++ b/platform/amiga/handler_main.c @@ -24,6 +24,12 @@ #define ODFS_FS_UNLOCK(g) ((void)0) #endif +#if ODFS_AMIGA_OS4 +#define ODFS_VECTOR_LINKAGE +#else +#define ODFS_VECTOR_LINKAGE static +#endif + #if ODFS_FEATURE_CDDA #include "cdda/cdda.h" #endif @@ -1781,9 +1787,10 @@ static void node_date(const odfs_node_t *node, struct DateStamp *ds) ds->ds_Tick = node->mtime.second * TICKS_PER_SECOND; } -void odfs_handler_fill_node_info(handler_global_t *g, - const odfs_node_t *node, - odfs_handler_node_info_t *info) +ODFS_VECTOR_LINKAGE void +odfs_handler_fill_node_info(handler_global_t *g, + const odfs_node_t *node, + odfs_handler_node_info_t *info) { if (!info) return; @@ -2523,11 +2530,12 @@ static LONG resolve_object_into_entry(handler_global_t *g, return 0; } -LONG odfs_handler_lock_object(handler_global_t *g, - odfs_lock_t *parent_lock, - const char *path, - LONG access, - odfs_lock_t **out) +ODFS_VECTOR_LINKAGE LONG +odfs_handler_lock_object(handler_global_t *g, + odfs_lock_t *parent_lock, + const char *path, + LONG access, + odfs_lock_t **out) { odfs_entry_t *entry; LONG err_dos; @@ -2561,7 +2569,8 @@ LONG odfs_handler_lock_object(handler_global_t *g, return 0; } -LONG odfs_handler_free_lock_object(handler_global_t *g, odfs_lock_t *ol) +ODFS_VECTOR_LINKAGE LONG +odfs_handler_free_lock_object(handler_global_t *g, odfs_lock_t *ol) { if (!ol) return 0; @@ -2832,6 +2841,7 @@ LONG odfs_handler_same_lock_object(handler_global_t *g, return 0; } +#if ODFS_AMIGA_OS4 LONG odfs_handler_same_file_object(handler_global_t *g, odfs_fh_t *fh1, odfs_fh_t *fh2, @@ -2860,12 +2870,14 @@ LONG odfs_handler_same_file_object(handler_global_t *g, *same_result = LOCK_SAME; return 0; } +#endif -LONG odfs_handler_open_object(handler_global_t *g, - odfs_lock_t *dirlock, - const char *path, - LONG mode, - odfs_fh_t **out) +ODFS_VECTOR_LINKAGE LONG +odfs_handler_open_object(handler_global_t *g, + odfs_lock_t *dirlock, + const char *path, + LONG mode, + odfs_fh_t **out) { LONG err_dos; odfs_entry_t *entry; @@ -3032,6 +3044,7 @@ LONG odfs_handler_seek_object(handler_global_t *g, return 0; } +#if ODFS_AMIGA_OS4 LONG odfs_handler_get_file_position(handler_global_t *g, odfs_fh_t *fh, int64_t *pos_out) @@ -3116,6 +3129,7 @@ LONG odfs_handler_get_file_size(handler_global_t *g, *size_out = (int64_t)fh_node(fh)->size; return 0; } +#endif LONG odfs_handler_fill_info(handler_global_t *g, odfs_lock_t *ol, @@ -3153,6 +3167,7 @@ LONG odfs_handler_fill_info(handler_global_t *g, return 0; } +#if ODFS_AMIGA_OS4 LONG odfs_handler_get_lock_node(handler_global_t *g, odfs_lock_t *ol, const odfs_node_t **node_out) @@ -3202,8 +3217,10 @@ LONG odfs_handler_get_fh_node(handler_global_t *g, *node_out = fh_node(fh); return 0; } +#endif -LONG odfs_handler_inhibit(handler_global_t *g, LONG state) +ODFS_VECTOR_LINKAGE LONG +odfs_handler_inhibit(handler_global_t *g, LONG state) { if (!g) return ERROR_REQUIRED_ARG_MISSING; @@ -3623,6 +3640,7 @@ static void exnext_cursor_update(odfs_exnext_cursor_t *cursor, } #endif +#if ODFS_AMIGA_OS4 typedef struct dir_next_ctx { ULONG previous_key; int first; @@ -3730,6 +3748,7 @@ LONG odfs_handler_next_dir_entry(handler_global_t *g, *resume_io = resume; return 0; } +#endif static void action_examine_object(handler_global_t *g, struct DosPacket *pkt) { From 197e145819b34a2dc89da64fc307cd63afcacac4 Mon Sep 17 00:00:00 2001 From: Stefan Reinauer Date: Mon, 7 Sep 2026 11:18:40 -0700 Subject: [PATCH 2/2] cdda: use bounded helpers for metadata formatting Replace printf-based CDDB and CD-Text formatting with bounded string, decimal and hexadecimal append helpers. Share numeric key/value lines and CD-Text keys so the output structure remains readable without repeating block and track prefixes at each call site. Keep the generated metadata unchanged and check the complete CDDB and CD-Text output in the existing unit tests. Removing the CDDA formatter dependency reduces the size of release handlers. --- backends/cdda/cdda.c | 210 ++++++++++++++++++++++++++--------------- tests/unit/test_cdda.c | 24 +++-- 2 files changed, 149 insertions(+), 85 deletions(-) diff --git a/backends/cdda/cdda.c b/backends/cdda/cdda.c index f5493da..dcae85d 100644 --- a/backends/cdda/cdda.c +++ b/backends/cdda/cdda.c @@ -20,12 +20,10 @@ #include "odfs/cache.h" #include "odfs/log.h" #include "odfs/error.h" -#include "odfs/printf.h" #include "odfs/string.h" #include #include -#include #define CDDA_CDDB_NAME "CDDB.txt" #define CDDA_CDDB_NODE_ID 0x43444442u @@ -168,26 +166,81 @@ static void cdda_set_album_volume_name(cdda_context_t *ctx) ctx->volume_name[i] = '\0'; } -static int cdda_appendf(char *buf, size_t buf_size, size_t *used, - const char *fmt, ...) +static int cdda_append_bytes(char *buf, size_t buf_size, size_t *used, + const char *src, size_t len) { - va_list ap; - int wrote; - - if (*used >= buf_size) + if (!buf || !used || !src || *used >= buf_size || + len >= buf_size - *used) return 0; - va_start(ap, fmt); - wrote = odfs_vsnprintf(buf + *used, buf_size - *used, fmt, ap); - va_end(ap); + memcpy(buf + *used, src, len); + *used += len; + buf[*used] = '\0'; + return 1; +} - if (wrote < 0 || (size_t)wrote >= buf_size - *used) - return 0; +static int cdda_append_string(char *buf, size_t buf_size, size_t *used, + const char *str) +{ + const char *end = str; + + while (*end != '\0') + end++; + return cdda_append_bytes(buf, buf_size, used, str, (size_t)(end - str)); +} + +static int cdda_append_line(char *buf, size_t buf_size, size_t *used, + const char *value) +{ + return cdda_append_string(buf, buf_size, used, value) && + cdda_append_string(buf, buf_size, used, "\n"); +} + +static int cdda_append_u32(char *buf, size_t buf_size, size_t *used, + uint32_t value, unsigned int min_width) +{ + char digits[10]; + size_t count = 0; + char zero = '0'; + + do { + digits[count++] = (char)('0' + value % 10u); + value /= 10u; + } while (value != 0); + + while (count < min_width) { + if (!cdda_append_bytes(buf, buf_size, used, &zero, 1)) + return 0; + min_width--; + } + + while (count != 0) { + if (!cdda_append_bytes(buf, buf_size, used, &digits[--count], 1)) + return 0; + } - *used += (size_t)wrote; return 1; } +/* Write a complete key=value line without the general printf formatter. */ +static int cdda_append_u32_field(char *buf, size_t buf_size, size_t *used, + const char *key, uint32_t value) +{ + return cdda_append_string(buf, buf_size, used, key) && + cdda_append_string(buf, buf_size, used, "=") && + cdda_append_u32(buf, buf_size, used, value, 0) && + cdda_append_string(buf, buf_size, used, "\n"); +} + +static int cdda_append_hex32(char *buf, size_t buf_size, size_t *used, + uint32_t value) +{ + char digits[9]; + + cdda_format_hex32(digits, value); + return cdda_append_bytes(buf, buf_size, used, digits, 8); +} + static void cdda_generate_cddb(cdda_context_t *ctx) { char *text; @@ -207,47 +260,54 @@ static void cdda_generate_cddb(cdda_context_t *ctx) disc_id = cdda_disc_id(ctx); total_seconds = cdda_total_seconds(ctx); - if (!cdda_appendf(text, text_size, &used, - "# Generated by ODFileSystem from disc TOC\n" - "DISCID=%08" PRIx32 "\n" - "TRACKS=%d\n" - "TOTAL_SECONDS=%" PRIu32 "\n" - "TOTAL_FRAMES=%" PRIu32 "\n", - disc_id, ctx->track_count, - total_seconds, - total_seconds * CDDA_FRAMES_PER_SEC)) { + if (!cdda_append_string(text, text_size, &used, + "# Generated by ODFileSystem from disc TOC\n" + "DISCID=") || + !cdda_append_hex32(text, text_size, &used, disc_id) || + !cdda_append_string(text, text_size, &used, "\n") || + !cdda_append_u32_field(text, text_size, &used, "TRACKS", + (uint32_t)ctx->track_count) || + !cdda_append_u32_field(text, text_size, &used, "TOTAL_SECONDS", + total_seconds) || + !cdda_append_u32_field(text, text_size, &used, "TOTAL_FRAMES", + total_seconds * CDDA_FRAMES_PER_SEC)) { odfs_free(text); return; } for (int i = 0; i < ctx->track_count; i++) { - if (!cdda_appendf(text, text_size, &used, - "OFFSET%02d=%" PRIu32 "\n", - i + 1, - cdda_track_offset_frames(&ctx->tracks[i]))) { + if (!cdda_append_string(text, text_size, &used, "OFFSET") || + !cdda_append_u32(text, text_size, &used, (uint32_t)(i + 1), 2) || + !cdda_append_string(text, text_size, &used, "=") || + !cdda_append_u32(text, text_size, &used, + cdda_track_offset_frames(&ctx->tracks[i]), 0) || + !cdda_append_string(text, text_size, &used, "\n")) { odfs_free(text); return; } } - if (!cdda_appendf(text, text_size, &used, - "QUERY=cddb query %08" PRIx32 " %d", - disc_id, ctx->track_count)) { + if (!cdda_append_string(text, text_size, &used, "QUERY=cddb query ") || + !cdda_append_hex32(text, text_size, &used, disc_id) || + !cdda_append_string(text, text_size, &used, " ") || + !cdda_append_u32(text, text_size, &used, + (uint32_t)ctx->track_count, 0)) { odfs_free(text); return; } for (int i = 0; i < ctx->track_count; i++) { - if (!cdda_appendf(text, text_size, &used, - " %" PRIu32, - cdda_track_offset_frames(&ctx->tracks[i]))) { + if (!cdda_append_string(text, text_size, &used, " ") || + !cdda_append_u32(text, text_size, &used, + cdda_track_offset_frames(&ctx->tracks[i]), 0)) { odfs_free(text); return; } } - if (!cdda_appendf(text, text_size, &used, " %" PRIu32 "\n", - total_seconds)) { + if (!cdda_append_string(text, text_size, &used, " ") || + !cdda_append_u32(text, text_size, &used, total_seconds, 0) || + !cdda_append_string(text, text_size, &used, "\n")) { odfs_free(text); return; } @@ -346,6 +406,31 @@ static size_t cdda_hex_encode(char *dst, size_t dst_size, return used; } +/* A CD-Text key is [BLOCKnn.]DISC.TYPE= or [BLOCKnn.]TRACKnn.TYPE=. */ +static int cdda_append_cdtext_key(char *buf, size_t buf_size, size_t *used, + uint8_t type, uint32_t track, uint8_t block) +{ + if (block != 0 && + (!cdda_append_string(buf, buf_size, used, "BLOCK") || + !cdda_append_u32(buf, buf_size, used, block, 2) || + !cdda_append_string(buf, buf_size, used, "."))) + return 0; + + if (track == 0) { + if (!cdda_append_string(buf, buf_size, used, "DISC.")) + return 0; + } else { + if (!cdda_append_string(buf, buf_size, used, "TRACK") || + !cdda_append_u32(buf, buf_size, used, track, 2) || + !cdda_append_string(buf, buf_size, used, ".")) + return 0; + } + + return cdda_append_string(buf, buf_size, used, + cdda_cdtext_type_name(type, (uint8_t)track)) && + cdda_append_string(buf, buf_size, used, "="); +} + static int cdda_append_cdtext_record(char *buf, size_t buf_size, size_t *used, uint8_t type, uint8_t track, uint8_t block, int is_dbcs, const uint8_t *data, @@ -355,27 +440,11 @@ static int cdda_append_cdtext_record(char *buf, size_t buf_size, size_t *used, size_t start = 0; int value_count = 0; - if (track == 0) { - if (block != 0) { - if (!cdda_appendf(buf, buf_size, used, "BLOCK%02u.", block)) - return 0; - } - if (!cdda_appendf(buf, buf_size, used, "DISC.%s=", - cdda_cdtext_type_name(type, track))) - return 0; - } else { - if (block != 0) { - if (!cdda_appendf(buf, buf_size, used, "BLOCK%02u.", block)) - return 0; - } - if (!cdda_appendf(buf, buf_size, used, "TRACK%02u.%s=", - track, cdda_cdtext_type_name(type, track))) - return 0; - } + if (!cdda_append_cdtext_key(buf, buf_size, used, type, track, block)) + return 0; - if (is_dbcs) { - return cdda_appendf(buf, buf_size, used, "\n"); - } + if (is_dbcs) + return cdda_append_string(buf, buf_size, used, "\n"); if (type >= 0x80 && type <= 0x85) { while (start < data_size) { @@ -384,27 +453,27 @@ static int cdda_append_cdtext_record(char *buf, size_t buf_size, size_t *used, end++; if (end > start) { if (value_count > 0) { - if (!cdda_appendf(buf, buf_size, used, "; ")) + if (!cdda_append_string(buf, buf_size, used, "; ")) return 0; } cdda_sanitize_ascii(value, sizeof(value), data + start, end - start); - if (!cdda_appendf(buf, buf_size, used, "%s", value)) + if (!cdda_append_string(buf, buf_size, used, value)) return 0; value_count++; } start = end + 1; } - return cdda_appendf(buf, buf_size, used, "\n"); + return cdda_append_string(buf, buf_size, used, "\n"); } if (type == 0x8e) { cdda_sanitize_ascii(value, sizeof(value), data, data_size); - return cdda_appendf(buf, buf_size, used, "%s\n", value); + return cdda_append_line(buf, buf_size, used, value); } cdda_hex_encode(value, sizeof(value), data, data_size); - return cdda_appendf(buf, buf_size, used, "%s\n", value); + return cdda_append_line(buf, buf_size, used, value); } static void cdda_store_track_title(cdda_context_t *ctx, int track, @@ -560,20 +629,10 @@ static int cdda_render_cdtext_strings(const uint8_t *raw, size_t pack_count, if (!skip_current && cur_len != 0) { cdda_sanitize_ascii(clean, sizeof(clean), (const uint8_t *)cur, cur_len); - if (block != 0 && - !cdda_appendf(buf, buf_size, used, "BLOCK%02u.", block)) + if (!cdda_append_cdtext_key(buf, buf_size, used, type, + (uint32_t)cur_track, block) || + !cdda_append_line(buf, buf_size, used, clean)) return 0; - if (cur_track == 0) { - if (!cdda_appendf(buf, buf_size, used, "DISC.%s=%s\n", - cdda_cdtext_type_name(type, 0), clean)) - return 0; - } else if (!cdda_appendf(buf, buf_size, used, - "TRACK%02u.%s=%s\n", cur_track, - cdda_cdtext_type_name(type, - (uint8_t)cur_track), - clean)) { - return 0; - } } cur_track++; cur_len = 0; @@ -625,8 +684,9 @@ static void cdda_generate_cdtext(cdda_context_t *ctx) return; } - if (!cdda_appendf(text, 128u + raw_size * 4u, &used, - "# Generated by ODFileSystem from CD-Text packs\n")) { + if (!cdda_append_string( + text, 128u + raw_size * 4u, &used, + "# Generated by ODFileSystem from CD-Text packs\n")) { odfs_free(field_buf); odfs_free(text); odfs_free(raw); diff --git a/tests/unit/test_cdda.c b/tests/unit/test_cdda.c index 96c8ce5..4dd8ae1 100644 --- a/tests/unit/test_cdda.c +++ b/tests/unit/test_cdda.c @@ -235,13 +235,15 @@ TEST(cdda_cddb_file_exposes_disc_id_and_query) buf, &len)); buf[len] = '\0'; - ASSERT(strstr(buf, "DISCID=05000402\n") != NULL); - ASSERT(strstr(buf, "TRACKS=2\n") != NULL); - ASSERT(strstr(buf, "TOTAL_SECONDS=4\n") != NULL); - ASSERT(strstr(buf, "TOTAL_FRAMES=300\n") != NULL); - ASSERT(strstr(buf, "OFFSET01=150\n") != NULL); - ASSERT(strstr(buf, "OFFSET02=250\n") != NULL); - ASSERT(strstr(buf, "QUERY=cddb query 05000402 2 150 250 4\n") != NULL); + ASSERT_STR_EQ(buf, + "# Generated by ODFileSystem from disc TOC\n" + "DISCID=05000402\n" + "TRACKS=2\n" + "TOTAL_SECONDS=4\n" + "TOTAL_FRAMES=300\n" + "OFFSET01=150\n" + "OFFSET02=250\n" + "QUERY=cddb query 05000402 2 150 250 4\n"); cdda_backend_ops.unmount(backend_ctx); } @@ -419,9 +421,11 @@ TEST(cdda_cdtext_file_exposes_parsed_metadata) ASSERT_OK(cdda_backend_ops.read(backend_ctx, NULL, NULL, &cdtext, 0, buf, &len)); buf[len] = '\0'; - ASSERT(strstr(buf, "DISC.TITLE=Album\n") != NULL); - ASSERT(strstr(buf, "DISC.PERFORMER=Artist\n") != NULL); - ASSERT(strstr(buf, "TRACK01.TITLE=Song 1\n") != NULL); + ASSERT_STR_EQ(buf, + "# Generated by ODFileSystem from CD-Text packs\n" + "DISC.TITLE=Album\n" + "TRACK01.TITLE=Song 1\n" + "DISC.PERFORMER=Artist\n"); /* the track title also becomes the AmigaDOS file comment */ ASSERT_EQ(collect.entries[2].amiga_as.has_comment, 1);