diff --git a/CMakeLists.txt b/CMakeLists.txt index 93be785..2183df1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,7 @@ add_library( libopustags OBJECT src/cli.cc + src/error.cc src/ogg.cc src/opus.cc ) diff --git a/src/error.cc b/src/error.cc new file mode 100644 index 0000000..9448836 --- /dev/null +++ b/src/error.cc @@ -0,0 +1,26 @@ +#include + +static const char* messages[] = { + "OK", + "Need to exit", + "Bad command-line arguments", + "Integer overflow", + "Standard error", + "End of file", + "libogg error", + "Bad magic number", + "Overflowing magic number", + "Overflowing vendor length", + "Overflowing vendor data", + "Overflowing comment count", + "Overflowing comment length", + "Overflowing comment data", +}; + +const char* ot::error_message(ot::status code) +{ +if (code >= ot::status::sentinel) + return nullptr; +auto index = static_cast(code); +return messages[index]; +} diff --git a/src/opustags.h b/src/opustags.h index 4505245..0639bb5 100644 --- a/src/opustags.h +++ b/src/opustags.h @@ -15,15 +15,16 @@ namespace ot { /** - * Possible error status. + * Possible error status, ranging from #ok (0) to #sentinel. * - * The overflowing error family means that the end of packet was reached when - * attempting to read the overflowing value. For example, - * overflowing_comment_count means that after reading the vendor string, less - * than 4 bytes were left in the packet. + * Use #error_message to get an error message from a status code. + * + * The overflowing error family means that the end of packet was reached when attempting to read the + * overflowing value. For example, overflowing_comment_count means that after reading the vendor + * string, less than 4 bytes were left in the packet. */ enum class status { - ok, + ok = 0, exit_now, bad_arguments, int_overflow, @@ -39,8 +40,15 @@ enum class status { overflowing_comment_count, overflowing_comment_length, overflowing_comment_data, + /** + * Last error code, for integrity checking. + * Do not use it, it does not represent any error. + */ + sentinel, }; +const char* error_message(status code); + /** * \defgroup ogg Ogg * \brief Helpers to work with libogg. diff --git a/t/CMakeLists.txt b/t/CMakeLists.txt index 52e7746..5d20f77 100644 --- a/t/CMakeLists.txt +++ b/t/CMakeLists.txt @@ -1,8 +1,11 @@ add_executable(opus.t EXCLUDE_FROM_ALL opus.cc) target_link_libraries(opus.t libopustags) +add_executable(error.t EXCLUDE_FROM_ALL error.cc) +target_link_libraries(error.t libopustags) + add_custom_target( check COMMAND prove "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}" - DEPENDS opustags opus.t + DEPENDS opustags opus.t error.t ) diff --git a/t/error.cc b/t/error.cc new file mode 100644 index 0000000..3b5e555 --- /dev/null +++ b/t/error.cc @@ -0,0 +1,27 @@ +#include +#include "tap.h" + +static void check_message() +{ + if (strcmp(ot::error_message(ot::status::ok), "OK") != 0) + throw failure("unexpected message for code ok"); + if (strcmp(ot::error_message(ot::status::overflowing_comment_data), "Overflowing comment data") != 0) + throw failure("unexpected message for overflowing_comment_data"); +} + +static void check_sentinel() +{ + if (ot::error_message(ot::status::sentinel) != nullptr) + throw failure("the sentinel should not have a message"); + auto too_far = static_cast(static_cast(ot::status::sentinel) + 1); + if (ot::error_message(too_far) != nullptr) + throw failure("an invalid status should not have a message"); +} + +int main() +{ + std::cout << "1..2\n"; + run(check_message, "check a few error messages"); + run(check_sentinel, "ensure the sentinel is respected"); + return 0; +}