diff --git a/configure.ac b/configure.ac index 750a6221af5a06b6365794d81f07d406a19654a2..ac9617efa1a20c381c933b7210b51e3453f0609b 100644 --- a/configure.ac +++ b/configure.ac @@ -20,6 +20,7 @@ PKG_CHECK_MODULES([CHECK], [check >= 0.9.4]) # Checks for header files. AC_CHECK_HEADER([errno.h]) AC_CHECK_HEADER([limits.h]) +AC_CHECK_HEADER([stdbool.h]) AC_CHECK_HEADER([stdio.h]) AC_CHECK_HEADER([stdlib.h]) AC_CHECK_HEADER([string.h]) diff --git a/sefht.geany b/sefht.geany index e0eeea6257c1f4e0d6312755d69baa92a9c5cab4..8bbbe6aa573da23bd117e01aff6e9d8e7b655c30 100644 --- a/sefht.geany +++ b/sefht.geany @@ -28,28 +28,31 @@ long_line_behaviour=1 long_line_column=72 [files] -current_page=16 -FILE_NAME_0=839;Sh;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fconfigure.ac;0;8 -FILE_NAME_1=280;Make;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2FMakefile.am;0;8 -FILE_NAME_2=1023;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fmain.c;0;8 +current_page=9 +FILE_NAME_0=607;Sh;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fconfigure.ac;0;8 +FILE_NAME_1=395;Make;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2FMakefile.am;0;8 +FILE_NAME_2=847;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fmain.c;0;8 FILE_NAME_3=850;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fcms.c;0;8 -FILE_NAME_4=1123;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fcms.h;0;8 -FILE_NAME_5=2615;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fdata.c;0;8 -FILE_NAME_6=993;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fdata.h;0;8 -FILE_NAME_7=1078;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Ffragment.c;0;8 -FILE_NAME_8=1014;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Ffragment.h;0;8 -FILE_NAME_9=902;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Ferror.h;0;4 -FILE_NAME_10=0;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flog.h;0;4 -FILE_NAME_11=847;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fmacro.h;0;8 -FILE_NAME_12=917;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fsefht.h;0;8 -FILE_NAME_13=804;Make;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2FMakefile.am;0;8 -FILE_NAME_14=1253;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_cms.c;0;8 -FILE_NAME_15=3391;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_data.c;0;8 -FILE_NAME_16=1685;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_fragment.c;0;8 -FILE_NAME_17=26;None;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftodo.txt;0;8 +FILE_NAME_4=1148;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fcms.h;0;8 +FILE_NAME_5=1604;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fdata.c;0;8 +FILE_NAME_6=1123;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fdata.h;0;8 +FILE_NAME_7=834;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Ffragment.c;0;8 +FILE_NAME_8=962;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Ffragment.h;0;8 +FILE_NAME_9=3323;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fvalidator.c;0;8 +FILE_NAME_10=1372;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fvalidator.h;0;8 +FILE_NAME_11=902;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Ferror.h;0;4 +FILE_NAME_12=0;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flog.h;0;4 +FILE_NAME_13=869;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fmacro.h;0;8 +FILE_NAME_14=963;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fsefht.h;0;8 +FILE_NAME_15=1000;Make;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2FMakefile.am;0;8 +FILE_NAME_16=1253;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_cms.c;0;8 +FILE_NAME_17=1739;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_data.c;0;8 +FILE_NAME_18=1145;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_fragment.c;0;8 +FILE_NAME_19=4340;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_validator.c;0;8 +FILE_NAME_20=26;None;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftodo.txt;0;8 [VTE] -last_dir=/home/jonathan/Dokumente/projekte/prgm/internet/web/SeFHT/tests +last_dir=/home/jonathan/Dokumente/projekte/prgm/internet/web/SeFHT/src [prjorg] source_patterns=*.c;*.C;*.cpp;*.cxx;*.c++;*.cc;*.m; diff --git a/src/Makefile.am b/src/Makefile.am index 5e5b1c816cbd15d7a1f3009c47d3168e22bed11b..f835d6562e31955f28b37bdef148ba74485d4f58 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,3 +13,4 @@ sefht_fcgi_SOURCES += log.h sefht_fcgi_SOURCES += cms.c cms.h sefht_fcgi_SOURCES += data.c data.h sefht_fcgi_SOURCES += fragment.c fragment.h +sefht_fcgi_SOURCES += validator.c validator.h diff --git a/src/macro.h b/src/macro.h index 29df329f89d31c4171180f02d167498ddd862ee4..844daa805a74ab15b2c89c9bcfc649f7971155f6 100644 --- a/src/macro.h +++ b/src/macro.h @@ -25,4 +25,9 @@ #ifndef _MACRO_H #define _MACRO_H +#include <stdbool.h> + +#define TRUE (bool) 1 +#define FALSE (bool) 0 + #endif /* _MACRO_H */ diff --git a/src/validator.c b/src/validator.c new file mode 100644 index 0000000000000000000000000000000000000000..0c8713b4a58423e9fb9ad6b1fd77f7a5b1d190f0 --- /dev/null +++ b/src/validator.c @@ -0,0 +1,183 @@ +/* + * validator.c + * + * Copyright 2022 Jonathan Schöbel <jonathan@Ubermos-2019> + * + * 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 <errno.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> + +#include "macro.h" +#include "error.h" +#include "log.h" + +#include "validator.h" + + +static inline void init_tags (struct SH_Validator * validator); + +struct SH_Validator * +SH_Validator_new (struct SH_Error * error) +{ + struct SH_Validator * validator; + validator = malloc (sizeof (struct SH_Validator)); + + if (validator == NULL) + { + ERROR ("Memory allocation for SH_Validator failed.\n"); + + if (error != NULL) + { + error->type = ALLOCATION_FAILED; + } + + return NULL; + } + + init_tags (validator); + + if (error != NULL) + { + error->type = SUCCESS; + } + + return validator; +} + +static inline void free_tags (struct SH_Validator * validator); + +void +SH_Validator_free (struct SH_Validator * validator, + struct SH_Error * error) +{ + free_tags (validator); + free (validator); + + if (error != NULL) + { + error->type = SUCCESS; + } + + return; +} + +static inline void +init_tags (struct SH_Validator * validator) +{ + validator->tag_n = 0; + validator->tags = malloc (0); + validator->last_tag = TAG_ERR; + + return; +} + +static inline void +free_tags (struct SH_Validator * validator) +{ + unsigned int index; + + for (index = 0; index < validator->tag_n; index++) + { + free (validator->tags[index].name); + } + + free (validator->tags); + return; +} + +tag_t +SH_Validator_register_tag (struct SH_Validator * validator, + const char * tag, struct SH_Error * error) +{ + /* abort on overflow */ + if (validator->tag_n == UINT_MAX + || validator->last_tag == TAG_MAX) + { + ERROR ("Maximum number of tags reached.\n"); + + if (error != NULL) + { + error->type = DOMAIN_ERROR; + } + + return TAG_ERR; + } + + validator->tags = realloc (validator->tags, + (validator->tag_n + 1) * sizeof (struct SH_Tag)); + + if (errno == ENOMEM) + { + ERROR ("Memory allocation for tag failed.\n"); + + if (error != NULL) + { + error->type = ALLOCATION_FAILED; + } + + return TAG_ERR; + } + + NEXT_TAG(validator->last_tag); + + validator->tags[validator->tag_n].id = validator->last_tag; + validator->tags[validator->tag_n].name = strdup (tag); + + if (errno == ENOMEM) + { + ERROR ("Memory allocation for tag failed.\n"); + + if (error != NULL) + { + error->type = ALLOCATION_FAILED; + } + + return TAG_ERR; + } + + validator->tag_n++; + + if (error != NULL) + { + error->type = SUCCESS; + } + + return validator->last_tag; +} + +bool +SH_Validator_check_tag (struct SH_Validator * validator, + const char * tag) +{ + unsigned int index; + + for (index = 0; index < validator->tag_n; index++) + { + if (strcmp (validator->tags[index].name, tag) == 0) + { + return TRUE; + } + } + + return FALSE; +} diff --git a/src/validator.h b/src/validator.h new file mode 100644 index 0000000000000000000000000000000000000000..f0fd7beca52d4dd695271471c1bf1dfeb547ccc3 --- /dev/null +++ b/src/validator.h @@ -0,0 +1,63 @@ +/* + * validator.h + * + * Copyright 2022 Jonathan Schöbel <jonathan@Ubermos-2019> + * + * 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. + * + * + */ + + +#ifndef _VALIDATOR_H +#define _VALIDATOR_H + +#include <limits.h> +#include <stdbool.h> + + +typedef unsigned int tag_t; +#define TAG_ERR 0 +#define TAG_MIN 1 +#define TAG_MAX UINT_MAX +#define NEXT_TAG(tag) tag++ + +struct SH_Tag +{ + tag_t id; + char * name; +}; + +struct SH_Validator +{ + unsigned int tag_n; + struct SH_Tag * tags; + tag_t last_tag; +}; + +struct SH_Validator * SH_Validator_new (struct SH_Error * error); +void SH_Validator_free (struct SH_Validator * validator, + struct SH_Error * error); + +tag_t SH_Validator_register_tag (struct SH_Validator * validator, + const char * tag, + struct SH_Error * error); + + +bool SH_Validator_check_tag (struct SH_Validator * validator, + const char * tag); + +#endif /* _VALIDATOR_H */ diff --git a/tests/Makefile.am b/tests/Makefile.am index 095ebfe66a29b5005d2602b00b78577054f5841e..a8eb57f7707d3872eefa14b9cbc951b0ab85d21a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -6,6 +6,7 @@ TESTS = TESTS += sefht_cms_test TESTS += sefht_data_test TESTS += sefht_fragment_test +TESTS += sefht_validator_test check_PROGRAMS = $(TESTS) @@ -29,3 +30,8 @@ sefht_fragment_test_SOURCES = test_fragment.c sefht_fragment_test_LDADD = sefht_fragment_test_LDADD += $(top_builddir)/src/fragment.o sefht_fragment_test_LDADD += $(LDADD) + +sefht_validator_test_SOURCES = test_validator.c +sefht_validator_test_LDADD = +sefht_validator_test_LDADD += $(top_builddir)/src/validator.o +sefht_validator_test_LDADD += $(LDADD) diff --git a/tests/test_validator.c b/tests/test_validator.c new file mode 100644 index 0000000000000000000000000000000000000000..8b17f6274411ce7043647a9a387dc11c9393b3cc --- /dev/null +++ b/tests/test_validator.c @@ -0,0 +1,187 @@ +/* + * test_validator.c + * + * Copyright 2022 Jonathan Schöbel <jonathan@Ubermos-2019> + * + * 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 <stdbool.h> +#include <stdlib.h> + +#include "macro.h" +#include "error.h" +#include "validator.h" + + +START_TEST(test_validator) +{ + struct SH_Error error; + struct SH_Validator * validator; + + validator = SH_Validator_new (NULL); + ck_assert_int_ne ((long int) validator, (long int) NULL); + + SH_Validator_free (validator, NULL); + + validator = SH_Validator_new (&error); + ck_assert_int_ne ((long int) validator, (long int) NULL); + ck_assert_int_eq (error.type, SUCCESS); + + SH_Validator_free (validator, &error); + ck_assert_int_eq (error.type, SUCCESS); +} +END_TEST + +START_TEST(test_validator_tag) +{ + struct SH_Error error; + struct SH_Validator * validator; + const char * tag1 = "html"; + const char * tag2 = "head"; + const char * tag3 = "body"; + const char * tag4 = "link"; + const char * tag5 = "main"; + const char * tag6 = "article"; + tag_t tag; + bool check; + + validator = SH_Validator_new (NULL); + + /* success without error */ + tag = SH_Validator_register_tag (validator, tag1, NULL); + ck_assert_int_eq (tag, 1); + + ck_assert_int_eq (validator->tag_n, 1); + ck_assert_int_eq (validator->last_tag, tag); + + ck_assert_int_eq (validator->tags[0].id, tag); + ck_assert_str_eq (validator->tags[0].name, tag1); + + /* fail without error */ + validator->tag_n = UINT_MAX; + + tag = SH_Validator_register_tag (validator, tag2, NULL); + ck_assert_int_eq (tag, TAG_ERR); + + ck_assert_int_eq (validator->tag_n, UINT_MAX); + ck_assert_int_eq (validator->last_tag, 1); + + /* fail2 without error */ + validator->tag_n = 1; + validator->last_tag = TAG_MAX; + + tag = SH_Validator_register_tag (validator, tag3, NULL); + ck_assert_int_eq (tag, TAG_ERR); + + ck_assert_int_eq (validator->tag_n, 1); + ck_assert_int_eq (validator->last_tag, TAG_MAX); + + /* success with error */ + validator->last_tag = 1; + tag = SH_Validator_register_tag (validator, tag4, &error); + ck_assert_int_eq (tag, 2); + ck_assert_int_eq (error.type, SUCCESS); + + ck_assert_int_eq (validator->tag_n, 2); + ck_assert_int_eq (validator->last_tag, tag); + + ck_assert_int_eq (validator->tags[1].id, tag); + ck_assert_str_eq (validator->tags[1].name, tag4); + + /* fail with error */ + validator->tag_n = UINT_MAX; + + tag = SH_Validator_register_tag (validator, tag5, &error); + ck_assert_int_eq (tag, TAG_ERR); + ck_assert_int_eq (error.type, DOMAIN_ERROR); + + ck_assert_int_eq (validator->tag_n, UINT_MAX); + ck_assert_int_eq (validator->last_tag, 2); + + /* fail2 with error */ + validator->tag_n = 2; + validator->last_tag = TAG_MAX; + + tag = SH_Validator_register_tag (validator, tag6, &error); + ck_assert_int_eq (tag, TAG_ERR); + ck_assert_int_eq (error.type, DOMAIN_ERROR); + + ck_assert_int_eq (validator->tag_n, 2); + ck_assert_int_eq (validator->last_tag, TAG_MAX); + + + /* check tag */ + check = SH_Validator_check_tag (validator, tag1); + ck_assert_int_eq (check, TRUE); + + check = SH_Validator_check_tag (validator, tag2); + ck_assert_int_eq (check, FALSE); + + check = SH_Validator_check_tag (validator, tag3); + ck_assert_int_eq (check, FALSE); + + check = SH_Validator_check_tag (validator, tag4); + ck_assert_int_eq (check, TRUE); + + check = SH_Validator_check_tag (validator, tag5); + ck_assert_int_eq (check, FALSE); + + check = SH_Validator_check_tag (validator, tag6); + ck_assert_int_eq (check, FALSE); + + + SH_Validator_free (validator, NULL); +} +END_TEST + +Suite * validator_suite (void) +{ + Suite *s; + TCase *tc_core; + + s = suite_create ("Testsuite SeFHT Validator"); + + /* Core test case */ + tc_core = tcase_create ("Core"); + + tcase_add_test (tc_core, test_validator); + tcase_add_test (tc_core, test_validator_tag); + suite_add_tcase (s, tc_core); + + return s; +} + +int main (int argc, char **argv) +{ + int number_failed; + Suite *s; + SRunner *sr; + + s = validator_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; +} +