From 83cd13f619150de5de6deca71526706623cd6788 Mon Sep 17 00:00:00 2001 From: Sharif Olorin Date: Mon, 18 Jul 2016 06:17:05 +0000 Subject: [PATCH 01/10] Bump mafia --- mafia | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mafia b/mafia index 3a9f823..de5e87f 100755 --- a/mafia +++ b/mafia @@ -118,4 +118,4 @@ case "$MODE" in upgrade) shift; run_upgrade "$@" ;; *) exec_mafia "$@" esac -# Version: dbbe635d8f98be1815130f04465c155f414985bf +# Version: de245376fd86c1ec9a5a451f096cb79bc8ae68f7 From d2d435e7c33b33903e06af7244f825360b8ffeb5 Mon Sep 17 00:00:00 2001 From: Sharif Olorin Date: Mon, 18 Jul 2016 06:18:21 +0000 Subject: [PATCH 02/10] Remove unused 7.8 lockfile --- ambiata-warden.lock-7.8.4 | 144 -------------------------------------- 1 file changed, 144 deletions(-) delete mode 100644 ambiata-warden.lock-7.8.4 diff --git a/ambiata-warden.lock-7.8.4 b/ambiata-warden.lock-7.8.4 deleted file mode 100644 index 17b2e9e..0000000 --- a/ambiata-warden.lock-7.8.4 +++ /dev/null @@ -1,144 +0,0 @@ -# mafia-lock-file-version: 0 -abstract-deque == 0.3 -abstract-par == 0.3.3 -adjunctions == 4.3 -aeson == 0.8.0.2 -aeson +old-locale -aeson-pretty == 0.7.2 -amazonka == 1.4.0 -amazonka-core == 1.4.0 -amazonka-core +old-locale -amazonka-s3 == 1.4.0 -ansi-terminal == 0.6.2.3 -ansi-wl-pprint == 0.6.7.3 -asn1-encoding == 0.9.3 -asn1-parse == 0.9.4 -asn1-types == 0.3.2 -async == 2.0.2 -attoparsec == 0.12.1.6 -base-orphans == 0.5.4 -base16-bytestring == 0.1.1.6 -base64-bytestring == 1.0.0.1 -bifunctors == 4.2.1 -blaze-builder == 0.4.0.2 -blaze-html == 0.8.1.1 -blaze-markup == 0.7.0.3 -byteable == 0.1.1 -case-insensitive == 1.2.0.5 -cassava == 0.4.5.0 -cereal == 0.5.1.0 -cityhash == 0.3.0.1 -cmdargs == 0.10.14 -comonad == 4.2.7.2 -conduit == 1.2.6.4 -conduit-extra == 1.1.11 -connection == 0.2.5 -constraints == 0.4.1.3 -contravariant == 1.4 -cookie == 0.4.1.6 -criterion == 1.1.1.0 -crypto-api == 0.13.2 -cryptohash == 0.11.9 -cryptonite == 0.15 -data-default == 0.6.0 -data-default-class == 0.0.1 -data-default-instances-base == 0.1.0 -data-default-instances-containers == 0.0.1 -data-default-instances-dlist == 0.0.1 -data-default-instances-old-locale == 0.0.1 -deepseq-generics == 0.2.0.0 -directory == 1.2.6.3 -distributive == 0.5.0.2 -dlist == 0.7.1.2 -either == 4.3.4.1 -entropy == 0.3.7 -erf == 2.0.0.0 -exceptions == 0.8.2.1 -foldl == 1.1.6 -free == 4.12.4 -Glob == 0.7.5 -hashable == 1.2.4.0 -hastache == 0.6.1 -hourglass == 0.2.10 -http-client == 0.4.18.1 -http-client-tls == 0.2.4 -http-conduit == 2.1.5.1 -http-types == 0.8.6 -ieee754 == 0.7.8 -ini == 0.3.3 -kan-extensions == 4.2.3 -largeword == 1.2.5 -lens == 4.9.1 -lifted-async == 0.5.0.1 -lifted-base == 0.2.3.6 -math-functions == 0.1.5.2 -memory == 0.12 -mime-types == 0.1.0.6 -mmorph == 1.0.6 -monad-control == 1.0.1.0 -monad-loops == 0.4.3 -monad-par == 0.3.4.7 -monad-par-extras == 0.3.3 -MonadRandom == 0.4.2.2 -mtl == 2.2.1 -mwc-random == 0.13.4.0 -nats == 1.1 -network == 2.6.2.1 -network-info == 0.2.0.8 -network-uri == 2.6.1.0 -newtype == 0.2 -optparse-applicative == 0.11.0.2 -parallel == 3.2.1.0 -parsec == 3.1.9 -pem == 0.2.2 -prelude-extras == 0.4.0.3 -primitive == 0.6.1.0 -process == 1.2.3.0 -profunctors == 4.4.1 -pureMD5 == 2.1.2.1 -pwstore-fast == 2.4.4 -QuickCheck == 2.8.2 -QuickCheck -base4point8 -quickcheck-instances == 0.3.12 -quickcheck-text == 0.1.0.1 -random == 1.1 -reflection == 1.5.2.1 -resourcet == 1.1.7.3 -retry == 0.7.1 -SafeSemaphore == 0.10.1 -scientific == 0.3.4.6 -semigroupoids == 4.0.4 -semigroups == 0.16.2.2 -socks == 0.5.4 -StateVar == 1.1.0.4 -statistics == 0.13.2.3 -stm == 2.4.4.1 -streaming-commons == 0.1.15.2 -syb == 0.4.4 -tagged == 0.8.3 -temporary == 1.2.0.4 -text == 1.2.2.1 -tf-random == 0.5 -tls == 1.3.5 -transformers == 0.4.3.0 -transformers-base == 0.4.4 -transformers-compat == 0.4.0.4 -tz == 0.1.0.1 -tzdata == 0.1.20150810.0 -unix == 2.7.1.0 -unix-bytestring == 0.3.7.3 -unordered-containers == 0.2.7.0 -uuid == 1.3.12 -uuid-types == 1.0.3 -vector == 0.10.12.3 -vector-algorithms == 0.7.0.1 -vector-binary-instances == 0.2.3.1 -vector-th-unbox == 0.2.1.5 -void == 0.7.1 -x509 == 1.6.3 -x509-store == 1.6.1 -x509-system == 1.6.3 -x509-validation == 1.6.3 -xml-conduit == 1.3.4.2 -xml-types == 0.3.6 -zlib == 0.6.1.1 From 0f5bb8d4d669621559f4bb17b79694ad7f3c86c6 Mon Sep 17 00:00:00 2001 From: Sharif Olorin Date: Mon, 18 Jul 2016 07:04:40 +0000 Subject: [PATCH 03/10] Get rid of conditional in is_digit --- cbits/predicates.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/cbits/predicates.h b/cbits/predicates.h index bd7c588..53dc1e5 100644 --- a/cbits/predicates.h +++ b/cbits/predicates.h @@ -4,10 +4,7 @@ #include "warden.h" static inline bool is_digit(char c) { - if (c >= '0' && c <= '9') { - return TRUE; - } - return FALSE; + return (c >= '0' && c <= '9'); } #endif From 6395bd02007a681a99ad768e4e025df6991e7226 Mon Sep 17 00:00:00 2001 From: Sharif Olorin Date: Mon, 18 Jul 2016 07:24:56 +0000 Subject: [PATCH 04/10] Add basic test for date fields --- cbits/field.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ cbits/field.h | 2 ++ 2 files changed, 62 insertions(+) diff --git a/cbits/field.c b/cbits/field.c index 16b4ab7..8e60e78 100644 --- a/cbits/field.c +++ b/cbits/field.c @@ -3,6 +3,8 @@ #include "field.h" #include "predicates.h" +/* Returns TRUE if the buffer we're passed contains a bool, otherwise + * FALSE. */ bool warden_field_bool(char *buf, size_t n) { /* little-endian "false" */ static const int64_t false_bits = 0x00000065736c6166; @@ -114,3 +116,61 @@ numeric_field warden_field_numeric(char *buf, size_t n) { /* just cruft on the end after all */ return non_numeric_field; } + + +static inline bool is_separator(char c) { + return (c == '-' || c == '/' || c == '.'); +} + +/* Match a year in the 20xx century, in big-endian date format with or + without separators. */ +static inline bool match_ymd(const char *buf, size_t n) { + /* The shortest thing we're willing to call a "date" at this + point is YYYYMMDD. */ + if (n < 8) { + return FALSE; + } + + /* 0xc0 = 0x80 | 0x40 - if these bits are set, the byte is too + high to be a digit or a separator. */ + static const int64_t ymd_mask = 0xc0c0c0c0c0c0ffff; + + /* No 0x80 or 0x40 set anywhere, and the first two bytes must + be "20". */ + static const int64_t ymd_bits = 0x0000000000003032; + int64_t *p = (int64_t *) buf; + + /* First, we drop everything which doesn't start with '20' and + have eight bytes compatible with a YYYYxMMxDD format. */ + if (!((*p & ymd_mask) == ymd_bits) && is_digit(buf[2]) && is_digit(buf[3])) { + return FALSE; + } + + /* YYYY-MM-DD */ + if (is_separator(buf[4])) { + return (n >= 10 && + is_digit(buf[5]) && + is_digit(buf[6]) && + is_separator(buf[7]) && + is_digit(buf[8]) && + is_digit(buf[9])); + } + + /* YYYYMMDD */ + return (is_digit(buf[4]) && + is_digit(buf[5]) && + is_digit(buf[6]) && + is_digit(buf[7])); + +} + +/* Returns TRUE if the data in the buffer looks like a date, otherwise + FALSE. + + Currently checks: + + - Fields beginning with big-endian dates. +*/ +bool warden_field_datetime(char *buf, size_t n) { + return match_ymd(buf, n); +} diff --git a/cbits/field.h b/cbits/field.h index ea4e1cb..067cdea 100644 --- a/cbits/field.h +++ b/cbits/field.h @@ -16,4 +16,6 @@ bool warden_field_bool(char *, size_t); numeric_field warden_field_numeric(char *, size_t); +bool warden_field_datetime(char *, size_t); + #endif From bf1a58619fdacc4c43d93cc7b570c57e893e8dee Mon Sep 17 00:00:00 2001 From: Sharif Olorin Date: Mon, 18 Jul 2016 07:41:13 +0000 Subject: [PATCH 05/10] Compile C bits with ALL the warnings --- ambiata-warden.cabal | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/ambiata-warden.cabal b/ambiata-warden.cabal index 1e1e606..099dc15 100644 --- a/ambiata-warden.cabal +++ b/ambiata-warden.cabal @@ -59,8 +59,17 @@ library -Wall cc-options: - -O3 -Wall -Werror - + -O3 + -Wall + -Wextra + -Werror + -Wbad-function-cast + -Wnested-externs + -Wstrict-prototypes + -Wmissing-prototypes + -Wmissing-declarations + -Waggregate-return + hs-source-dirs: src gen From 671cbd36f30b60785b30082eb4252f1c9854a9cf Mon Sep 17 00:00:00 2001 From: Sharif Olorin Date: Mon, 18 Jul 2016 07:41:44 +0000 Subject: [PATCH 06/10] All the warnings except -Wextra Something in the build process generates code which violates the warn-on-unused rule. --- ambiata-warden.cabal | 1 - 1 file changed, 1 deletion(-) diff --git a/ambiata-warden.cabal b/ambiata-warden.cabal index 099dc15..bace835 100644 --- a/ambiata-warden.cabal +++ b/ambiata-warden.cabal @@ -61,7 +61,6 @@ library cc-options: -O3 -Wall - -Wextra -Werror -Wbad-function-cast -Wnested-externs From 86dabc8ffebdf1fd7a8be97ce0c739e13183c0fe Mon Sep 17 00:00:00 2001 From: Sharif Olorin Date: Mon, 18 Jul 2016 07:49:05 +0000 Subject: [PATCH 07/10] Haskell wrapper for date field test --- src/Warden/Parser/Field.hs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/Warden/Parser/Field.hs b/src/Warden/Parser/Field.hs index c3a7b36..8c28dd2 100644 --- a/src/Warden/Parser/Field.hs +++ b/src/Warden/Parser/Field.hs @@ -6,6 +6,7 @@ module Warden.Parser.Field ( checkFieldBool + , checkFieldDate , checkFieldNumeric , integralFieldP , realFieldP @@ -78,3 +79,15 @@ numericFieldP = {-# SCC numericFieldP #-} , (NumericField . fromIntegral) <$> integralFieldP ] {-# INLINE numericFieldP #-} + +checkFieldDate :: ByteString -> Bool +checkFieldDate bs = {-# SCC checkFieldDate #-} + unsafePerformIO $ do + BSU.unsafeUseAsCStringLen bs $ \(bsPtr, bsLen) -> + cBool <$> warden_field_datetime (castPtr bsPtr) (fromIntegral bsLen) +{-# INLINE checkFieldDate #-} + +foreign import ccall unsafe warden_field_datetime + :: Ptr Word8 + -> CSize + -> IO Word8 From 0e83bc4e9c9b2ba2718156c92c3e93d93b44bffc Mon Sep 17 00:00:00 2001 From: Sharif Olorin Date: Mon, 18 Jul 2016 08:08:23 +0000 Subject: [PATCH 08/10] Test and benchmark for date field check --- ambiata-warden.cabal | 8 +++- bench/bench.hs | 17 +++++++- cbits/field.c | 4 +- test/Test/Warden/Arbitrary.hs | 73 +++++++++++++++++++++++++++++++- test/Test/Warden/Parser/Field.hs | 10 +++++ 5 files changed, 107 insertions(+), 5 deletions(-) diff --git a/ambiata-warden.cabal b/ambiata-warden.cabal index bace835..2f9b14b 100644 --- a/ambiata-warden.cabal +++ b/ambiata-warden.cabal @@ -186,8 +186,9 @@ executable warden-gen , resourcet == 1.1.* , semigroups , temporary == 1.2.* - , transformers >= 0.3 && < 5 , text + , time == 1.5.* + , transformers >= 0.3 && < 5 , unix >= 2.7.1 && < 2.7.3 , vector == 0.10.* @@ -223,10 +224,11 @@ test-suite test , filepath == 1.3.* , ieee754 == 0.7.* , lens == 4.9.* - , semigroups , quickcheck-instances == 0.3.* + , semigroups , temporary == 1.2.* , text + , time == 1.5.* , vector == 0.10.* test-suite test-io @@ -273,6 +275,7 @@ test-suite test-io , semigroups , temporary , text == 1.2.* + , time == 1.5.* , transformers >= 0.3 && < 5 , unix >= 2.7.1 && < 2.7.3 , vector == 0.10.* @@ -319,6 +322,7 @@ benchmark bench , semigroups , temporary , text == 1.2.* + , time == 1.5.* , transformers >= 0.3 && < 5 , unix >= 2.7.1 && < 2.7.3 , vector == 0.10.* diff --git a/bench/bench.hs b/bench/bench.hs index 1946b3e..daf6302 100644 --- a/bench/bench.hs +++ b/bench/bench.hs @@ -105,6 +105,12 @@ prepareBools = fmap (fmap T.encodeUtf8) . generate' (Deterministic 555) (GenSize prepareNonBools :: IO [ByteString] prepareNonBools = fmap (fmap T.encodeUtf8) . generate' (Deterministic 666) (GenSize 100) $ vectorOf 100 renderedNonBool +prepareDates :: IO [ByteString] +prepareDates = generate' (Deterministic 555) (GenSize 100) $ vectorOf 100 renderedDate + +prepareNonDates :: IO [ByteString] +prepareNonDates = generate' (Deterministic 666) (GenSize 100) $ vectorOf 100 renderedNonDate + benchABDecode :: FileFormat -> NonEmpty ViewFile -> IO () benchABDecode ff vfs = let sep = Separator . fromIntegral $ ord '|' @@ -150,6 +156,9 @@ benchToRow = toRow . Right benchCheckFieldBool :: [ByteString] -> [Bool] benchCheckFieldBool = fmap checkFieldBool +benchCheckFieldDate :: [ByteString] -> [Bool] +benchCheckFieldDate = fmap checkFieldDate + main :: IO () main = do withTempDirectory "." "warden-bench-" $ \root -> @@ -160,11 +169,17 @@ main = do , bench "decode/delimited-text/1000" $ nfIO (benchABDecode DelimitedText vfs) , bench "decode/toRow/100" $ nf benchToRow bss ] - , env ((,,) <$> prepareRow <*> prepareBools <*> prepareNonBools) $ \ ~(rs, bools, nonbools) -> + , env ((,,,,) <$> prepareRow + <*> prepareBools + <*> prepareNonBools + <*> prepareDates + <*> prepareNonDates) $ \ ~(rs, bools, nonbools, dates, nondates) -> bgroup "field-parsing" $ [ bench "parseField/200" $ nf benchFieldParse rs , bench "checkFieldBool/boolean/100" $ nf benchCheckFieldBool bools , bench "checkFieldBool/non-boolean/100" $ nf benchCheckFieldBool nonbools + , bench "checkFieldDate/date/100" $ nf benchCheckFieldDate dates + , bench "checkFieldDate/non-date/100" $ nf benchCheckFieldDate nondates ] , env prepareFolds $ \ ~(rs, ts, piis, nonPiis, bs100, bs10) -> bgroup "folds" $ [ diff --git a/cbits/field.c b/cbits/field.c index 8e60e78..ff4fd50 100644 --- a/cbits/field.c +++ b/cbits/field.c @@ -142,7 +142,7 @@ static inline bool match_ymd(const char *buf, size_t n) { /* First, we drop everything which doesn't start with '20' and have eight bytes compatible with a YYYYxMMxDD format. */ - if (!((*p & ymd_mask) == ymd_bits) && is_digit(buf[2]) && is_digit(buf[3])) { + if (!(((*p & ymd_mask) == ymd_bits) && is_digit(buf[2]) && is_digit(buf[3]))) { return FALSE; } @@ -170,6 +170,8 @@ static inline bool match_ymd(const char *buf, size_t n) { Currently checks: - Fields beginning with big-endian dates. + + FIXME: more supported date formats */ bool warden_field_datetime(char *buf, size_t n) { return match_ymd(buf, n); diff --git a/test/Test/Warden/Arbitrary.hs b/test/Test/Warden/Arbitrary.hs index 48738c9..bad50e4 100644 --- a/test/Test/Warden/Arbitrary.hs +++ b/test/Test/Warden/Arbitrary.hs @@ -11,12 +11,16 @@ import qualified Data.ByteString.Lazy as BL import Data.Char import Data.Csv import qualified Data.Set as S -import Data.List (nub) +import Data.List ((\\), nub) import qualified Data.List as L import Data.List.NonEmpty (NonEmpty) import qualified Data.List.NonEmpty as NE +import Data.String (String) import qualified Data.Text as T import Data.Text.Encoding (decodeUtf8, decodeUtf8', encodeUtf8) +import Data.Time.Calendar (Day(..)) +import Data.Time.Clock (UTCTime(..), secondsToDiffTime) +import Data.Time.Format (defaultTimeLocale, formatTime) import qualified Data.Vector as V import qualified Data.Vector.Unboxed as VU import Data.Word @@ -36,6 +40,7 @@ import Test.Delorean.Arbitrary () import Test.QuickCheck (Small(..), NonNegative(..)) import Test.QuickCheck (Arbitrary, Gen, elements, choose, listOf, listOf1) import Test.QuickCheck (vectorOf, arbitrary, suchThat, oneof, sized) +import Test.QuickCheck (frequency) import Test.QuickCheck.Instances () import Text.Printf (printf) @@ -792,3 +797,69 @@ instance Arbitrary PIICheckType where pure NoPIIChecks , PIIChecks <$> arbitrary ] + +genSensibleDateTime :: Gen UTCTime +genSensibleDateTime = do + -- sometime this century + days <- ModifiedJulianDay <$> choose (142 * 365, 192 * 365) + secs <- secondsToDiffTime <$> choose (0, 86401) + pure $ UTCTime days secs + +genSillyDateTime :: Gen UTCTime +genSillyDateTime = do + days <- oneof [ + whenIWasALad + , hurdReleaseDate + ] + secs <- secondsToDiffTime <$> choose (0, 86401) + pure $ UTCTime days secs + where + -- Uniform between 0001-01-01 and 1858-11-17 + whenIWasALad = ModifiedJulianDay <$> choose ((- 678575), 0) + + -- Uniform between 4616-10-14 and 2739765-11-19. + hurdReleaseDate = ModifiedJulianDay <$> choose (100000, 100000000) + +renderedDate :: Gen BS.ByteString +renderedDate = renderedDate' genSensibleDateTime + +renderedDate' :: Gen UTCTime -> Gen BS.ByteString +renderedDate' gdt = do + dt <- gdt + render <- frequency [(1, renderDateNoSeparator), (9, renderDateSeparator)] + pure . BSC.pack $ render dt + +renderDateNoSeparator :: Gen (UTCTime -> String) +renderDateNoSeparator = do + tp <- timePart + pure (formatTime defaultTimeLocale ("%Y%m%d" <> tp)) + +renderDateSeparator :: Gen (UTCTime -> String) +renderDateSeparator = do + tp <- timePart + sep <- elements ["-", ".", "/"] + pure (formatTime defaultTimeLocale ((concat ["%Y", sep, "%m", sep, "%d"]) <> tp)) + +timePart :: Gen String +timePart = elements [ + "" + , "%H%M" + , "%H:%M" + , "%H%M%S" + , "%H:%M:%S" + , "T%H:%M:%SZ" + ] + + +renderedNonDate :: Gen BS.ByteString +renderedNonDate = do + x <- fmap BS.pack $ listOf1 noDigits + dt <- renderedDate + oneof [ + pure $ x <> dt + , renderedDate' genSillyDateTime + , encodeUtf8 <$> elements muppets + ] + where + noDigits = + elements $ [0x00..0xff] \\ [0x30..0x39] diff --git a/test/Test/Warden/Parser/Field.hs b/test/Test/Warden/Parser/Field.hs index 92560b4..909dc04 100644 --- a/test/Test/Warden/Parser/Field.hs +++ b/test/Test/Warden/Parser/Field.hs @@ -78,6 +78,16 @@ prop_numericFieldP_neg = forAll (elements muppets) $ \t -> let r = parseOnly numericFieldP $ T.encodeUtf8 t in isLeft r === True +prop_checkFieldDate_pos :: Property +prop_checkFieldDate_pos = forAll renderedDate $ \bs -> + let r = checkFieldDate bs in + r === True + +prop_checkFieldDate_neg :: Property +prop_checkFieldDate_neg = forAll renderedNonDate $ \bs -> + let r = checkFieldDate bs in + r === False + return [] tests :: IO Bool tests = $forAllProperties $ quickCheckWithResult (stdArgs { maxSuccess = 1000 }) From 5e926460e49d8b5661818dc65400bcd5c56923c1 Mon Sep 17 00:00:00 2001 From: Sharif Olorin Date: Tue, 19 Jul 2016 06:43:36 +0000 Subject: [PATCH 09/10] Use const char * for immutable buffers --- cbits/field.c | 6 +++--- cbits/field.h | 6 +++--- cbits/pii.c | 14 +++++++------- cbits/pii.h | 8 ++++---- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/cbits/field.c b/cbits/field.c index ff4fd50..bfe6950 100644 --- a/cbits/field.c +++ b/cbits/field.c @@ -5,7 +5,7 @@ /* Returns TRUE if the buffer we're passed contains a bool, otherwise * FALSE. */ -bool warden_field_bool(char *buf, size_t n) { +bool warden_field_bool(const char *buf, size_t n) { /* little-endian "false" */ static const int64_t false_bits = 0x00000065736c6166; static const int64_t false_mask = 0x000000ffffffffff; @@ -50,7 +50,7 @@ bool warden_field_bool(char *buf, size_t n) { in scientific notation. Otherwise returns non_numeric_field. */ -numeric_field warden_field_numeric(char *buf, size_t n) { +numeric_field warden_field_numeric(const char *buf, size_t n) { size_t i = 0; int preradix_digits = 0; /* digits before the radix point */ int exponent_digits = 0; /* digits in the exponent (scientific notation) */ @@ -173,6 +173,6 @@ static inline bool match_ymd(const char *buf, size_t n) { FIXME: more supported date formats */ -bool warden_field_datetime(char *buf, size_t n) { +bool warden_field_datetime(const char *buf, size_t n) { return match_ymd(buf, n); } diff --git a/cbits/field.h b/cbits/field.h index 067cdea..6169f9a 100644 --- a/cbits/field.h +++ b/cbits/field.h @@ -12,10 +12,10 @@ typedef enum _numeric_field { real_field = 2 } numeric_field; -bool warden_field_bool(char *, size_t); +bool warden_field_bool(const char *, size_t); -numeric_field warden_field_numeric(char *, size_t); +numeric_field warden_field_numeric(const char *, size_t); -bool warden_field_datetime(char *, size_t); +bool warden_field_datetime(const char *, size_t); #endif diff --git a/cbits/pii.c b/cbits/pii.c index 0c6595a..25379d3 100644 --- a/cbits/pii.c +++ b/cbits/pii.c @@ -15,7 +15,7 @@ static inline bool is_number_filler(char c) { Email address checks. */ -bool warden_check_email(char *buf, size_t n) { +bool warden_check_email(const char *buf, size_t n) { size_t i = 1; /* local part */ @@ -69,7 +69,7 @@ bool warden_check_email(char *buf, size_t n) { /* Matches numbers of the form +xxxxxxxxxxx Expects the initial '+' to be removed/already checked. */ -static inline bool check_international_phone(char *buf, size_t n) { +static inline bool check_international_phone(const char *buf, size_t n) { size_t i; int phone_chars = 0; /* We need exactly 11 digits, but don't care if there are @@ -84,7 +84,7 @@ static inline bool check_international_phone(char *buf, size_t n) { return (phone_chars == 11); } -static inline bool check_australian_phone(char *buf, size_t n) { +static inline bool check_australian_phone(const char *buf, size_t n) { size_t i; int phone_chars = 0; /* length already checked, >= 10 */ @@ -112,7 +112,7 @@ static inline bool check_australian_phone(char *buf, size_t n) { return (phone_chars == 8); } -bool warden_check_phone_number(char *buf, size_t n) { +bool warden_check_phone_number(const char *buf, size_t n) { /* Field too short, no point checking it. */ if (n < 10) { return FALSE; @@ -142,7 +142,7 @@ static char *street_types[N_STREET_TYPES] = { "ave" }; -static inline bool check_street_type(char *buf, size_t n) { +static inline bool check_street_type(const char *buf, size_t n) { int i; /* no street types shorter than this */ if (2 > n) { @@ -168,7 +168,7 @@ static inline bool is_alpha(char c) { return FALSE; } -bool warden_check_address(char *buf, size_t n) { +bool warden_check_address(const char *buf, size_t n) { size_t i; if (n < 1) { return FALSE; @@ -217,7 +217,7 @@ bool warden_check_address(char *buf, size_t n) { * after performing some sanity checks on the length. * * https://en.wikipedia.org/wiki/Luhn_algorithm */ -bool warden_check_creditcard(char *buf, size_t n) { +bool warden_check_creditcard(const char *buf, size_t n) { char c; size_t i; int luhn_sum = 0; diff --git a/cbits/pii.h b/cbits/pii.h index e9c553a..a80fcd2 100644 --- a/cbits/pii.h +++ b/cbits/pii.h @@ -5,12 +5,12 @@ #include "warden.h" -bool warden_check_email(char *, size_t); +bool warden_check_email(const char *, size_t); -bool warden_check_phone_number(char *, size_t); +bool warden_check_phone_number(const char *, size_t); -bool warden_check_address(char *, size_t); +bool warden_check_address(const char *, size_t); -bool warden_check_creditcard(char *, size_t); +bool warden_check_creditcard(const char *, size_t); #endif From 5424f22bd27f1007f2d79f80bacd23b1ab37b497 Mon Sep 17 00:00:00 2001 From: Sharif Olorin Date: Tue, 19 Jul 2016 07:20:43 +0000 Subject: [PATCH 10/10] Fail if someone tries to compile us on a big-endian CPU Unlikely as that may be. Have a bunch of LE-specific optimisations in place. --- cbits/warden.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cbits/warden.h b/cbits/warden.h index 37a3203..eb67f3e 100644 --- a/cbits/warden.h +++ b/cbits/warden.h @@ -4,6 +4,12 @@ #include #include +#include + +#if __BYTE_ORDER != __LITTLE_ENDIAN +#error "warden only works on little-endian architectures." +#endif + typedef uint8_t bool; #define TRUE 1