[id3lib-devel] Fix build for C99 and un-break ABI for C++
Brought to you by:
t1mpy
From: Đoàn T. C. D. <con...@gm...> - 2022-09-15 15:52:30
|
Hello, id3lib is failed to be built with C99 due to conflict types for bool. C99 defines bool as a typedef for _Bool in stdbool.h, which could be included transitively via stdlib.h. We can fix the build by guarding the typedef with #ifdef __bool_true_false_are_defined However, that would not be ideal, and some buggy C99 version doesn't define that macro, either. That raises another issue, id3lib's bool is a typedef of int, which is typically 4 or 8 bytes in major architecture. However, C99 and C++ bool is typically 1 byte. Hence, the current code is already broken for C++ because struct Mp3_Headerinfo has different layout for C and C++ (in C++, privatebit, copyrighted, and original are squeezed into 1 word, but in old C, it's in 3 different words). It's also broken if id3lib was built with C99 (with patch for typedef) and its dependants with old C, and vice versus. In addition, passing bool as parameter and return bool are also broken in big-endian C++, and C99. The only way the keep id3lib buildable and not break ABI is changing all C facing interface bool to int. Here is a patch to do that. --- --- a/include/id3.h +++ b/include/id3.h @@ -47,12 +47,12 @@ extern "C" ID3_C_EXPORT ID3Tag* CCONV ID3Tag_New (void); ID3_C_EXPORT void CCONV ID3Tag_Delete (ID3Tag *tag); ID3_C_EXPORT void CCONV ID3Tag_Clear (ID3Tag *tag); - ID3_C_EXPORT bool CCONV ID3Tag_HasChanged (const ID3Tag *tag); - ID3_C_EXPORT void CCONV ID3Tag_SetUnsync (ID3Tag *tag, bool unsync); - ID3_C_EXPORT void CCONV ID3Tag_SetExtendedHeader (ID3Tag *tag, bool ext); - ID3_C_EXPORT void CCONV ID3Tag_SetPadding (ID3Tag *tag, bool pad); + ID3_C_EXPORT ID3_Bool CCONV ID3Tag_HasChanged (const ID3Tag *tag); + ID3_C_EXPORT void CCONV ID3Tag_SetUnsync (ID3Tag *tag, ID3_Bool unsync); + ID3_C_EXPORT void CCONV ID3Tag_SetExtendedHeader (ID3Tag *tag, ID3_Bool ext); + ID3_C_EXPORT void CCONV ID3Tag_SetPadding (ID3Tag *tag, ID3_Bool pad); ID3_C_EXPORT void CCONV ID3Tag_AddFrame (ID3Tag *tag, const ID3Frame *frame); - ID3_C_EXPORT bool CCONV ID3Tag_AttachFrame (ID3Tag *tag, ID3Frame *frame); + ID3_C_EXPORT ID3_Bool CCONV ID3Tag_AttachFrame (ID3Tag *tag, ID3Frame *frame); ID3_C_EXPORT void CCONV ID3Tag_AddFrames (ID3Tag *tag, const ID3Frame *frames, size_t num); ID3_C_EXPORT ID3Frame* CCONV ID3Tag_RemoveFrame (ID3Tag *tag, const ID3Frame *frame); ID3_C_EXPORT ID3_Err CCONV ID3Tag_Parse (ID3Tag *tag, const uchar header[ID3_TAGHEADERSIZE], const uchar *buffer); @@ -66,7 +66,7 @@ extern "C" ID3_C_EXPORT ID3Frame* CCONV ID3Tag_FindFrameWithASCII (const ID3Tag *tag, ID3_FrameID id, ID3_FieldID fld, const char *data); ID3_C_EXPORT ID3Frame* CCONV ID3Tag_FindFrameWithUNICODE (const ID3Tag *tag, ID3_FrameID id, ID3_FieldID fld, const unicode_t *data); ID3_C_EXPORT size_t CCONV ID3Tag_NumFrames (const ID3Tag *tag); - ID3_C_EXPORT bool CCONV ID3Tag_HasTagType (const ID3Tag *tag, ID3_TagType); + ID3_C_EXPORT ID3_Bool CCONV ID3Tag_HasTagType (const ID3Tag *tag, ID3_TagType); ID3_C_EXPORT ID3TagIterator* CCONV ID3Tag_CreateIterator (ID3Tag *tag); ID3_C_EXPORT ID3TagConstIterator* CCONV ID3Tag_CreateConstIterator (const ID3Tag *tag); @@ -83,8 +83,8 @@ extern "C" ID3_C_EXPORT void CCONV ID3Frame_SetID (ID3Frame *frame, ID3_FrameID id); ID3_C_EXPORT ID3_FrameID CCONV ID3Frame_GetID (const ID3Frame *frame); ID3_C_EXPORT ID3Field* CCONV ID3Frame_GetField (const ID3Frame *frame, ID3_FieldID name); - ID3_C_EXPORT void CCONV ID3Frame_SetCompression (ID3Frame *frame, bool comp); - ID3_C_EXPORT bool CCONV ID3Frame_GetCompression (const ID3Frame *frame); + ID3_C_EXPORT void CCONV ID3Frame_SetCompression (ID3Frame *frame, ID3_Bool comp); + ID3_C_EXPORT ID3_Bool CCONV ID3Frame_GetCompression (const ID3Frame *frame); /* field wrappers */ ID3_C_EXPORT void CCONV ID3Field_Clear (ID3Field *field); @@ -116,7 +116,7 @@ extern "C" ID3_C_EXPORT flags_t CCONV ID3FrameInfo_FieldFlags (ID3_FrameID frameid, int fieldnum); /* Deprecated */ - ID3_C_EXPORT void CCONV ID3Tag_SetCompression (ID3Tag *tag, bool comp); + ID3_C_EXPORT void CCONV ID3Tag_SetCompression (ID3Tag *tag, ID3_Bool comp); #ifdef __cplusplus } --- a/include/id3/globals.h +++ b/include/id3/globals.h @@ -82,14 +82,10 @@ #define ID3_C_VAR extern -#ifndef __cplusplus - -typedef int bool; -# define false (0) -# define true (!false) - -#endif /* __cplusplus */ +typedef int ID3_Bool; +# define ID3_False 0 +# define ID3_True 1 ID3_C_VAR const char * const ID3LIB_NAME; ID3_C_VAR const char * const ID3LIB_RELEASE; ID3_C_VAR const char * const ID3LIB_FULL_NAME; @@ -532,9 +530,9 @@ ID3_STRUCT(Mp3_Headerinfo) uint32 framesize; uint32 frames; // nr of frames uint32 time; // nr of seconds in song - bool privatebit; - bool copyrighted; - bool original; + ID3_Bool privatebit; + ID3_Bool copyrighted; + ID3_Bool original; }; #define ID3_NR_OF_V1_GENRES 148 --- a/src/c_wrapper.cpp +++ b/src/c_wrapper.cpp @@ -72,10 +72,10 @@ extern "C" } - ID3_C_EXPORT bool CCONV + ID3_C_EXPORT ID3_Bool CCONV ID3Tag_HasChanged(const ID3Tag *tag) { - bool changed = false; + ID3_Bool changed = ID3_False; if (tag) { @@ -87,7 +87,7 @@ extern "C" ID3_C_EXPORT void CCONV - ID3Tag_SetUnsync(ID3Tag *tag, bool unsync) + ID3Tag_SetUnsync(ID3Tag *tag, ID3_Bool unsync) { if (tag) { @@ -97,7 +97,7 @@ extern "C" ID3_C_EXPORT void CCONV - ID3Tag_SetExtendedHeader(ID3Tag *tag, bool ext) + ID3Tag_SetExtendedHeader(ID3Tag *tag, ID3_Bool ext) { if (tag) { @@ -106,7 +106,7 @@ extern "C" } ID3_C_EXPORT void CCONV - ID3Tag_SetPadding(ID3Tag *tag, bool pad) + ID3Tag_SetPadding(ID3Tag *tag, ID3_Bool pad) { if (tag) { @@ -125,10 +125,10 @@ extern "C" } - ID3_C_EXPORT bool CCONV + ID3_C_EXPORT ID3_Bool CCONV ID3Tag_AttachFrame(ID3Tag *tag, ID3Frame *frame) { - bool b = false; + ID3_Bool b = ID3_False; if (tag) { ID3_CATCH(b = reinterpret_cast<ID3_Tag *>(tag)->AttachFrame(reinterpret_cast<ID3_Frame *>(frame))); @@ -303,10 +303,10 @@ extern "C" } - ID3_C_EXPORT bool CCONV + ID3_C_EXPORT ID3_Bool CCONV ID3Tag_HasTagType(const ID3Tag *tag, ID3_TagType tt) { - bool has_tt = false; + ID3_Bool has_tt = ID3_False; if (tag) { @@ -459,7 +459,7 @@ extern "C" ID3_C_EXPORT void CCONV - ID3Frame_SetCompression(ID3Frame *frame, bool comp) + ID3Frame_SetCompression(ID3Frame *frame, ID3_Bool comp) { if (frame) { @@ -468,10 +468,10 @@ extern "C" } - ID3_C_EXPORT bool CCONV + ID3_C_EXPORT ID3_Bool CCONV ID3Frame_GetCompression(const ID3Frame *frame) { - bool compressed = false; + ID3_Bool compressed = ID3_False; if (frame) { ID3_CATCH(compressed = reinterpret_cast<const ID3_Frame *>(frame)->GetCompression()); -- Danh |