diff --git a/sefht.geany b/sefht.geany index 1960fc8f2f8853c73131d76d4a06f487b3ea3dd5..42ceb560eddcfb324d0358661ff55fafbb91c19e 100644 --- a/sefht.geany +++ b/sefht.geany @@ -28,7 +28,7 @@ long_line_behaviour=1 long_line_column=72 [files] -current_page=53 +current_page=54 FILE_NAME_0=139;None;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2FREADME;0;8 FILE_NAME_1=134;None;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2F.gitignore;0;8 FILE_NAME_2=1737;Sh;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fconfigure.ac;0;8 @@ -64,14 +64,14 @@ FILE_NAME_31=1111;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fp FILE_NAME_32=5802;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator_tag.c;0;8 FILE_NAME_33=1148;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator_tag.h;0;8 FILE_NAME_34=1124;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator_tag_data.h;0;8 -FILE_NAME_35=9882;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator_attr.c;0;8 +FILE_NAME_35=9830;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator_attr.c;0;8 FILE_NAME_36=1627;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator_attr.h;0;8 FILE_NAME_37=1099;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator_attr_data.h;0;8 FILE_NAME_38=924;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fstatus.h;0;8 FILE_NAME_39=18;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Flog.h;0;4 FILE_NAME_40=20;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fmacro.h;0;8 FILE_NAME_41=20;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fsefht.h;0;8 -FILE_NAME_42=3077;Make;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2FMakefile.am;0;8 +FILE_NAME_42=3259;Make;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2FMakefile.am;0;8 FILE_NAME_43=218;Sh;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Fno_test.sh.in;0;8 FILE_NAME_44=23;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_cms.c;0;8 FILE_NAME_45=24;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_data.c;0;8 @@ -83,10 +83,11 @@ FILE_NAME_50=4221;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fp FILE_NAME_51=994;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_text_mark.c;0;8 FILE_NAME_52=2447;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_validator.c;0;8 FILE_NAME_53=3880;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_validator_tag.c;0;8 -FILE_NAME_54=536;None;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftodo.txt;0;8 -FILE_NAME_55=201;YAML;0;EUTF-8;0;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2F.gitlab-ci.yml;0;4 -FILE_NAME_56=71;Sh;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fgitlab-ci%2Fupload.sh.in;0;8 -FILE_NAME_57=806;Sh;0;EUTF-8;0;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fgitlab-ci%2Frelease.sh.in;0;4 +FILE_NAME_54=7652;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_validator_attr.c;0;8 +FILE_NAME_55=536;None;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftodo.txt;0;8 +FILE_NAME_56=201;YAML;0;EUTF-8;0;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2F.gitlab-ci.yml;0;4 +FILE_NAME_57=71;Sh;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fgitlab-ci%2Fupload.sh.in;0;8 +FILE_NAME_58=806;Sh;0;EUTF-8;0;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fgitlab-ci%2Frelease.sh.in;0;4 [VTE] last_dir=/home/jonathan/Documents/projects/prgm/internet/web/SeFHT/tests diff --git a/src/lib/sefht/validator_attr.c b/src/lib/sefht/validator_attr.c index 0041186ef6dc0a9ca0bcf1bb0ae592242fd2e1ae..3cda4e329aa644949284b18400c6f8cb395732d7 100644 --- a/src/lib/sefht/validator_attr.c +++ b/src/lib/sefht/validator_attr.c @@ -441,6 +441,7 @@ SH_Validator_register_attr (struct SH_Validator * validator, attr_id = get_attr_id_by_name (validator, attr, &index); if (attr_id != ATTR_ERR) { + set_success (status); return attr_id; } diff --git a/tests/Makefile.am b/tests/Makefile.am index 0429773fcc4fb4851d1e96b9d4709702c0b8849b..86f7ab58946adb20df1d001c88a01931dbaf8c84 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -21,6 +21,7 @@ check_PROGRAMS += sefht_text_test check_PROGRAMS += sefht_text_mark_test check_PROGRAMS += sefht_validator_test check_PROGRAMS += sefht_validator_tag_test +check_PROGRAMS += sefht_validator_attr_test XFAIL_TESTS = XFAIL_TESTS += sefht_fragment_test @@ -94,3 +95,7 @@ sefht_validator_test_LDADD += $(LDADD) sefht_validator_tag_test_SOURCES = test_validator_tag.c sefht_validator_tag_test_LDADD = sefht_validator_tag_test_LDADD += $(LDADD) + +sefht_validator_attr_test_SOURCES = test_validator_attr.c +sefht_validator_attr_test_LDADD = +sefht_validator_attr_test_LDADD += $(LDADD) diff --git a/tests/test_validator_attr.c b/tests/test_validator_attr.c new file mode 100644 index 0000000000000000000000000000000000000000..5521536f3ec7e63bc5f68d6507f3c8e2f798dc75 --- /dev/null +++ b/tests/test_validator_attr.c @@ -0,0 +1,438 @@ +/* + * test_validator_attr.c + * + * Copyright 2023 Jonathan Schöbel <jonathan@xn--schbel-yxa.info> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + * + */ + + +#include <check.h> +#include <math.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> + + +/* lower SIZE_MAX as we try to reach it */ +#include <limits.h> +#undef SIZE_MAX +#define SIZE_MAX 10 * sizeof (struct attr_info) + +#include "macro.h" +#include "status.h" + + +/* C file is needed, because we want to override SIZE_MAX */ +#include "validator.c" + + +START_TEST(test_validator_no_status) +{ + struct SH_Validator * validator; + + validator = SH_Validator_new (NULL); + ck_assert_ptr_ne (NULL, validator); + + ck_assert_int_eq (0, validator->attr_n); + ck_assert_int_eq (ATTR_ERR, validator->last_attr); + + SH_Validator_free (validator); +} +END_TEST + +START_TEST(test_validator_with_status) +{ + struct SH_Status status; + struct SH_Validator * validator; + + _status_preinit (status); + validator = SH_Validator_new (&status); + ck_assert_ptr_ne (NULL, validator); + ck_assert_int_eq (status.status, SUCCESS); + + ck_assert_int_eq (0, validator->attr_n); + ck_assert_int_eq (ATTR_ERR, validator->last_attr); + + SH_Validator_free (validator); +} +END_TEST + +START_TEST(test_validator_copy_no_status) +{ + struct SH_Validator * validator; + struct SH_Validator * copy; + Attr attr; + + /* setup */ + validator = SH_Validator_new_html5 (NULL); + ck_assert_ptr_ne (NULL, validator); + + attr = SH_Validator_register_attr (validator, "id", NULL); + ck_assert_int_ne (ATTR_ERR, attr); + + attr = SH_Validator_register_attr (validator, "lang", NULL); + ck_assert_int_ne (ATTR_ERR, attr); + + /* test */ + copy = SH_Validator_copy (validator, NULL); + ck_assert_ptr_ne (NULL, copy); + + ck_assert_ptr_ne (NULL, copy->attrs); + ck_assert_ptr_ne (validator->attrs, copy->attrs); + ck_assert_int_eq (validator->attr_n, copy->attr_n); + ck_assert_int_eq (validator->last_attr, copy->last_attr); + + #define TEST_INT(I) ck_assert_int_eq (validator->I, copy->I); + #define TEST_STR(S) ck_assert_ptr_ne (validator->S, copy->S); \ + ck_assert_str_eq (validator->S, copy->S); + + for (size_t index = 0; index < copy->attr_n; index++) + { + TEST_INT(attrs[index].id) + TEST_STR(attrs[index].name) + } + #undef TEST_INT + #undef TEST_STR + + SH_Validator_free (copy); + SH_Validator_free (validator); +} +END_TEST + +START_TEST(test_validator_copy_with_status) +{ + struct SH_Status status; + struct SH_Validator * validator; + struct SH_Validator * copy; + Attr attr; + + /* setup */ + validator = SH_Validator_new_html5 (NULL); + ck_assert_ptr_ne (NULL, validator); + + attr = SH_Validator_register_attr (validator, "id", NULL); + ck_assert_int_ne (ATTR_ERR, attr); + + attr = SH_Validator_register_attr (validator, "lang", NULL); + ck_assert_int_ne (ATTR_ERR, attr); + + /* test */ + _status_preinit (status); + copy = SH_Validator_copy (validator, &status); + ck_assert_ptr_ne (NULL, copy); + ck_assert_int_eq (status.status, SUCCESS); + + ck_assert_ptr_ne (NULL, copy->attrs); + ck_assert_ptr_ne (validator->attrs, copy->attrs); + ck_assert_int_eq (validator->attr_n, copy->attr_n); + ck_assert_int_eq (validator->last_attr, copy->last_attr); + + #define TEST_INT(I) ck_assert_int_eq (validator->I, copy->I); + #define TEST_STR(S) ck_assert_ptr_ne (validator->S, copy->S); \ + ck_assert_str_eq (validator->S, copy->S); + + for (size_t index = 0; index < copy->attr_n; index++) + { + TEST_INT(attrs[index].id) + TEST_STR(attrs[index].name) + } + #undef TEST_INT + #undef TEST_STR + + SH_Validator_free (copy); + SH_Validator_free (validator); +} +END_TEST + +START_TEST(test_validator_register_no_status) +{ + struct SH_Validator * validator; + const char * attr1 = "id"; + const char * attr2 = "class"; + const char * attr3 = "name"; + const char * attr4 = "src"; + const char * attr5 = "content"; + char * attrN; + Tag attr; + Tag attr_; + + /* setup */ + validator = SH_Validator_new_html5 (NULL); + ck_assert_ptr_ne (NULL, validator); + + /* test - register */ + attr = SH_Validator_register_attr (validator, attr1, NULL); + ck_assert_int_eq (1, attr); + + ck_assert_int_eq (validator->attr_n, 1); + ck_assert_int_eq (validator->last_attr, attr); + + ck_assert_int_eq (validator->attrs[0].id, attr); + ck_assert_str_eq (validator->attrs[0].name, attr1); + + /* test - duplicate registration */ + attr_ = SH_Validator_register_attr (validator, attr1, NULL); + ck_assert_int_eq (attr_, attr); + + ck_assert_int_eq (validator->attr_n, 1); + ck_assert_int_eq (validator->last_attr, attr); + + ck_assert_int_eq (validator->attrs[0].id, attr); + ck_assert_str_eq (validator->attrs[0].name, attr1); + + /* test - order */ + attr = SH_Validator_register_attr (validator, attr3, NULL); + ck_assert_int_eq (attr, 2); + + attr = SH_Validator_register_attr (validator, attr4, NULL); + ck_assert_int_eq (attr, 3); + + attr = SH_Validator_register_attr (validator, attr5, NULL); + ck_assert_int_eq (attr, 4); + + ck_assert_int_eq (validator->attr_n, 4); + + ck_assert_str_eq (validator->attrs[0].name, attr5); + ck_assert_str_eq (validator->attrs[1].name, attr1); + ck_assert_str_eq (validator->attrs[2].name, attr3); + ck_assert_str_eq (validator->attrs[3].name, attr4); + + /* test - overflow detection */ + /* make method fail by filling with garbage until + * upper boundary is reached */ + + /* ensure enough space inside string*/ + /* log10 +1 = number length */ + /* +4 "attr" */ + /* +1 '\0' */ + /* = +5 */ + attrN = calloc (((int) floor (log10 ((double) SIZE_MAX))) + 6, + sizeof (char)); + + /* fill with garbage */ + do + { + sprintf (attrN, "attr%zu", validator->attr_n); + } + while (ATTR_ERR != SH_Validator_register_attr (validator, attrN, NULL)); + + free (attrN); + + /* test overflow #1 */ + attr = SH_Validator_register_attr (validator, attr2, NULL); + ck_assert_int_eq (ATTR_ERR, attr); + + ck_assert_int_eq (validator->attr_n, 10); + + /* test overflow #2 */ + validator->attr_n = 1; + validator->last_attr = ATTR_MAX; + + attr = SH_Validator_register_attr (validator, attr2, NULL); + ck_assert_int_eq (ATTR_ERR, attr); + + ck_assert_int_eq (validator->attr_n, 1); + ck_assert_int_eq (validator->last_attr, ATTR_MAX); + + /* cleanup */ + /* also free garbage created for overflow test */ + validator->attr_n = 10; + SH_Validator_free (validator); +} + +START_TEST(test_validator_register_with_status) +{ + struct SH_Status status; + struct SH_Validator * validator; + const char * attr1 = "id"; + const char * attr2 = "class"; + const char * attr3 = "name"; + const char * attr4 = "src"; + const char * attr5 = "content"; + char * attrN; + Tag attr; + Tag attr_; + + /* setup */ + validator = SH_Validator_new_html5 (NULL); + ck_assert_ptr_ne (NULL, validator); + + /* test - register */ + _status_preinit (status); + attr = SH_Validator_register_attr (validator, attr1, &status); + ck_assert_int_eq (1, attr); + ck_assert_int_eq (SUCCESS, status.status); + + ck_assert_int_eq (validator->attr_n, 1); + ck_assert_int_eq (validator->last_attr, attr); + + ck_assert_int_eq (validator->attrs[0].id, attr); + ck_assert_str_eq (validator->attrs[0].name, attr1); + + /* test - duplicate registration */ + _status_preinit (status); + attr_ = SH_Validator_register_attr (validator, attr1, &status); + ck_assert_int_eq (attr_, attr); + ck_assert_int_eq (SUCCESS, status.status); + + ck_assert_int_eq (validator->attr_n, 1); + ck_assert_int_eq (validator->last_attr, attr); + + ck_assert_int_eq (validator->attrs[0].id, attr); + ck_assert_str_eq (validator->attrs[0].name, attr1); + + /* test - order */ + _status_preinit (status); + attr = SH_Validator_register_attr (validator, attr3, &status); + ck_assert_int_eq (attr, 2); + ck_assert_int_eq (status.status, SUCCESS); + + _status_preinit (status); + attr = SH_Validator_register_attr (validator, attr4, &status); + ck_assert_int_eq (attr, 3); + ck_assert_int_eq (status.status, SUCCESS); + + _status_preinit (status); + attr = SH_Validator_register_attr (validator, attr5, &status); + ck_assert_int_eq (attr, 4); + ck_assert_int_eq (status.status, SUCCESS); + + ck_assert_int_eq (validator->attr_n, 4); + + ck_assert_str_eq (validator->attrs[0].name, attr5); + ck_assert_str_eq (validator->attrs[1].name, attr1); + ck_assert_str_eq (validator->attrs[2].name, attr3); + ck_assert_str_eq (validator->attrs[3].name, attr4); + + /* test - overflow detection */ + /* make method fail by filling with garbage until + * upper boundary is reached */ + + /* ensure enough space inside string*/ + /* log10 +1 = number length */ + /* +4 "attr" */ + /* +1 '\0' */ + /* = +5 */ + attrN = calloc (((int) floor (log10 ((double) SIZE_MAX))) + 6, + sizeof (char)); + + /* fill with garbage */ + do + { + sprintf (attrN, "attr%zu", validator->attr_n); + } + while (ATTR_ERR != SH_Validator_register_attr (validator, attrN, NULL)); + + free (attrN); + + /* test overflow #1 */ + _status_preinit (status); + attr = SH_Validator_register_attr (validator, attr2, &status); + ck_assert_int_eq (ATTR_ERR, attr); + ck_assert_int_eq (E_DOMAIN, status.status); + + ck_assert_int_eq (validator->attr_n, 10); + + /* test overflow #2 */ + validator->attr_n = 1; + validator->last_attr = ATTR_MAX; + + _status_preinit (status); + attr = SH_Validator_register_attr (validator, attr2, &status); + ck_assert_int_eq (ATTR_ERR, attr); + ck_assert_int_eq (E_DOMAIN, status.status); + + ck_assert_int_eq (validator->attr_n, 1); + ck_assert_int_eq (validator->last_attr, ATTR_MAX); + + /* cleanup */ + /* also free garbage created for overflow test */ + validator->attr_n = 10; + SH_Validator_free (validator); +} + +START_TEST(test_validator_check) +{ + struct SH_Validator * validator; + const char * attr1 = "id"; + const char * attr2 = "id"; + const char * attr3 = "class"; + Tag attr; + bool result; + + /* setup */ + validator = SH_Validator_new (NULL); + ck_assert_ptr_ne (NULL, validator); + + attr = SH_Validator_register_attr (validator, attr1, NULL); + ck_assert_int_ne (ATTR_ERR, attr); + + /* test */ + result = SH_Validator_check_attr (validator, attr1); + ck_assert_int_eq (TRUE, result); + + result = SH_Validator_check_attr (validator, attr2); + ck_assert_int_eq (TRUE, result); + + result = SH_Validator_check_attr (validator, attr3); + ck_assert_int_eq (FALSE, result); + + /* cleanup */ + SH_Validator_free (validator); +} +END_TEST + +Suite * test_suite (void) +{ + Suite *s; + TCase *tc_core; + + s = suite_create ("Testsuite SeFHT Validator Tag"); + + /* Core test case */ + tc_core = tcase_create ("Core"); + + tcase_add_test (tc_core, test_validator_no_status); + tcase_add_test (tc_core, test_validator_with_status); + tcase_add_test (tc_core, test_validator_copy_no_status); + tcase_add_test (tc_core, test_validator_copy_with_status); + tcase_add_test (tc_core, test_validator_register_no_status); + tcase_add_test (tc_core, test_validator_register_with_status); + tcase_add_test (tc_core, test_validator_check); + suite_add_tcase (s, tc_core); + + return s; +} + +int main (void) +{ + int number_failed; + Suite *s; + SRunner *sr; + + s = test_suite (); + sr = srunner_create (s); + + srunner_run_all (sr, CK_NORMAL); + number_failed = srunner_ntests_failed (sr); + srunner_free (sr); + + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} +