#include "unity/unity.h" #include "zlib.h" #include #include #include #include /* Unity setup/teardown */ void setUp(void) { /* Setup code here, or leave empty */ } void tearDown(void) { /* Cleanup code here, or leave empty */ } /* Helper: create a unique temporary filename with .gz suffix. Returns a heap-allocated string that must be freed by the caller. */ static char* make_temp_gz_path(void) { char base[L_tmpnam]; char fallback[64]; char *result; if (tmpnam(base) == NULL) { /* Fallback: use time + rand */ srand((unsigned)time(NULL)); snprintf(fallback, sizeof(fallback), "tmp_gzeof_%lu_%u", (unsigned long)time(NULL), (unsigned)rand()); snprintf(base, sizeof(base), "%s", fallback); } size_t len = strlen(base) + 3; /* + ".gz" and null */ result = (char*)malloc(len + 1); if (!result) return NULL; snprintf(result, len + 1, "%s.gz", base); return result; } /* Helper: write content to a gzip file (overwrites if exists). */ static void write_gz_file(const char *path, const void *data, unsigned len) { gzFile f = gzopen(path, "wb"); TEST_ASSERT_MESSAGE(f != NULL, "gzopen for write failed"); int wrote = gzwrite(f, data, len); TEST_ASSERT_EQUAL_INT((int)len, wrote); int rc = gzclose(f); TEST_ASSERT_EQUAL_INT(0, rc); } /* Test: gzeof(NULL) returns 0 */ static void test_gzeof_null_returns_zero(void) { TEST_ASSERT_EQUAL_INT(0, gzeof(NULL)); } /* Test: gzeof on write-mode handle is always 0 */ static void test_gzeof_write_mode_returns_zero(void) { char *path = make_temp_gz_path(); TEST_ASSERT_NOT_NULL(path); gzFile f = gzopen(path, "wb"); TEST_ASSERT_NOT_NULL(f); /* Before writing */ TEST_ASSERT_EQUAL_INT(0, gzeof(f)); /* After writing some data */ const char *msg = "writing some data"; int wrote = gzwrite(f, msg, (unsigned)strlen(msg)); TEST_ASSERT_EQUAL_INT((int)strlen(msg), wrote); TEST_ASSERT_EQUAL_INT(0, gzeof(f)); /* Close and cleanup */ TEST_ASSERT_EQUAL_INT(0, gzclose(f)); remove(path); free(path); } /* Test: gzeof on read-mode remains 0 until reading past end */ static void test_gzeof_read_mode_past_end_behavior(void) { char *path = make_temp_gz_path(); TEST_ASSERT_NOT_NULL(path); const char *content = "hello"; write_gz_file(path, content, (unsigned)strlen(content)); gzFile f = gzopen(path, "rb"); TEST_ASSERT_NOT_NULL(f); /* Before any read */ TEST_ASSERT_EQUAL_INT(0, gzeof(f)); /* Partial read */ char buf[3]; int n = gzread(f, buf, 3); TEST_ASSERT_EQUAL_INT(3, n); TEST_ASSERT_EQUAL_INT(0, gzeof(f)); /* not past end yet */ /* Read remaining bytes (2 more) */ char buf2[4] = {0}; int n2 = gzread(f, buf2, 2); TEST_ASSERT_EQUAL_INT(2, n2); /* Now attempt to read one more byte to go past end */ int c = gzgetc(f); TEST_ASSERT_EQUAL_INT(-1, c); TEST_ASSERT_NOT_EQUAL(0, gzeof(f)); /* now past end */ /* Cleanup */ TEST_ASSERT_EQUAL_INT(0, gzclose(f)); remove(path); free(path); } /* Test: gzclearerr resets gzeof from non-zero back to zero */ static void test_gzeof_cleared_by_gzclearerr(void) { char *path = make_temp_gz_path(); TEST_ASSERT_NOT_NULL(path); const char *content = "abc"; write_gz_file(path, content, (unsigned)strlen(content)); gzFile f = gzopen(path, "rb"); TEST_ASSERT_NOT_NULL(f); /* Consume all data */ char buf[8]; int n = gzread(f, buf, (unsigned)strlen(content)); TEST_ASSERT_EQUAL_INT((int)strlen(content), n); /* Force read past end */ TEST_ASSERT_EQUAL_INT(-1, gzgetc(f)); TEST_ASSERT_NOT_EQUAL(0, gzeof(f)); /* Clear and check */ gzclearerr(f); TEST_ASSERT_EQUAL_INT(0, gzeof(f)); /* Reading past end again makes it non-zero again */ TEST_ASSERT_EQUAL_INT(-1, gzgetc(f)); TEST_ASSERT_NOT_EQUAL(0, gzeof(f)); TEST_ASSERT_EQUAL_INT(0, gzclose(f)); remove(path); free(path); } /* Test: gzrewind resets so that gzeof becomes 0 again */ static void test_gzeof_reset_by_gzrewind(void) { char *path = make_temp_gz_path(); TEST_ASSERT_NOT_NULL(path); const char *content = "ABCDEFG"; write_gz_file(path, content, (unsigned)strlen(content)); gzFile f = gzopen(path, "rb"); TEST_ASSERT_NOT_NULL(f); /* Read to end */ char buf[16]; int n = gzread(f, buf, sizeof(buf)); TEST_ASSERT_EQUAL_INT((int)strlen(content), n); /* Force read past end so gzeof is non-zero */ TEST_ASSERT_EQUAL_INT(-1, gzgetc(f)); TEST_ASSERT_NOT_EQUAL(0, gzeof(f)); /* Rewind and confirm gzeof reset */ TEST_ASSERT_EQUAL_INT(0, gzrewind(f)); TEST_ASSERT_EQUAL_INT(0, gzeof(f)); /* Close and cleanup */ TEST_ASSERT_EQUAL_INT(0, gzclose(f)); remove(path); free(path); } int main(void) { UNITY_BEGIN(); RUN_TEST(test_gzeof_null_returns_zero); RUN_TEST(test_gzeof_write_mode_returns_zero); RUN_TEST(test_gzeof_read_mode_past_end_behavior); RUN_TEST(test_gzeof_cleared_by_gzclearerr); RUN_TEST(test_gzeof_reset_by_gzrewind); return UNITY_END(); }