ATF_TC_BODY(init_raw, tc) { const char *src = "String 1, String 2"; atf_dynstr_t str; RE(atf_dynstr_init_raw(&str, src, 0)); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0); atf_dynstr_fini(&str); RE(atf_dynstr_init_raw(&str, src, 8)); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 1") == 0); atf_dynstr_fini(&str); RE(atf_dynstr_init_raw(&str, src + 10, 8)); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 2") == 0); atf_dynstr_fini(&str); RE(atf_dynstr_init_raw(&str, "String\0Lost", 11)); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String") == 0); atf_dynstr_fini(&str); { atf_error_t err = atf_dynstr_init_raw(&str, "NULL", SIZE_MAX - 1); ATF_REQUIRE(atf_is_error(err)); ATF_REQUIRE(atf_error_is(err, "no_memory")); atf_error_free(err); } }
ATF_TC_BODY(fork, tc) { fprintf(stdout, "Should not get into child\n"); fprintf(stderr, "Should not get into child\n"); pid_t pid = atf_utils_fork(); if (pid == 0) { fprintf(stdout, "Child stdout\n"); fprintf(stderr, "Child stderr\n"); exit(EXIT_SUCCESS); } int status; ATF_REQUIRE(waitpid(pid, &status, 0) != -1); ATF_REQUIRE(WIFEXITED(status)); ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); atf_dynstr_t out_name; RE(atf_dynstr_init_fmt(&out_name, "atf_utils_fork_%d_out.txt", (int)pid)); atf_dynstr_t err_name; RE(atf_dynstr_init_fmt(&err_name, "atf_utils_fork_%d_err.txt", (int)pid)); char buffer[1024]; read_file(atf_dynstr_cstring(&out_name), buffer, sizeof(buffer)); ATF_REQUIRE_STREQ("Child stdout\n", buffer); read_file(atf_dynstr_cstring(&err_name), buffer, sizeof(buffer)); ATF_REQUIRE_STREQ("Child stderr\n", buffer); atf_dynstr_fini(&err_name); atf_dynstr_fini(&out_name); }
bool grep_file(const char *file, const char *regex, ...) { bool done, found; int fd; va_list ap; atf_dynstr_t formatted; va_start(ap, regex); RE(atf_dynstr_init_ap(&formatted, regex, ap)); va_end(ap); done = false; found = false; ATF_REQUIRE((fd = open(file, O_RDONLY)) != -1); do { atf_dynstr_t line; RE(atf_dynstr_init(&line)); done = read_line(fd, &line); if (!done) found = grep_string(&line, atf_dynstr_cstring(&formatted)); atf_dynstr_fini(&line); } while (!found && !done); close(fd); atf_dynstr_fini(&formatted); return found; }
ATF_TC_BODY(equal_dynstr, tc) { atf_dynstr_t str, str2; RE(atf_dynstr_init(&str)); RE(atf_dynstr_init_fmt(&str2, "Test")); ATF_REQUIRE( atf_equal_dynstr_dynstr(&str, &str)); ATF_REQUIRE(!atf_equal_dynstr_dynstr(&str, &str2)); atf_dynstr_fini(&str2); atf_dynstr_fini(&str); }
static void check_prepend(atf_error_t (*prepend)(atf_dynstr_t *, const char *, ...)) { const size_t maxlen = 8192; char buf[maxlen + 1]; size_t i; atf_dynstr_t str; printf("Prepending with plain string\n"); buf[0] = '\0'; RE(atf_dynstr_init(&str)); for (i = 0; i < maxlen; i++) { if (strcmp(atf_dynstr_cstring(&str), buf) != 0) { fprintf(stderr, "Failed at iteration %zd\n", i); atf_tc_fail("Failed to prepend character at iteration %zd", i); } memmove(buf + 1, buf, i + 1); if (i % 2 == 0) { RE(prepend(&str, "%s", "a")); buf[0] = 'a'; } else { RE(prepend(&str, "%s", "b")); buf[0] = 'b'; } } atf_dynstr_fini(&str); printf("Prepending with formatted string\n"); buf[0] = '\0'; RE(atf_dynstr_init(&str)); for (i = 0; i < maxlen; i++) { if (strcmp(atf_dynstr_cstring(&str), buf) != 0) { fprintf(stderr, "Failed at iteration %zd\n", i); atf_tc_fail("Failed to prepend character at iteration %zd", i); } memmove(buf + 1, buf, i + 1); if (i % 2 == 0) { RE(prepend(&str, "%s", "a")); buf[0] = 'a'; } else { RE(prepend(&str, "%s", "b")); buf[0] = 'b'; } } atf_dynstr_fini(&str); }
/** Searches for a regexp in a file. * * \param regex The regexp to look for. * \param file The file in which to look for the expression. * \param ... Positional parameters to the regex. * * \return True if there is a match; false otherwise. */ bool atf_utils_grep_file(const char *regex, const char *file, ...) { int fd; va_list ap; atf_dynstr_t formatted; atf_error_t error; va_start(ap, file); error = atf_dynstr_init_ap(&formatted, regex, ap); va_end(ap); ATF_REQUIRE(!atf_is_error(error)); ATF_REQUIRE((fd = open(file, O_RDONLY)) != -1); bool found = false; char *line = NULL; while (!found && (line = atf_utils_readline(fd)) != NULL) { found = grep_string(atf_dynstr_cstring(&formatted), line); free(line); } close(fd); atf_dynstr_fini(&formatted); return found; }
ATF_TC_BODY(copy, tc) { atf_dynstr_t str, str2; RE(atf_dynstr_init_fmt(&str, "Test string")); RE(atf_dynstr_copy(&str2, &str)); ATF_REQUIRE(atf_equal_dynstr_dynstr(&str, &str2)); RE(atf_dynstr_append_fmt(&str2, " non-shared text")); ATF_REQUIRE(!atf_equal_dynstr_dynstr(&str, &str2)); atf_dynstr_fini(&str2); atf_dynstr_fini(&str); }
ATF_TC_BODY(path_leaf_name, tc) { struct test { const char *in; const char *leaf; } tests[] = { { ".", "." }, { "foo", "foo" }, { "foo/bar", "bar" }, { "/foo", "foo" }, { "/foo/bar", "bar" }, { NULL, NULL }, }; struct test *t; for (t = &tests[0]; t->in != NULL; t++) { atf_fs_path_t p; atf_dynstr_t ln; printf("Input : %s\n", t->in); printf("Expected output: %s\n", t->leaf); RE(atf_fs_path_init_fmt(&p, "%s", t->in)); RE(atf_fs_path_leaf_name(&p, &ln)); printf("Output : %s\n", atf_dynstr_cstring(&ln)); ATF_REQUIRE(atf_equal_dynstr_cstring(&ln, t->leaf)); atf_dynstr_fini(&ln); atf_fs_path_fini(&p); printf("\n"); } }
ATF_TC_BODY(equal_cstring, tc) { atf_dynstr_t str; RE(atf_dynstr_init(&str)); ATF_REQUIRE( atf_equal_dynstr_cstring(&str, "")); ATF_REQUIRE(!atf_equal_dynstr_cstring(&str, "Test")); atf_dynstr_fini(&str); RE(atf_dynstr_init_fmt(&str, "Test")); ATF_REQUIRE( atf_equal_dynstr_cstring(&str, "Test")); ATF_REQUIRE(!atf_equal_dynstr_cstring(&str, "")); ATF_REQUIRE(!atf_equal_dynstr_cstring(&str, "Tes")); ATF_REQUIRE(!atf_equal_dynstr_cstring(&str, "Test ")); atf_dynstr_fini(&str); }
static atf_error_t normalize_ap(atf_dynstr_t *d, const char *p, va_list ap) { char *str; atf_error_t err; va_list ap2; err = atf_dynstr_init(d); if (atf_is_error(err)) goto out; va_copy(ap2, ap); err = atf_text_format_ap(&str, p, ap2); va_end(ap2); if (atf_is_error(err)) atf_dynstr_fini(d); else { err = normalize(d, str); free(str); } out: return err; }
ATF_TC_BODY(cstring, tc) { const char *cstr; atf_dynstr_t str; RE(atf_dynstr_init_fmt(&str, "Test string 1")); cstr = atf_dynstr_cstring(&str); ATF_REQUIRE(cstr != NULL); ATF_REQUIRE(strcmp(cstr, "Test string 1") == 0); atf_dynstr_fini(&str); RE(atf_dynstr_init_fmt(&str, "Test string 2")); cstr = atf_dynstr_cstring(&str); ATF_REQUIRE(cstr != NULL); ATF_REQUIRE(strcmp(cstr, "Test string 2") == 0); atf_dynstr_fini(&str); }
ATF_TC_BODY(init_substr, tc) { atf_dynstr_t src; atf_dynstr_t str; RE(atf_dynstr_init_fmt(&src, "Str 1, Str 2")); RE(atf_dynstr_init_substr(&str, &src, 0, 0)); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0); atf_dynstr_fini(&str); RE(atf_dynstr_init_substr(&str, &src, 0, atf_dynstr_npos)); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Str 1, Str 2") == 0); atf_dynstr_fini(&str); RE(atf_dynstr_init_substr(&str, &src, 0, 100)); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Str 1, Str 2") == 0); atf_dynstr_fini(&str); RE(atf_dynstr_init_substr(&str, &src, 0, 5)); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Str 1") == 0); atf_dynstr_fini(&str); RE(atf_dynstr_init_substr(&str, &src, 100, atf_dynstr_npos)); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0); atf_dynstr_fini(&str); RE(atf_dynstr_init_substr(&str, &src, 7, atf_dynstr_npos)); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Str 2") == 0); atf_dynstr_fini(&str); atf_dynstr_fini(&src); }
ATF_TC_BODY(init, tc) { atf_dynstr_t str; RE(atf_dynstr_init(&str)); ATF_REQUIRE_EQ(atf_dynstr_length(&str), 0); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0); atf_dynstr_fini(&str); }
ATF_TC_BODY(clear, tc) { atf_dynstr_t str; printf("Clear an empty string\n"); RE(atf_dynstr_init(&str)); atf_dynstr_clear(&str); ATF_REQUIRE_EQ(atf_dynstr_length(&str), 0); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0); atf_dynstr_fini(&str); printf("Clear a non-empty string\n"); RE(atf_dynstr_init_fmt(&str, "Not empty")); ATF_REQUIRE_EQ(atf_dynstr_length(&str), strlen("Not empty")); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Not empty") == 0); atf_dynstr_clear(&str); ATF_REQUIRE_EQ(atf_dynstr_length(&str), 0); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0); atf_dynstr_fini(&str); }
ATF_TC_BODY(length, tc) { size_t i; for (i = 0; i < 8192; i++) { atf_dynstr_t str; RE(atf_dynstr_init_rep(&str, i, 'a')); ATF_REQUIRE_EQ(atf_dynstr_length(&str), i); atf_dynstr_fini(&str); } }
static void check_line(int fd, const char *exp) { atf_dynstr_t line; atf_dynstr_init(&line); ATF_CHECK(!read_line(fd, &line)); ATF_CHECK_MSG(atf_equal_dynstr_cstring(&line, exp), "read: '%s', expected: '%s'", atf_dynstr_cstring(&line), exp); atf_dynstr_fini(&line); }
ATF_TC_BODY(init_ap, tc) { atf_dynstr_t str; init_fmt(&str, "String 1"); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 1") == 0); atf_dynstr_fini(&str); init_fmt(&str, "String %d", 2); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 2") == 0); atf_dynstr_fini(&str); init_fmt(&str, "%s %d", "String", 3); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 3") == 0); atf_dynstr_fini(&str); init_fmt(&str, "%s%s%s%s%s%s%s", "This ", "should ", "be ", "a ", "large ", "string ", "aaaabbbbccccdddd"); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "This should be a large string " "aaaabbbbccccdddd") == 0); atf_dynstr_fini(&str); }
static void check_append(atf_error_t (*append)(atf_dynstr_t *, const char *, ...)) { const size_t maxlen = 8192; char buf[maxlen + 1]; size_t i; atf_dynstr_t str; printf("Appending with plain string\n"); buf[0] = '\0'; RE(atf_dynstr_init(&str)); for (i = 0; i < maxlen; i++) { if (strcmp(atf_dynstr_cstring(&str), buf) != 0) { fprintf(stderr, "Failed at iteration %zd\n", i); atf_tc_fail("Failed to append character at iteration %zd", i); } RE(append(&str, "a")); strcat(buf, "a"); } atf_dynstr_fini(&str); printf("Appending with formatted string\n"); buf[0] = '\0'; RE(atf_dynstr_init(&str)); for (i = 0; i < maxlen; i++) { if (strcmp(atf_dynstr_cstring(&str), buf) != 0) { fprintf(stderr, "Failed at iteration %zd\n", i); atf_tc_fail("Failed to append character at iteration %zd", i); } RE(append(&str, "%s", "a")); strcat(buf, "a"); } atf_dynstr_fini(&str); }
ATF_TC_BODY(grep_string, tc) { atf_dynstr_t str; atf_dynstr_init_fmt(&str, "a string - aaaabbbb"); ATF_CHECK(grep_string(&str, "a string")); ATF_CHECK(grep_string(&str, "^a string")); ATF_CHECK(grep_string(&str, "aaaabbbb$")); ATF_CHECK(grep_string(&str, "aa.*bb")); ATF_CHECK(!grep_string(&str, "foo")); ATF_CHECK(!grep_string(&str, "bar")); ATF_CHECK(!grep_string(&str, "aaaaa")); atf_dynstr_fini(&str); }
ATF_TC_BODY(rfind_ch, tc) { atf_dynstr_t str; RE(atf_dynstr_init_fmt(&str, "Foo1/Bar2/,.Baz")); ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, '\0'), atf_dynstr_npos); ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, '0'), atf_dynstr_npos); ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, 'b'), atf_dynstr_npos); ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, 'F'), 0); ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, '/'), 9); ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, 'a'), 13); ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, 'z'), 14); atf_dynstr_fini(&str); }
/** Searches for a regexp in a string. * * \param regex The regexp to look for. * \param str The string in which to look for the expression. * \param ... Positional parameters to the regex. * * \return True if there is a match; false otherwise. */ bool atf_utils_grep_string(const char *regex, const char *str, ...) { bool res; va_list ap; atf_dynstr_t formatted; atf_error_t error; va_start(ap, str); error = atf_dynstr_init_ap(&formatted, regex, ap); va_end(ap); ATF_REQUIRE(!atf_is_error(error)); res = grep_string(atf_dynstr_cstring(&formatted), str); atf_dynstr_fini(&formatted); return res; }
bool build_check_c_o(const char *path) { bool success; atf_dynstr_t iflag; const char *optargs[4]; RE(atf_dynstr_init_fmt(&iflag, "-I%s", atf_config_get("atf_includedir"))); optargs[0] = atf_dynstr_cstring(&iflag); optargs[1] = "-Wall"; optargs[2] = "-Werror"; optargs[3] = NULL; RE(atf_check_build_c_o(path, "test.o", optargs, &success)); atf_dynstr_fini(&iflag); return success; }
/** Creates a file. * * \param name Name of the file to create. * \param contents Text to write into the created file. * \param ... Positional parameters to the contents. */ void atf_utils_create_file(const char *name, const char *contents, ...) { va_list ap; atf_dynstr_t formatted; atf_error_t error; va_start(ap, contents); error = atf_dynstr_init_ap(&formatted, contents, ap); va_end(ap); ATF_REQUIRE(!atf_is_error(error)); const int fd = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0644); ATF_REQUIRE_MSG(fd != -1, "Cannot create file %s", name); ATF_REQUIRE(write(fd, atf_dynstr_cstring(&formatted), atf_dynstr_length(&formatted)) != -1); close(fd); atf_dynstr_fini(&formatted); }
static void build_check_c_o_aux(const char *path, const char *failmsg) { bool success; atf_dynstr_t iflag; const char *optargs[2]; RE(atf_dynstr_init_fmt(&iflag, "-I%s", atf_config_get("atf_includedir"))); optargs[0] = atf_dynstr_cstring(&iflag); optargs[1] = NULL; RE(atf_check_build_c_o(path, "test.o", optargs, &success)); atf_dynstr_fini(&iflag); if (!success) atf_tc_fail(failmsg); }
bool build_check_c_o(const char *path) { bool success; atf_dynstr_t iflag; const char *optargs[4]; RE(atf_dynstr_init_fmt(&iflag, "-I%s", atf_env_get_with_default( "ATF_INCLUDEDIR", ATF_INCLUDEDIR))); optargs[0] = atf_dynstr_cstring(&iflag); optargs[1] = "-Wall"; optargs[2] = "-Werror"; optargs[3] = NULL; RE(atf_check_build_c_o(path, "test.o", optargs, &success)); atf_dynstr_fini(&iflag); return success; }
static void capture_stream_fini (void *v) { struct capture_stream *s = v; switch (s->m_base.m_type) { case stdout_type: ATF_CHECK (grep_string (&s->m_msg, "stdout: msg")); ATF_CHECK (!grep_string (&s->m_msg, "stderr: msg")); break; case stderr_type: ATF_CHECK (!grep_string (&s->m_msg, "stdout: msg")); ATF_CHECK (grep_string (&s->m_msg, "stderr: msg")); break; default: UNREACHABLE; } atf_dynstr_fini (&s->m_msg); atf_process_stream_fini (&s->m_base.m_sb); }
ATF_TC_BODY(init_rep, tc) { const size_t maxlen = 8192; char buf[maxlen + 1]; size_t i; buf[0] = '\0'; for (i = 0; i < maxlen; i++) { atf_dynstr_t str; RE(atf_dynstr_init_rep(&str, i, 'a')); if (strcmp(atf_dynstr_cstring(&str), buf) != 0) { fprintf(stderr, "Failed at iteration %zd\n", i); atf_tc_fail("Failed to construct dynstr by repeating %zd " "times the '%c' character", i, 'a'); } atf_dynstr_fini(&str); strcat(buf, "a"); } { atf_dynstr_t str; atf_error_t err; err = atf_dynstr_init_rep(&str, SIZE_MAX, 'a'); ATF_REQUIRE(atf_is_error(err)); ATF_REQUIRE(atf_error_is(err, "no_memory")); atf_error_free(err); err = atf_dynstr_init_rep(&str, SIZE_MAX - 1, 'a'); ATF_REQUIRE(atf_is_error(err)); ATF_REQUIRE(atf_error_is(err, "no_memory")); atf_error_free(err); } }
atf_error_t atf_fs_path_append_ap(atf_fs_path_t *p, const char *fmt, va_list ap) { atf_dynstr_t aux; atf_error_t err; va_list ap2; va_copy(ap2, ap); err = normalize_ap(&aux, fmt, ap2); va_end(ap2); if (!atf_is_error(err)) { const char *auxstr = atf_dynstr_cstring(&aux); const bool needslash = auxstr[0] != '/'; err = atf_dynstr_append_fmt(&p->m_data, "%s%s", needslash ? "/" : "", auxstr); atf_dynstr_fini(&aux); } return err; }
/** Reads a line of arbitrary length. * * \param fd The descriptor from which to read the line. * * \return A pointer to the read line, which must be released with free(), or * NULL if there was nothing to read from the file. */ char * atf_utils_readline(const int fd) { char ch; ssize_t cnt; atf_dynstr_t temp; atf_error_t error; error = atf_dynstr_init(&temp); ATF_REQUIRE(!atf_is_error(error)); while ((cnt = read(fd, &ch, sizeof(ch))) == sizeof(ch) && ch != '\n') { error = atf_dynstr_append_fmt(&temp, "%c", ch); ATF_REQUIRE(!atf_is_error(error)); } ATF_REQUIRE(cnt != -1); if (cnt == 0 && atf_dynstr_length(&temp) == 0) { atf_dynstr_fini(&temp); return NULL; } else return atf_dynstr_fini_disown(&temp); }
void atf_fs_path_fini(atf_fs_path_t *p) { atf_dynstr_fini(&p->m_data); }