📄 skel-test.c
字号:
static voidput_list_start(svn_stringbuf_t *str, char space, int len){ int i; if (len > 0 && ! skel_is_space(space)) abort(); svn_stringbuf_appendcstr(str, "("); for (i = 0; i < len; i++) svn_stringbuf_appendbytes(str, &space, 1);}/* Append the end of a list to STR, using LEN bytes of the whitespace character SPACE. */static voidput_list_end(svn_stringbuf_t *str, char space, int len){ int i; if (len > 0 && ! skel_is_space(space)) abort(); for (i = 0; i < len; i++) svn_stringbuf_appendbytes(str, &space, 1); svn_stringbuf_appendcstr(str, ")");}/* Return true iff SKEL is a list of length DESIRED_LEN. */static intcheck_list(skel_t *skel, int desired_len){ int len; skel_t *child; if (! (skel && ! skel->is_atom)) return 0; len = 0; for (child = skel->children; child; child = child->next) len++; return len == desired_len;}/* Parse lists. */static svn_error_t *parse_list(const char **msg, svn_boolean_t msg_only, svn_test_opts_t *opts, apr_pool_t *pool){ *msg = "parse lists"; if (msg_only) return SVN_NO_ERROR; { /* Try lists of varying length. */ int list_len; for (list_len = 0; list_len < 30; list_len < 4 ? list_len++ : (list_len *= 3)) { /* Try lists with different separators. */ int sep; for (sep = 0; sep < 256; sep++) if (skel_is_space( (apr_byte_t)sep)) { /* Try lists with different numbers of separator characters between the elements. */ int sep_count; for (sep_count = 0; sep_count < 30; sep_count < 4 ? sep_count++ : (sep_count *= 3)) { /* Try various single-byte implicit-length atoms for elements. */ int atom_byte; for (atom_byte = 0; atom_byte < 256; atom_byte++) if (skel_is_name( (apr_byte_t)atom_byte)) { int i; svn_stringbuf_t *str = get_empty_string(pool); skel_t *skel; skel_t *child; put_list_start(str, (apr_byte_t)sep, sep_count); for (i = 0; i < list_len; i++) put_implicit_length_byte(str, (apr_byte_t)atom_byte, (apr_byte_t)sep); put_list_end(str, (apr_byte_t)sep, sep_count); skel = parse_str(str, pool); if (! check_list(skel, list_len)) return fail(pool, "couldn't parse list"); for (child = skel->children; child; child = child->next) if (! check_implicit_length_byte (child, (apr_byte_t)atom_byte)) return fail(pool, "list was reparsed incorrectly"); } /* Try the atom containing every character that's legal in an implicit-length atom as the element. */ { int i; svn_stringbuf_t *str = get_empty_string(pool); skel_t *skel; skel_t *child; put_list_start(str, (apr_byte_t)sep, sep_count); for (i = 0; i < list_len; i++) put_implicit_length_all_chars(str, (apr_byte_t)sep); put_list_end(str, (apr_byte_t)sep, sep_count); skel = parse_str(str, pool); if (! check_list(skel, list_len)) return fail(pool, "couldn't parse list"); for (child = skel->children; child; child = child->next) if (! check_implicit_length_all_chars(child)) return fail(pool, "couldn't parse list"); } /* Try using every one-byte explicit-length atom as an element. */ for (atom_byte = 0; atom_byte < 256; atom_byte++) { int i; svn_stringbuf_t *str = get_empty_string(pool); skel_t *skel; skel_t *child; char buf[1]; buf[0] = atom_byte; put_list_start(str, (apr_byte_t)sep, sep_count); for (i = 0; i < list_len; i++) put_explicit_length(str, buf, 1, (apr_byte_t)sep); put_list_end(str, (apr_byte_t)sep, sep_count); skel = parse_str(str, pool); if (! check_list(skel, list_len)) return fail(pool, "couldn't parse list"); for (child = skel->children; child; child = child->next) if (! check_explicit_length(child, buf, 1)) return fail(pool, "list was reparsed incorrectly"); } /* Try using an atom containing every character as an element. */ { int i; svn_stringbuf_t *str = get_empty_string(pool); skel_t *skel; skel_t *child; char data[256]; for (i = 0; i < 256; i++) data[i] = i; put_list_start(str, (apr_byte_t)sep, sep_count); for (i = 0; i < list_len; i++) put_explicit_length(str, data, 256, (apr_byte_t)sep); put_list_end(str, (apr_byte_t)sep, sep_count); skel = parse_str(str, pool); if (! check_list(skel, list_len)) return fail(pool, "couldn't parse list"); for (child = skel->children; child; child = child->next) if (! check_explicit_length(child, data, 256)) return fail(pool, "list was re-parsed incorrectly"); } } } } } /* Try to parse some invalid lists. */ { int sep; /* Try different separators. */ for (sep = 0; sep < 256; sep++) if (skel_is_space( (apr_byte_t)sep)) { /* Try lists with different numbers of separator characters between the elements. */ int sep_count; for (sep_count = 0; sep_count < 100; sep_count < 10 ? sep_count++ : (sep_count *= 3)) { svn_stringbuf_t *str; /* A list with only a separator. */ str = get_empty_string(pool); put_list_start(str, (apr_byte_t)sep, sep_count); if (parse_str(str, pool)) return fail(pool, "failed to detect syntax error"); /* A list with only a terminator. */ str = get_empty_string(pool); put_list_end(str, (apr_byte_t)sep, sep_count); if (parse_str(str, pool)) return fail(pool, "failed to detect syntax error"); /* A list containing an invalid element. */ str = get_empty_string(pool); put_list_start(str, (apr_byte_t)sep, sep_count); svn_stringbuf_appendcstr(str, "100 "); put_list_end(str, (apr_byte_t)sep, sep_count); if (parse_str(str, pool)) return fail(pool, "failed to detect invalid element"); } } } return SVN_NO_ERROR;}/* Building interesting skels. *//* Build an atom skel containing the LEN bytes at DATA. */static skel_t *build_atom(apr_size_t len, char *data, apr_pool_t *pool){ char *copy = apr_palloc(pool, len); skel_t *skel = apr_palloc(pool, sizeof(*skel)); memcpy(copy, data, len); skel->is_atom = 1; skel->len = len; skel->data = copy; return skel;}/* Build an empty list skel. */static skel_t *empty(apr_pool_t *pool){ skel_t *skel = apr_palloc(pool, sizeof(*skel)); skel->is_atom = 0; skel->children = 0; return skel;}/* Stick ELEMENT at the beginning of the list skeleton LIST. */static voidadd(skel_t *element, skel_t *list){ element->next = list->children; list->children = element;}/* Return true if the contents of skel A are identical to those of skel B. */static intskel_equal(skel_t *a, skel_t *b){ if (a->is_atom != b->is_atom) return 0; if (a->is_atom) return (a->len == b->len && ! memcmp(a->data, b->data, a->len)); else { skel_t *a_child, *b_child; for (a_child = a->children, b_child = b->children; a_child && b_child; a_child = a_child->next, b_child = b_child->next) if (! skel_equal(a_child, b_child)) return 0; if (a_child || b_child) return 0; } return 1;}/* Unparsing implicit-length atoms. */static svn_error_t *unparse_implicit_length(const char **msg, svn_boolean_t msg_only, svn_test_opts_t *opts, apr_pool_t *pool){ *msg = "unparse implicit-length atoms"; if (msg_only) return SVN_NO_ERROR; /* Unparse and check every single-byte implicit-length atom. */ { int byte; for (byte = 0; byte < 256; byte++) if (skel_is_name( (apr_byte_t)byte)) { svn_stringbuf_t *str = get_empty_string(pool); char buf = (char)byte; skel_t *skel = build_atom(1, &buf, pool); str = svn_fs_base__unparse_skel(skel, pool); if (! (str && str->len == 1 && str->data[0] == (char)byte)) return fail(pool, "incorrectly unparsed single-byte " "implicit-length atom"); } } return SVN_NO_ERROR;}/* Unparse some lists. */static svn_error_t *unparse_list(const char **msg, svn_boolean_t msg_only, svn_test_opts_t *opts, apr_pool_t *pool){ *msg = "unparse lists"; if (msg_only) return SVN_NO_ERROR; /* Make a list of all the single-byte implicit-length atoms. */ { svn_stringbuf_t *str = get_empty_string(pool); int byte; skel_t *list = empty(pool); skel_t *reparsed, *elt; for (byte = 0; byte < 256; byte++) if (skel_is_name( (apr_byte_t)byte)) { char buf = byte; add(build_atom(1, &buf, pool), list); } /* Unparse that, parse it again, and see if we got the same thing back. */ str = svn_fs_base__unparse_skel(list, pool); reparsed = svn_fs_base__parse_skel(str->data, str->len, pool); if (! reparsed || reparsed->is_atom) return fail(pool, "result is syntactically misformed, or not a list"); if (! skel_equal(list, reparsed)) return fail(pool, "unparsing and parsing didn't preserve contents"); elt = reparsed->children; for (byte = 255; byte >= 0; byte--) if (skel_is_name( (apr_byte_t)byte)) { if (! (elt && elt->is_atom && elt->len == 1 && elt->data[0] == byte)) return fail(pool, "bad element"); /* Verify that each element's data falls within the string. */ if (elt->data < str->data || elt->data + elt->len > str->data + str->len) return fail(pool, "bad element"); elt = elt->next; } /* We should have reached the end of the list at this point. */ if (elt) return fail(pool, "list too long"); } /* Make a list of lists. */ { svn_stringbuf_t *str = get_empty_string(pool); skel_t *top = empty(pool); skel_t *reparsed; int i; for (i = 0; i < 10; i++) { skel_t *middle = empty(pool); int j; for (j = 0; j < 10; j++) { char buf[10]; apr_size_t k; int val; /* Make some interesting atom, containing lots of binary characters. */ val = i * 10 + j; for (k = 0; k < sizeof(buf); k++) { buf[k] = val; val += j; } add(build_atom(sizeof(buf), buf, pool), middle); } add(middle, top); } str = svn_fs_base__unparse_skel(top, pool); reparsed = svn_fs_base__parse_skel(str->data, str->len, pool); if (! skel_equal(top, reparsed)) return fail(pool, "failed to reparse list of lists"); } return SVN_NO_ERROR;}/* The test table. */struct svn_test_descriptor_t test_funcs[] = { SVN_TEST_NULL, SVN_TEST_PASS(parse_implicit_length), SVN_TEST_PASS(parse_explicit_length), SVN_TEST_PASS(parse_invalid_atoms), SVN_TEST_PASS(parse_list), SVN_TEST_PASS(unparse_implicit_length), SVN_TEST_PASS(unparse_list), SVN_TEST_NULL };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -