From 662696ce12640ebfa4540d3820244c6e7cc16179 Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Sat, 13 Jan 2024 17:13:45 -0500 Subject: [PATCH] C99 Compliance (#29) This pull request brings Cytoplasm up from C89 to C99, which makes it much more portable across platforms. In particular, this pull request solves a number of issues with 32-bit platforms. Closes #28. Closes #12. Closes #20. Reviewed-on: https://git.telodendria.io/Telodendria/Cytoplasm/pulls/29 --- configure | 94 +++++---- src/Array.c | 20 +- src/Base64.c | 8 +- src/Cron.c | 55 +++--- src/Cytoplasm.c | 20 +- src/Db.c | 51 +++-- src/HashMap.c | 14 +- src/HttpClient.c | 3 +- src/HttpRouter.c | 22 +-- src/HttpServer.c | 30 +-- src/Int64.c | 399 --------------------------------------- src/Json.c | 59 +++--- src/Memory.c | 8 +- src/Queue.c | 18 +- src/Rand.c | 34 ++-- src/Runtime.c | 8 +- src/Sha/Sha1.c | 43 +++-- src/Sha/Sha256.c | 31 ++- src/Str.c | 23 ++- src/Stream.c | 11 +- src/UInt64.c | 265 -------------------------- src/Util.c | 81 +++----- src/include/Array.h | 9 +- src/include/Base64.h | 3 +- src/include/Cron.h | 8 +- src/include/Cytoplasm.h | 29 +-- src/include/Db.h | 9 +- src/include/HashMap.h | 4 +- src/include/HttpRouter.h | 4 +- src/include/HttpServer.h | 3 +- src/include/Int.h | 122 ------------ src/include/Int64.h | 252 ------------------------- src/include/Json.h | 16 +- src/include/Memory.h | 1 + src/include/Queue.h | 7 +- src/include/Rand.h | 8 +- src/include/Str.h | 12 +- src/include/Stream.h | 6 +- src/include/UInt64.h | 252 ------------------------- src/include/Util.h | 9 +- 40 files changed, 384 insertions(+), 1667 deletions(-) delete mode 100644 src/Int64.c delete mode 100644 src/UInt64.c delete mode 100644 src/include/Int.h delete mode 100644 src/include/Int64.h delete mode 100644 src/include/UInt64.h diff --git a/configure b/configure index a9f682b..f962059 100755 --- a/configure +++ b/configure @@ -13,23 +13,44 @@ SRC="src" INCLUDE="src/include" TOOLS="tools" -CFLAGS="-Wall -Wextra -pedantic -std=c89 -O3 -pipe -D_DEFAULT_SOURCE -I${INCLUDE}" -LIBS="-lm -pthread" +# Default compiler flags. These must be supported by all POSIX C compilers. +# "Fancy" compilers that have additional options must be detected and set below. +CFLAGS="-O1 -D_DEFAULT_SOURCE -I${INCLUDE}" +LIBS="-lm -lpthread" +# Default args for all platforms. +SCRIPT_ARGS="--prefix=/usr/local --lib-name=Cytoplasm" -# Set default args for all platforms -SCRIPT_ARGS="--cc=cc --prefix=/usr/local --enable-ld-extra --lib-name=Cytoplasm --lib-version=0.4.1 $@" - -# Set platform specific args +# Set SSL flags depending on the platform. case "$(uname)" in OpenBSD) - SCRIPT_ARGS="--with-libressl $SCRIPT_ARGS" + SCRIPT_ARGS="${SCRIPT_ARGS} --with-libressl" ;; *) - SCRIPT_ARGS="--with-openssl $SCRIPT_ARGS" + SCRIPT_ARGS="${SCRIPT_ARGS} --with-openssl" ;; esac +# Set compiler depending on the platform. +case "$(uname)" in + Linux|NetBSD) + # These systems typically use GCC. + SCRIPT_ARGS="${SCRIPT_ARGS} --cc=gcc" + ;; + OpenBSD|FreeBSD) + # These systems typically use Clang. + SCRIPT_ARGS="${SCRIPT_ARGS} --cc=clang" + ;; + *) + # Use default compiler which is required to be present on + # all POSIX-compliant systems. + SCRIPT_ARGS="${SCRIPT_ARGS} --cc=c99" + ;; +esac + +# Append any additional args specified by user +SCRIPT_ARGS="${SCRIPT_ARGS} $@" + echo "Processing options..." echo "Ran with arguments: $SCRIPT_ARGS" @@ -38,6 +59,14 @@ for arg in $SCRIPT_ARGS; do case "$arg" in --cc=*) CC=$(echo "$arg" | cut -d '=' -f 2-) + case "${CC}" in + gcc*|clang*) + # "Fancy" compilers that support a plethora of additional flags we + # want to enable if present. + CFLAGS="-Wall -Werror -pedantic -std=c99 ${CFLAGS}" + LDFLAGS="-flto -fdata-sections -ffunction-sections -s -Wl,-gc-sections" + ;; + esac ;; --with-openssl) TLS_IMPL="TLS_OPENSSL" @@ -54,35 +83,15 @@ for arg in $SCRIPT_ARGS; do --prefix=*) PREFIX=$(echo "$arg" | cut -d '=' -f 2-) ;; - --enable-ld-extra) - LD_EXTRA="-flto -fdata-sections -ffunction-sections -s -Wl,-gc-sections" - ;; - --disable-ld-extra) - LD_EXTRA="" - ;; --lib-name=*) LIB_NAME=$(echo "$arg" | cut -d '=' -f 2-) ;; - --lib-version=*) - LIB_VERSION=$(echo "$arg" | cut -d '=' -f 2-) - ;; --enable-debug) DEBUG="-O0 -g" - echo "Notice: --enable-debug implies --disable-ld-extra and --no-static." - echo "You must explicitly provide --enable-ld-extra and/or --static after" - echo "specifying --enable-debug if you wish to enable these features in debug mode." - LD_EXTRA="" - STATIC="" ;; --disable-debug) DEBUG="" ;; - --static) - STATIC="-static -Wl,-static" - ;; - --no-static) - STATIC="" - ;; *) echo "Invalid argument: $arg" exit 1 @@ -95,8 +104,8 @@ if [ -n "$TLS_IMPL" ]; then LIBS="${LIBS} ${TLS_LIBS}" fi -CFLAGS="${CFLAGS} '-DLIB_NAME=\"${LIB_NAME}\"' '-DLIB_VERSION=\"${LIB_VERSION}\"' ${DEBUG}" -LDFLAGS="${LIBS} ${LD_EXTRA}" +CFLAGS="${CFLAGS} '-DLIB_NAME=\"${LIB_NAME}\"' ${DEBUG}" +LDFLAGS="${LIBS} ${LDFLAGS}" # # Makefile generation @@ -128,11 +137,27 @@ print_obj() { printf '%s ' "$2" } +get_deps() { + src="$1" + + ${CC} -I${INCLUDE} -E "$src" \ + | grep '^#' \ + | awk '{print $3}' \ + | cut -d '"' -f 2 \ + | sort \ + | uniq \ + | grep -v '^[/<]' \ + | grep "^${SRC}/" \ + | while IFS= read -r dep; do + printf "%s " "$dep" + done +} + compile_obj() { src="$1" obj="$2" - ${CC} -I${INCLUDE} -MM -MT "${obj}" "${src}" + echo "${obj}: $(get_deps ${src})" echo "${TAB}@mkdir -p $(dirname ${obj})" echo "${TAB}\$(CC) \$(CFLAGS) -fPIC -c -o \"${obj}\" \"${src}\"" } @@ -143,16 +168,13 @@ compile_bin() { echo "${out}: ${OUT}/lib/lib${LIB_NAME}.a ${OUT}/lib/lib${LIB_NAME}.so ${src}" echo "${TAB}@mkdir -p ${OUT}/bin" - echo "${TAB}\$(CC) \$(CFLAGS) -o \"${out}\" \"${src}\" -L${OUT}/lib \$(LDFLAGS) -l${LIB_NAME} ${STATIC}" + echo "${TAB}\$(CC) \$(CFLAGS) -o \"${out}\" \"${src}\" -L${OUT}/lib \$(LDFLAGS) -l${LIB_NAME}" } compile_doc() { src="$1" out="$2" - - if [ -z "${STATIC}" ]; then - pref="LD_LIBRARY_PATH=${OUT}/lib " - fi + pref="LD_LIBRARY_PATH=${OUT}/lib " echo "${out}: ${OUT}/bin/hdoc ${src}" echo "${TAB}@mkdir -p ${OUT}/man/man3" diff --git a/src/Array.c b/src/Array.c index 911258e..d16db3f 100644 --- a/src/Array.c +++ b/src/Array.c @@ -38,12 +38,12 @@ struct Array size_t size; /* Elements actually filled */ }; -int +bool ArrayAdd(Array * array, void *value) { if (!array) { - return 0; + return false; } return ArrayInsert(array, array->size, value); @@ -122,14 +122,14 @@ ArrayGet(Array * array, size_t index) } -extern int +bool ArrayInsert(Array * array, size_t index, void *value) { size_t i; if (!array || !value || index > array->size) { - return 0; + return false; } if (array->size >= array->allocated) @@ -145,7 +145,7 @@ ArrayInsert(Array * array, size_t index, void *value) if (!array->entries) { array->entries = tmp; - return 0; + return false; } array->allocated = newSize; @@ -160,7 +160,7 @@ ArrayInsert(Array * array, size_t index, void *value) array->entries[index] = value; - return 1; + return true; } extern void * @@ -200,14 +200,14 @@ ArraySize(Array * array) return array->size; } -int +bool ArrayTrim(Array * array) { void **tmp; if (!array) { - return 0; + return false; } tmp = array->entries; @@ -218,10 +218,10 @@ ArrayTrim(Array * array) if (!array->entries) { array->entries = tmp; - return 0; + return false; } - return 1; + return true; } static void diff --git a/src/Base64.c b/src/Base64.c index fc43be8..ec81935 100644 --- a/src/Base64.c +++ b/src/Base64.c @@ -212,7 +212,7 @@ Base64Unpad(char *base64, size_t length) base64[length] = '\0'; } -extern int +bool Base64Pad(char **base64Ptr, size_t length) { char *tmp; @@ -221,7 +221,7 @@ Base64Pad(char **base64Ptr, size_t length) if (length % 4 == 0) { - return length; /* Success: no padding needed */ + return true; /* Success: no padding needed */ } newSize = length + (4 - (length % 4)); @@ -229,7 +229,7 @@ Base64Pad(char **base64Ptr, size_t length) tmp = Realloc(*base64Ptr, newSize + 100);; if (!tmp) { - return 0; /* Memory error */ + return false; /* Memory error */ } *base64Ptr = tmp; @@ -240,5 +240,5 @@ Base64Pad(char **base64Ptr, size_t length) (*base64Ptr)[newSize] = '\0'; - return newSize; + return true; } diff --git a/src/Cron.c b/src/Cron.c index df82b70..dd820ba 100644 --- a/src/Cron.c +++ b/src/Cron.c @@ -23,32 +23,33 @@ */ #include -#include #include #include #include +#include + #include struct Cron { - UInt64 tick; + uint64_t tick; Array *jobs; pthread_mutex_t lock; - volatile unsigned int stop:1; pthread_t thread; + volatile bool stop; }; typedef struct Job { - UInt64 interval; - UInt64 lastExec; + uint64_t interval; + uint64_t lastExec; JobFunc *func; void *args; } Job; static Job * -JobCreate(UInt32 interval, JobFunc * func, void *args) +JobCreate(uint64_t interval, JobFunc * func, void *args) { Job *job; @@ -63,8 +64,8 @@ JobCreate(UInt32 interval, JobFunc * func, void *args) return NULL; } - job->interval = UInt64Create(0, interval); - job->lastExec = UInt64Create(0, 0); + job->interval = interval; + job->lastExec = 0; job->func = func; job->args = args; @@ -79,51 +80,51 @@ CronThread(void *args) while (!cron->stop) { size_t i; - UInt64 ts; /* tick start */ - UInt64 te; /* tick end */ + uint64_t ts; /* tick start */ + uint64_t te; /* tick end */ pthread_mutex_lock(&cron->lock); - ts = UtilServerTs(); + ts = UtilTsMillis(); for (i = 0; i < ArraySize(cron->jobs); i++) { Job *job = ArrayGet(cron->jobs, i); - if (UInt64Gt(UInt64Sub(ts, job->lastExec), job->interval)) + if ((ts - job->lastExec) > job->interval) { job->func(job->args); job->lastExec = ts; } - if (UInt64Eq(job->interval, UInt64Create(0, 0))) + if (!job->interval) { ArrayDelete(cron->jobs, i); Free(job); } } - te = UtilServerTs(); + te = UtilTsMillis(); pthread_mutex_unlock(&cron->lock); - /* Only sleep if the jobs didn't overrun the tick */ - if (UInt64Gt(cron->tick, UInt64Sub(te, ts))) + // Only sleep if the jobs didn't overrun the tick + if (cron->tick > (te - ts)) { - const UInt64 microTick = UInt64Create(0, 100); + const uint64_t microTick = 100; - UInt64 remainingTick = UInt64Sub(cron->tick, UInt64Sub(te, ts)); + uint64_t remainingTick = cron->tick - (te - ts); /* Only sleep for microTick ms at a time because if the job * scheduler is supposed to stop before the tick is up, we * don't want to be stuck in a long sleep */ - while (UInt64Geq(remainingTick, microTick) && !cron->stop) + while (remainingTick >= microTick && !cron->stop) { UtilSleepMillis(microTick); - remainingTick = UInt64Sub(remainingTick, microTick); + remainingTick -= microTick; } - if (UInt64Neq(remainingTick, UInt64Create(0, 0)) && !cron->stop) + if (remainingTick && !cron->stop) { UtilSleepMillis(remainingTick); } @@ -134,7 +135,7 @@ CronThread(void *args) } Cron * -CronCreate(UInt32 tick) +CronCreate(uint64_t tick) { Cron *cron = Malloc(sizeof(Cron)); @@ -150,8 +151,8 @@ CronCreate(UInt32 tick) return NULL; } - cron->tick = UInt64Create(0, tick); - cron->stop = 1; + cron->tick = tick; + cron->stop = true; pthread_mutex_init(&cron->lock, NULL); @@ -180,7 +181,7 @@ CronOnce(Cron * cron, JobFunc * func, void *args) } void -CronEvery(Cron * cron, unsigned long interval, JobFunc * func, void *args) +CronEvery(Cron * cron, uint64_t interval, JobFunc * func, void *args) { Job *job; @@ -208,7 +209,7 @@ CronStart(Cron * cron) return; } - cron->stop = 0; + cron->stop = false; pthread_create(&cron->thread, NULL, CronThread, cron); } @@ -221,7 +222,7 @@ CronStop(Cron * cron) return; } - cron->stop = 1; + cron->stop = true; pthread_join(cron->thread, NULL); } diff --git a/src/Cytoplasm.c b/src/Cytoplasm.c index 43ff294..8c435c4 100644 --- a/src/Cytoplasm.c +++ b/src/Cytoplasm.c @@ -24,12 +24,22 @@ #include -char *CytoplasmGetName() +int +CytoplasmGetVersion(void) { - return LIB_NAME; + return CYTOPLASM_VERSION; } -char *CytoplasmGetVersion() +const char * +CytoplasmGetVersionStr(void) { - return LIB_VERSION; -} \ No newline at end of file + return "v" STRINGIFY(CYTOPLASM_VERSION_MAJOR) + "." STRINGIFY(CYTOPLASM_VERSION_MINOR) + "." STRINGIFY(CYTOPLASM_VERSION_PATCH) +#if CYTOPLASM_VERSION_ALPHA + "-alpha" STRINGIFY(CYTOPLASM_VERSION_ALPHA) +#elif CYTOPLASM_VERSION_BETA + "-beta" STRINGIFY(CYTOPLASM_VERSION_BETA) +#endif + ; +} diff --git a/src/Db.c b/src/Db.c index 41b329f..4d2983a 100644 --- a/src/Db.c +++ b/src/Db.c @@ -23,7 +23,6 @@ */ #include -#include #include #include #include @@ -77,7 +76,7 @@ struct DbRef { HashMap *json; - UInt64 ts; + uint64_t ts; size_t size; Array *name; @@ -495,12 +494,12 @@ DbLockFromArr(Db * db, Array * args) if (ref) /* In cache */ { - UInt64 diskTs = UtilLastModified(file); + uint64_t diskTs = UtilLastModified(file); ref->fd = fd; ref->stream = stream; - if (UInt64Gt(diskTs, ref->ts)) + if (diskTs > ref->ts) { /* File was modified on disk since it was cached */ HashMap *json = JsonDecode(ref->stream); @@ -588,7 +587,7 @@ DbLockFromArr(Db * db, Array * args) if (db->cache) { - ref->ts = UtilServerTs(); + ref->ts = UtilTsMillis(); ref->size = DbComputeSize(ref->json); HashMapSet(db->cache, hash, ref); db->cacheSize += ref->size; @@ -652,7 +651,7 @@ DbCreate(Db * db, size_t nArgs,...) file = DbFileName(db, args); - if (UInt64Neq(UtilLastModified(file), UInt64Create(0, 0))) + if (UtilLastModified(file)) { Free(file); ArrayFree(args); @@ -694,19 +693,19 @@ DbCreate(Db * db, size_t nArgs,...) return ret; } -int +bool DbDelete(Db * db, size_t nArgs,...) { va_list ap; Array *args; char *file; char *hash; - int ret = 1; + bool ret = true; DbRef *ref; if (!db) { - return 0; + return false; } va_start(ap, nArgs); @@ -755,9 +754,9 @@ DbDelete(Db * db, size_t nArgs,...) Free(hash); - if (UInt64Neq(UtilLastModified(file), UInt64Create(0, 0))) + if (UtilLastModified(file)) { - ret = remove(file) == 0; + ret = (remove(file) == 0); } pthread_mutex_unlock(&db->lock); @@ -790,14 +789,14 @@ DbLock(Db * db, size_t nArgs,...) return ret; } -int +bool DbUnlock(Db * db, DbRef * ref) { - int destroy; + bool destroy; if (!db || !ref) { - return 0; + return false; } lseek(ref->fd, 0L, SEEK_SET); @@ -806,7 +805,7 @@ DbUnlock(Db * db, DbRef * ref) pthread_mutex_unlock(&db->lock); Log(LOG_ERR, "Failed to truncate file on disk."); Log(LOG_ERR, "Error on fd %d: %s", ref->fd, strerror(errno)); - return 0; + return false; } JsonEncode(ref->json, ref->stream, JSON_DEFAULT); @@ -827,18 +826,18 @@ DbUnlock(Db * db, DbRef * ref) * require some items to be evicted. */ DbCacheEvict(db); - destroy = 0; + destroy = false; } else { - destroy = 1; + destroy = true; } Free(key); } else { - destroy = 1; + destroy = true; } if (destroy) @@ -850,16 +849,16 @@ DbUnlock(Db * db, DbRef * ref) } pthread_mutex_unlock(&db->lock); - return 1; + return true; } -int +bool DbExists(Db * db, size_t nArgs,...) { va_list ap; Array *args; char *file; - int ret; + bool ret; va_start(ap, nArgs); args = ArrayFromVarArgs(nArgs, ap); @@ -867,13 +866,13 @@ DbExists(Db * db, size_t nArgs,...) if (!args) { - return 0; + return false; } pthread_mutex_lock(&db->lock); file = DbFileName(db, args); - ret = UInt64Neq(UtilLastModified(file), UInt64Create(0, 0)); + ret = (UtilLastModified(file) != 0); pthread_mutex_unlock(&db->lock); @@ -955,15 +954,15 @@ DbJson(DbRef * ref) return ref ? ref->json : NULL; } -int +bool DbJsonSet(DbRef * ref, HashMap * json) { if (!ref || !json) { - return 0; + return false; } JsonFree(ref->json); ref->json = JsonDuplicate(json); - return 1; + return true; } diff --git a/src/HashMap.c b/src/HashMap.c index 424939b..d158b3f 100644 --- a/src/HashMap.c +++ b/src/HashMap.c @@ -247,12 +247,12 @@ HashMapGet(HashMap * map, const char *key) return NULL; } -int +bool HashMapIterateReentrant(HashMap * map, char **key, void **value, size_t * i) { if (!map) { - return 0; + return false; } if (*i >= map->capacity) @@ -260,7 +260,7 @@ HashMapIterateReentrant(HashMap * map, char **key, void **value, size_t * i) *i = 0; *key = NULL; *value = NULL; - return 0; + return false; } while (*i < map->capacity) @@ -273,20 +273,20 @@ HashMapIterateReentrant(HashMap * map, char **key, void **value, size_t * i) { *key = bucket->key; *value = bucket->value; - return 1; + return true; } } *i = 0; - return 0; + return false; } -int +bool HashMapIterate(HashMap * map, char **key, void **value) { if (!map) { - return 0; + return false; } else { diff --git a/src/HttpClient.c b/src/HttpClient.c index 142ac81..88d7179 100644 --- a/src/HttpClient.c +++ b/src/HttpClient.c @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -154,7 +155,7 @@ HttpRequest(HttpRequestMethod method, int flags, unsigned short port, char *host HttpRequestMethodToString(method), path); HttpRequestHeader(context, "Connection", "close"); - HttpRequestHeader(context, "User-Agent", LIB_NAME "/" LIB_VERSION); + HttpRequestHeader(context, "User-Agent", LIB_NAME "/" STRINGIFY(CYTOPLASM_VERSION)); HttpRequestHeader(context, "Host", host); return context; diff --git a/src/HttpRouter.c b/src/HttpRouter.c index 02e6213..7777fcd 100644 --- a/src/HttpRouter.c +++ b/src/HttpRouter.c @@ -143,7 +143,7 @@ HttpRouterFree(HttpRouter * router) Free(router); } -int +bool HttpRouterAdd(HttpRouter * router, char *regPath, HttpRouteFunc * exec) { RouteNode *node; @@ -152,19 +152,19 @@ HttpRouterAdd(HttpRouter * router, char *regPath, HttpRouteFunc * exec) if (!router || !regPath || !exec) { - return 0; + return false; } if (StrEquals(regPath, "/")) { router->root->exec = exec; - return 1; + return true; } regPath = StrDuplicate(regPath); if (!regPath) { - return 0; + return false; } tmp = regPath; @@ -187,10 +187,10 @@ HttpRouterAdd(HttpRouter * router, char *regPath, HttpRouteFunc * exec) Free(regPath); - return 1; + return true; } -int +bool HttpRouterRoute(HttpRouter * router, char *path, void *args, void **ret) { RouteNode *node; @@ -199,17 +199,17 @@ HttpRouterRoute(HttpRouter * router, char *path, void *args, void **ret) HttpRouteFunc *exec = NULL; Array *matches = NULL; size_t i; - int retval; + bool retval; if (!router || !path) { - return 0; + return false; } matches = ArrayCreate(); if (!matches) { - return 0; + return false; } node = router->root; @@ -280,7 +280,7 @@ HttpRouterRoute(HttpRouter * router, char *path, void *args, void **ret) if (!exec) { - retval = 0; + retval = false; goto finish; } @@ -293,7 +293,7 @@ HttpRouterRoute(HttpRouter * router, char *path, void *args, void **ret) exec(matches, args); } - retval = 1; + retval = true; finish: for (i = 0; i < ArraySize(matches); i++) diff --git a/src/HttpServer.c b/src/HttpServer.c index 0740e4b..b2a9535 100644 --- a/src/HttpServer.c +++ b/src/HttpServer.c @@ -465,7 +465,7 @@ HttpServerWorkerThread(void *args) ssize_t i = 0; HttpRequestMethod requestMethod; - UInt64 firstRead; + uint64_t firstRead; fp = DequeueConnection(server); @@ -473,7 +473,7 @@ HttpServerWorkerThread(void *args) { /* Block for 1 millisecond before continuing so we don't * murder the CPU if the queue is empty. */ - UtilSleepMillis(UInt64Create(0, 1)); + UtilSleepMillis(1); continue; } @@ -483,21 +483,25 @@ HttpServerWorkerThread(void *args) * happens, UtilGetLine() sets errno to EAGAIN. If we get * EAGAIN, then clear the error on the stream and try again * after a few ms. This is typically more than enough time for - * the client to send data. */ - firstRead = UtilServerTs(); + * the client to send data. + * + * TODO: Instead of looping, abort immediately, and place the request + * at the end of the queue. + */ + firstRead = UtilTsMillis(); while ((lineLen = UtilGetLine(&line, &lineSize, fp)) == -1 && errno == EAGAIN) { StreamClearError(fp); - /* If the server is stopped, or it's been a while, just - * give up so we aren't wasting a thread on this client. */ - if (server->stop || UInt64Gt(UInt64Sub(UtilServerTs(), firstRead), UInt64Create(0, 1000 * 30))) + // If the server is stopped, or it's been a while, just + // give up so we aren't wasting a thread on this client. + if (server->stop || (UtilTsMillis() - firstRead) > (1000 * 30)) { goto finish; } - UtilSleepMillis(UInt64Create(0, 5)); + UtilSleepMillis(5); } if (lineLen == -1) @@ -711,25 +715,25 @@ HttpServerEventThread(void *args) return NULL; } -int +bool HttpServerStart(HttpServer * server) { if (!server) { - return 0; + return false; } if (server->isRunning) { - return 1; + return true; } if (pthread_create(&server->socketThread, NULL, HttpServerEventThread, server) != 0) { - return 0; + return false; } - return 1; + return true; } void diff --git a/src/Int64.c b/src/Int64.c deleted file mode 100644 index 21f07f5..0000000 --- a/src/Int64.c +++ /dev/null @@ -1,399 +0,0 @@ -/* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include - -#include -#include - -#include - -#ifdef INT64_NATIVE -#define Int64Sign(x) ((int) (((UInt64) (x)) >> 63)) -#else -#define Int64Sign(x) ((int) ((x).i[1] >> 31)) -#endif - -size_t -Int64Str(Int64 x, int base, char *out, size_t len) -{ - static const char symbols[] = "0123456789ABCDEF"; - - size_t i = len - 1; - size_t j = 0; - - int neg = Int64Sign(x); - - Int64 base64 = Int64Create(0, base); - - /* We only have symbols up to base 16 */ - if (base < 2 || base > 16) - { - return 0; - } - - /* - * This algorithm doesn't work on INT64_MIN. - * - * But it works on all other integers in the range, so we - * just scoot the range in by one for now. It's a hack and - * I'm not a huge fan of it, but this function is mostly - * used in Json, which shouldn't have a range this large - * anyway (Json is limited to -2^53 -> 2^53-1). - * - * Proper fixes are always welcome. - */ - if (Int64Eq(x, Int64Create(0x80000000, 0x00000000))) - { - x = Int64Add(x, Int64Create(0, 1)); - } -#if 0 - else if (Int64Eq(x, Int64Create(0x7FFFFFFF, 0xFFFFFFFF))) - { - x = Int64Sub(x, Int64Create(0, 1)); - } -#endif - - if (base != 2 && base != 8 && base != 16 && neg) - { - x = Int64Neg(x); - } - - do - { - Int64 mod = Int64Rem(x, base64); - Int32 low = Int64Low(mod); - - out[i] = symbols[low]; - i--; - x = Int64Div(x, base64); - } while (Int64Gt(x, Int64Create(0, 0))); - - if (base != 2 && base != 8 && base != 16) - { - /* - * Binary, octal, and hexadecimal are known to - * be bit representations. Everything else (notably - * decimal) should include the negative sign. - */ - if (neg) - { - out[i] = '-'; - i--; - } - } - - while (++i < len) - { - out[j++] = out[i]; - } - - out[j] = '\0'; - - return j; -} - -#ifndef INT64_NATIVE - -/* No native 64-bit support, add our own */ - -Int64 -Int64Create(UInt32 high, UInt32 low) -{ - Int64 x; - - x.i[0] = low; - x.i[1] = high; - - return x; -} - -Int64 -Int64Add(Int64 x, Int64 y) -{ - Int64 z = Int64Create(0, 0); - int carry; - - z.i[0] = x.i[0] + y.i[0]; - carry = z.i[0] < x.i[0]; - z.i[1] = x.i[1] + y.i[1] + carry; - - return z; -} - -Int64 -Int64Sub(Int64 x, Int64 y) -{ - return Int64Add(x, Int64Neg(y)); -} - -Int64 -Int64Mul(Int64 x, Int64 y) -{ - Int64 z = Int64Create(0, 0); - - int xneg = Int64Sign(x); - int yneg = Int64Sign(y); - - if (xneg) - { - x = Int64Neg(x); - } - - if (yneg) - { - y = Int64Neg(y); - } - - /* while (y > 0) */ - while (Int64Gt(y, Int64Create(0, 0))) - { - /* if (y & 1 != 0) */ - if (Int64Neq(Int64And(y, Int64Create(0, 1)), Int64Create(0, 0))) - { - z = Int64Add(z, x); - } - - x = Int64Sll(x, 1); - y = Int64Sra(y, 1); - } - - if (xneg != yneg) - { - z = Int64Neg(z); - } - - return z; -} - -typedef struct -{ - Int64 q; - Int64 r; -} Int64Ldiv; - -static Int64Ldiv -Int64LongDivision(Int64 n, Int64 d) -{ - Int64Ldiv o; - - int i; - - int nneg = Int64Sign(n); - int dneg = Int64Sign(d); - - o.q = Int64Create(0, 0); - o.r = Int64Create(0, 0); - - if (Int64Eq(d, Int64Create(0, 0))) - { - raise(SIGFPE); - return o; - } - - if (nneg) - { - n = Int64Neg(n); - } - - if (dneg) - { - d = Int64Neg(d); - } - - for (i = 63; i >= 0; i--) - { - Int64 bit = Int64And(Int64Sra(n, i), Int64Create(0, 1)); - - o.r = Int64Sll(o.r, 1); - o.r = Int64Or(o.r, bit); - - if (Int64Geq(o.r, d)) - { - o.r = Int64Sub(o.r, d); - o.q = Int64Or(o.q, Int64Sll(Int64Create(0, 1), i)); - } - } - - if (nneg != dneg) - { - o.r = Int64Neg(o.r); - o.q = Int64Neg(o.q); - } - - return o; -} - -Int64 -Int64Div(Int64 x, Int64 y) -{ - return Int64LongDivision(x, y).q; -} - -Int64 -Int64Rem(Int64 x, Int64 y) -{ - return Int64LongDivision(x, y).r; -} - -Int64 -Int64Sll(Int64 x, int y) -{ - Int64 z; - - if (!y) - { - return x; - } - - z = Int64Create(0, 0); - - if (y < 32) - { - z.i[1] = (x.i[0] >> (32 - y)) | (x.i[1] << y); - z.i[0] = x.i[0] << y; - } - else - { - z.i[1] = x.i[0] << (y - 32); - } - - return z; -} - -Int64 -Int64Sra(Int64 x, int y) -{ - Int64 z; - - int neg = Int64Sign(x); - - if (!y) - { - return x; - } - - z = Int64Create(0, 0); - - if (y < 32) - { - z.i[0] = (x.i[1] << (32 - y)) | (x.i[0] >> y); - z.i[1] = x.i[1] >> y; - } - else - { - z.i[0] = x.i[1] >> (y - 32); - } - - if (neg) - { - Int64 mask = Int64Create(0xFFFFFFFF, 0xFFFFFFFF); - - z = Int64Or(Int64Sll(mask, (64 - y)), z); - } - - return z; -} - -Int64 -Int64And(Int64 x, Int64 y) -{ - return Int64Create(x.i[1] & y.i[1], x.i[0] & y.i[0]); -} - -Int64 -Int64Or(Int64 x, Int64 y) -{ - return Int64Create(x.i[1] | y.i[1], x.i[0] | y.i[0]); -} - -Int64 -Int64Xor(Int64 x, Int64 y) -{ - return Int64Create(x.i[1] ^ y.i[1], x.i[0] ^ y.i[0]); -} - -Int64 -Int64Not(Int64 x) -{ - return Int64Create(~(x.i[1]), ~(x.i[0])); -} - -int -Int64Eq(Int64 x, Int64 y) -{ - return x.i[0] == y.i[0] && x.i[1] == y.i[1]; -} - -int -Int64Lt(Int64 x, Int64 y) -{ - int xneg = Int64Sign(x); - int yneg = Int64Sign(y); - - if (xneg != yneg) - { - return xneg > yneg; - } - else - { - if (xneg) - { - /* Both negative */ - return x.i[1] > y.i[1] || (x.i[1] == y.i[1] && x.i[0] > y.i[0]); - } - else - { - /* Both positive */ - return x.i[1] < y.i[1] || (x.i[1] == y.i[1] && x.i[0] < y.i[0]); - } - } -} - -int -Int64Gt(Int64 x, Int64 y) -{ - int xneg = Int64Sign(x); - int yneg = Int64Sign(y); - - if (xneg != yneg) - { - return xneg < yneg; - } - else - { - if (xneg) - { - /* Both negative */ - return x.i[1] < y.i[1] || (x.i[1] == y.i[1] && x.i[0] < y.i[0]); - } - else - { - /* Both positive */ - return x.i[1] > y.i[1] || (x.i[1] == y.i[1] && x.i[0] > y.i[0]); - } - } - -} - -#endif diff --git a/src/Json.c b/src/Json.c index 10a0316..3ff9880 100644 --- a/src/Json.c +++ b/src/Json.c @@ -26,14 +26,15 @@ #include #include #include -#include -#include #include #include #include #include #include +#include +#include + #include struct JsonValue @@ -44,9 +45,9 @@ struct JsonValue HashMap *object; Array *array; char *string; - Int64 integer; + uint64_t integer; double floating; - int boolean:1; + bool boolean; } as; }; @@ -201,7 +202,7 @@ JsonValueAsString(JsonValue * value) } JsonValue * -JsonValueInteger(Int64 integer) +JsonValueInteger(uint64_t integer) { JsonValue *value; @@ -217,12 +218,12 @@ JsonValueInteger(Int64 integer) return value; } -Int64 +uint64_t JsonValueAsInteger(JsonValue * value) { if (!value || value->type != JSON_INTEGER) { - return Int64Create(0, 0); + return 0; } return value->as.integer; @@ -258,7 +259,7 @@ JsonValueAsFloat(JsonValue * value) } JsonValue * -JsonValueBoolean(int boolean) +JsonValueBoolean(bool boolean) { JsonValue *value; @@ -274,12 +275,12 @@ JsonValueBoolean(int boolean) return value; } -int +bool JsonValueAsBoolean(JsonValue * value) { if (!value || value->type != JSON_BOOLEAN) { - return 0; + return false; } return value->as.boolean; @@ -335,12 +336,12 @@ JsonValueFree(JsonValue * value) Free(value); } -int +size_t JsonEncodeString(const char *str, Stream * out) { size_t i; char c; - int length = 0; + size_t length = 0; StreamPutc(out, '"'); length++; @@ -403,9 +404,9 @@ JsonDecodeString(Stream * in) int c; char a[5]; - UInt32 codepoint; - UInt16 high; - UInt16 low; + uint32_t codepoint; + uint16_t high; + uint16_t low; char *utf8Ptr; @@ -422,7 +423,7 @@ JsonDecodeString(Stream * in) { if (c <= 0x001F) { - /* Bad byte; these must be escaped */ + /* Bad byte; these must be escaped */ Free(str); return NULL; } @@ -598,15 +599,13 @@ JsonDecodeString(Stream * in) return NULL; } -int +size_t JsonEncodeValue(JsonValue * value, Stream * out, int level) { size_t i; size_t len; Array *arr; - int length = 0; - - char ibuf[INT64_STRBUF]; + size_t length = 0; switch (value->type) { @@ -644,8 +643,7 @@ JsonEncodeValue(JsonValue * value, Stream * out, int level) length += JsonEncodeString(value->as.string, out); break; case JSON_INTEGER: - Int64Str(value->as.integer, 10, ibuf, INT64_STRBUF); - length += StreamPrintf(out, "%s", ibuf); + length += StreamPrintf(out, "%" PRId64, value->as.integer); break; case JSON_FLOAT: length += StreamPrintf(out, "%f", value->as.floating); @@ -673,14 +671,14 @@ JsonEncodeValue(JsonValue * value, Stream * out, int level) return length; } -int +size_t JsonEncode(HashMap * object, Stream * out, int level) { size_t index; size_t count; char *key; JsonValue *value; - int length; + size_t length; if (!object) { @@ -863,6 +861,7 @@ JsonConsumeWhitespace(JsonParserState * state) break; } + // TODO: This logic should be moved into Stream as a sync function. if (StreamError(state->stream)) { if (errno == EAGAIN) @@ -876,7 +875,7 @@ JsonConsumeWhitespace(JsonParserState * state) } else { - UtilSleepMillis(UInt64Create(0, delay)); + UtilSleepMillis(delay); continue; } } @@ -1123,7 +1122,7 @@ JsonDecodeValue(JsonParserState * state) JsonValue *value; char *strValue; - Int64 iValue; + int64_t iValue; size_t i; int neg; @@ -1146,7 +1145,7 @@ JsonDecodeValue(JsonParserState * state) Free(strValue); break; case TOKEN_INTEGER: - iValue = Int64Create(0, 0); + iValue = 0; i = 0; neg = 0; @@ -1162,14 +1161,14 @@ JsonDecodeValue(JsonParserState * state) } d = state->token[i] - '0'; - iValue = Int64Mul(iValue, Int64Create(0, 10)); - iValue = Int64Add(iValue, Int64Create(0, d)); + iValue *= 10; + iValue += d; i++; } if (neg) { - iValue = Int64Neg(iValue); + iValue *= -1; } value = JsonValueInteger(iValue); break; diff --git a/src/Memory.c b/src/Memory.c index 7fb2f64..134505c 100644 --- a/src/Memory.c +++ b/src/Memory.c @@ -32,8 +32,6 @@ #include #include -#include - #ifndef MEMORY_TABLE_CHUNK #define MEMORY_TABLE_CHUNK 256 #endif @@ -50,12 +48,12 @@ struct MemoryInfo void *pointer; }; -#define MEM_BOUND_TYPE UInt32 +#define MEM_BOUND_TYPE uint32_t #define MEM_BOUND 0xDEADBEEF #define MEM_BOUND_LOWER(p) *((MEM_BOUND_TYPE *) p) -#define MEM_BOUND_UPPER(p, x) *(((MEM_BOUND_TYPE *) (((UInt8 *) p) + x)) + 1) -#define MEM_SIZE_ACTUAL(x) (((x) * sizeof(UInt8)) + (2 * sizeof(MEM_BOUND_TYPE))) +#define MEM_BOUND_UPPER(p, x) *(((MEM_BOUND_TYPE *) (((uint8_t *) p) + x)) + 1) +#define MEM_SIZE_ACTUAL(x) (((x) * sizeof(uint8_t)) + (2 * sizeof(MEM_BOUND_TYPE))) static pthread_mutex_t lock; static void (*hook) (MemoryAction, MemoryInfo *, void *) = MemoryDefaultHook; diff --git a/src/Queue.c b/src/Queue.c index dbb0595..db228d1 100644 --- a/src/Queue.c +++ b/src/Queue.c @@ -75,39 +75,39 @@ QueueFree(Queue * q) Free(q); } -int +bool QueueFull(Queue * q) { if (!q) { - return 0; + return false; } return ((q->front == q->rear + 1) || (q->front == 0 && q->rear == q->size - 1)); } -int +bool QueueEmpty(Queue * q) { if (!q) { - return 0; + return false; } - return q->front == q->size + 1; + return (q->front == (q->size + 1)); } -int +bool QueuePush(Queue * q, void *element) { if (!q || !element) { - return 0; + return false; } if (QueueFull(q)) { - return 0; + return false; } if (q->front == q->size + 1) @@ -126,7 +126,7 @@ QueuePush(Queue * q, void *element) q->items[q->rear] = element; - return 1; + return true; } void * diff --git a/src/Rand.c b/src/Rand.c index 6665aef..3ece67a 100644 --- a/src/Rand.c +++ b/src/Rand.c @@ -23,12 +23,12 @@ */ #include -#include -#include #include #include #include +#include + #include #include @@ -42,12 +42,12 @@ typedef struct RandState { - UInt32 mt[RAND_STATE_VECTOR_LENGTH]; + uint32_t mt[RAND_STATE_VECTOR_LENGTH]; int index; } RandState; static void -RandSeed(RandState * state, UInt32 seed) +RandSeed(RandState * state, uint32_t seed) { state->mt[0] = seed & 0xFFFFFFFF; @@ -57,12 +57,12 @@ RandSeed(RandState * state, UInt32 seed) } } -static UInt32 +static uint32_t RandGenerate(RandState * state) { - static const UInt32 mag[2] = {0x0, 0x9908B0DF}; + static const uint32_t mag[2] = {0x0, 0x9908B0DF}; - UInt32 result; + uint32_t result; if (state->index >= RAND_STATE_VECTOR_LENGTH || state->index < 0) { @@ -118,22 +118,22 @@ RandDestructor(void *p) /* This algorithm therefore computes N random numbers generally in O(N) * time, while being less biased. */ void -RandIntN(int *buf, size_t size, unsigned int max) +RandIntN(uint32_t *buf, size_t size, uint32_t max) { static pthread_key_t stateKey; - static int createdKey = 0; + static bool createdKey = false; /* Limit the range to banish all previously biased results */ - const int allowed = RAND_MAX - RAND_MAX % max; + const uint32_t allowed = RAND_MAX - RAND_MAX % max; RandState *state; - int tmp; + uint32_t tmp; size_t i; if (!createdKey) { pthread_key_create(&stateKey, RandDestructor); - createdKey = 1; + createdKey = true; } state = pthread_getspecific(stateKey); @@ -141,8 +141,8 @@ RandIntN(int *buf, size_t size, unsigned int max) if (!state) { /* Generate a seed from the system time, PID, and TID */ - UInt64 ts = UtilServerTs(); - UInt32 seed = UInt64Low(ts) ^ getpid() ^ (unsigned long) pthread_self(); + uint64_t ts = UtilTsMillis(); + uint32_t seed = ts ^ getpid() ^ (unsigned long) pthread_self(); state = Malloc(sizeof(RandState)); RandSeed(state, seed); @@ -164,10 +164,10 @@ RandIntN(int *buf, size_t size, unsigned int max) } /* Generate just 1 random number */ -int -RandInt(unsigned int max) +uint32_t +RandInt(uint32_t max) { - int val = 0; + uint32_t val = 0; RandIntN(&val, 1, max); return val; diff --git a/src/Runtime.c b/src/Runtime.c index e5218ba..9a69875 100644 --- a/src/Runtime.c +++ b/src/Runtime.c @@ -38,11 +38,11 @@ HexDump(size_t off, char *hexBuf, char *asciiBuf, void *args) if (hexBuf && asciiBuf) { - fprintf(report, "%04lx: %s | %s |\n", off, hexBuf, asciiBuf); + fprintf(report, "%04zx: %s | %s |\n", off, hexBuf, asciiBuf); } else { - fprintf(report, "%04lx\n", off); + fprintf(report, "%04zx\n", off); } } @@ -52,7 +52,7 @@ MemoryIterator(MemoryInfo * i, void *args) { FILE *report = args; - fprintf(report, "%s:%d: %lu bytes at %p\n", + fprintf(report, "%s:%d: %zu bytes at %p\n", MemoryInfoGetFile(i), MemoryInfoGetLine(i), MemoryInfoGetSize(i), MemoryInfoGetPointer(i)); @@ -107,7 +107,7 @@ GenerateMemoryReport(int argc, char **argv) fprintf(report, " '%s'", argv[i]); } fprintf(report, "\nDate: %s\n", tsBuffer); - fprintf(report, "Total Bytes: %lu\n", MemoryAllocated()); + fprintf(report, "Total Bytes: %zu\n", MemoryAllocated()); fprintf(report, "\n"); MemoryIterate(MemoryIterator, report); diff --git a/src/Sha/Sha1.c b/src/Sha/Sha1.c index 1df414e..edd250f 100644 --- a/src/Sha/Sha1.c +++ b/src/Sha/Sha1.c @@ -23,7 +23,6 @@ */ #include #include -#include #include @@ -31,10 +30,10 @@ #define LOAD32H(x, y) \ { \ - x = ((UInt32)((y)[0] & 255) << 24) | \ - ((UInt32)((y)[1] & 255) << 16) | \ - ((UInt32)((y)[2] & 255) << 8) | \ - ((UInt32)((y)[3] & 255)); \ + x = ((uint32_t)((y)[0] & 255) << 24) | \ + ((uint32_t)((y)[1] & 255) << 16) | \ + ((uint32_t)((y)[2] & 255) << 8) | \ + ((uint32_t)((y)[3] & 255)); \ } #define ROL(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) @@ -49,22 +48,22 @@ typedef union { - UInt8 c[64]; - UInt32 l[16]; + uint8_t c[64]; + uint32_t l[16]; } Char64Long16; typedef struct { - UInt32 state[5]; - UInt32 count[2]; - UInt8 buffer[64]; + uint32_t state[5]; + uint32_t count[2]; + uint8_t buffer[64]; } Sha1Context; static void -Sha1Transform(UInt32 state[5], const UInt8 buffer[64]) +Sha1Transform(uint32_t state[5], const uint8_t *buffer) { - UInt32 a, b, c, d, e, i; - UInt8 workspace[64]; + uint32_t a, b, c, d, e, i; + uint8_t workspace[64]; Char64Long16 *block = (Char64Long16 *) workspace; for (i = 0; i < 16; i++) @@ -180,9 +179,9 @@ Sha1Init(Sha1Context * ctx) } static void -Sha1Update(Sha1Context * ctx, const void *buf, UInt32 size) +Sha1Update(Sha1Context * ctx, const void *buf, uint32_t size) { - UInt32 i, j; + uint32_t i, j; j = (ctx->count[0] >> 3) & 63; @@ -202,7 +201,7 @@ Sha1Update(Sha1Context * ctx, const void *buf, UInt32 size) for (; i + 63 < size; i += 64) { - Sha1Transform(ctx->state, (UInt8 *) buf + i); + Sha1Transform(ctx->state, (uint8_t *) buf + i); } j = 0; @@ -212,14 +211,14 @@ Sha1Update(Sha1Context * ctx, const void *buf, UInt32 size) i = 0; } - memcpy(&ctx->buffer[j], &((UInt8 *) buf)[i], size - i); + memcpy(&ctx->buffer[j], &((uint8_t *) buf)[i], size - i); } static void Sha1Calculate(Sha1Context * ctx, unsigned char *out) { - UInt32 i; - UInt8 count[8]; + uint32_t i; + uint8_t count[8]; for (i = 0; i < 8; i++) { @@ -227,16 +226,16 @@ Sha1Calculate(Sha1Context * ctx, unsigned char *out) >> ((3 - (i & 3)) * 8)) & 255); } - Sha1Update(ctx, (UInt8 *) "\x80", 1); + Sha1Update(ctx, (uint8_t *) "\x80", 1); while ((ctx->count[0] & 504) != 448) { - Sha1Update(ctx, (UInt8 *) "\0", 1); + Sha1Update(ctx, (uint8_t *) "\0", 1); } Sha1Update(ctx, count, 8); for (i = 0; i < (160 / 8); i++) { - out[i] = (UInt8) ((ctx->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255); + out[i] = (uint8_t) ((ctx->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255); } } diff --git a/src/Sha/Sha256.c b/src/Sha/Sha256.c index 3584f09..82ea046 100644 --- a/src/Sha/Sha256.c +++ b/src/Sha/Sha256.c @@ -23,7 +23,6 @@ */ #include #include -#include #include #include @@ -31,10 +30,10 @@ #include #define GET_UINT32(x) \ - (((UInt32)(x)[0] << 24) | \ - ((UInt32)(x)[1] << 16) | \ - ((UInt32)(x)[2] << 8) | \ - ((UInt32)(x)[3])) + (((uint32_t)(x)[0] << 24) | \ + ((uint32_t)(x)[1] << 16) | \ + ((uint32_t)(x)[2] << 8) | \ + ((uint32_t)(x)[3])) #define PUT_UINT32(dst, x) { \ (dst)[0] = (x) >> 24; \ @@ -56,8 +55,8 @@ #define WW(i) (w[i] = w[i - 16] + S0(w[i - 15]) + w[i - 7] + S1(w[i - 2])) #define ROUND(a, b, c, d, e, f, g, h, k, w) { \ - UInt32 tmp0 = h + T0(e) + CH(e, f, g) + k + w; \ - UInt32 tmp1 = T1(a) + MAJ(a, b, c); \ + uint32_t tmp0 = h + T0(e) + CH(e, f, g) + k + w; \ + uint32_t tmp1 = T1(a) + MAJ(a, b, c); \ h = tmp0 + tmp1; \ d += tmp0; \ } @@ -65,7 +64,7 @@ typedef struct Sha256Context { size_t length; - UInt32 state[8]; + uint32_t state[8]; size_t bufLen; unsigned char buffer[64]; } Sha256Context; @@ -73,7 +72,7 @@ typedef struct Sha256Context static void Sha256Chunk(Sha256Context * context, unsigned char chunk[64]) { - const UInt32 rk[64] = { + const uint32_t rk[64] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, @@ -87,8 +86,8 @@ Sha256Chunk(Sha256Context * context, unsigned char chunk[64]) 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; - UInt32 w[64]; - UInt32 a, b, c, d, e, f, g, h; + uint32_t w[64]; + uint32_t a, b, c, d, e, f, g, h; int i; @@ -178,10 +177,10 @@ Sha256(char *str) unsigned char *out; unsigned char fill[64]; - UInt32 fillLen; + uint32_t fillLen; unsigned char buf[8]; - UInt32 hiLen; - UInt32 loLen; + uint32_t hiLen; + uint32_t loLen; if (!str) { @@ -213,8 +212,8 @@ Sha256(char *str) fill[0] = 0x80; fillLen = (context.bufLen < 56) ? 56 - context.bufLen : 120 - context.bufLen; - hiLen = (UInt32) (context.length >> 29); - loLen = (UInt32) (context.length << 3); + hiLen = (uint32_t) (context.length >> 29); + loLen = (uint32_t) (context.length << 3); PUT_UINT32(&buf[0], hiLen); PUT_UINT32(&buf[4], loLen); diff --git a/src/Str.c b/src/Str.c index 2f4c665..bcbb63d 100644 --- a/src/Str.c +++ b/src/Str.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -35,8 +34,8 @@ #include #include -UInt32 -StrUtf16Decode(UInt16 high, UInt16 low) +uint32_t +StrUtf16Decode(uint16_t high, uint16_t low) { if (high <= 0xD7FF) { @@ -56,7 +55,7 @@ StrUtf16Decode(UInt16 high, UInt16 low) } char * -StrUtf8Encode(UInt32 codepoint) +StrUtf8Encode(uint32_t codepoint) { char *str; @@ -220,10 +219,10 @@ StrConcat(size_t nStr,...) return str; } -int +bool StrBlank(const char *str) { - int blank = 1; + bool blank = true; size_t i = 0; while (str[i]) @@ -245,7 +244,7 @@ StrRandom(size_t len) static const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; char *str; - int *nums; + uint32_t *nums; size_t i; if (!len) @@ -260,7 +259,7 @@ StrRandom(size_t len) return NULL; } - nums = Malloc(len * sizeof(int)); + nums = Malloc(len * sizeof(uint32_t)); if (!nums) { Free(str); @@ -323,21 +322,21 @@ StrLower(char *str) return ret; } -int +bool StrEquals(const char *str1, const char *str2) { /* Both strings are NULL, they're equal */ if (!str1 && !str2) { - return 1; + return true; } /* One or the other is NULL, they're not equal */ if (!str1 || !str2) { - return 0; + return false; } /* Neither are NULL, do a regular string comparison */ - return strcmp(str1, str2) == 0; + return (strcmp(str1, str2) == 0); } diff --git a/src/Stream.c b/src/Stream.c index 7c582af..539ec20 100644 --- a/src/Stream.c +++ b/src/Stream.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -50,11 +49,11 @@ struct Stream { Io *io; - UInt8 *rBuf; + uint8_t *rBuf; size_t rLen; size_t rOff; - UInt8 *wBuf; + uint8_t *wBuf; size_t wLen; char *ugBuf; @@ -550,13 +549,13 @@ StreamSeek(Stream * stream, off_t offset, int whence) return result; } -int +bool StreamEof(Stream * stream) { return stream && (stream->flags & STREAM_EOF); } -int +bool StreamError(Stream * stream) { return stream && (stream->flags & STREAM_ERR); @@ -626,7 +625,7 @@ StreamCopy(Stream * in, Stream * out) } else { - UtilSleepMillis(UInt64Create(0, STREAM_DELAY)); + UtilSleepMillis(STREAM_DELAY); continue; } } diff --git a/src/UInt64.c b/src/UInt64.c deleted file mode 100644 index ae8eff7..0000000 --- a/src/UInt64.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include - -#include -#include - -size_t -UInt64Str(UInt64 x, int base, char *out, size_t len) -{ - static const char symbols[] = "0123456789ABCDEF"; - - size_t i = len - 1; - size_t j = 0; - - UInt64 base64 = UInt64Create(0, base); - - /* We only have symbols up to base 16 */ - if (base < 2 || base > 16) - { - return 0; - } - - do - { - UInt64 mod = UInt64Rem(x, base64); - UInt32 low = UInt64Low(mod); - - out[i] = symbols[low]; - i--; - x = UInt64Div(x, base64); - } while (UInt64Gt(x, UInt64Create(0, 0))); - - while (++i < len) - { - out[j++] = out[i]; - } - - out[j] = '\0'; - - return j; -} - -#ifndef UINT64_NATIVE - -/* No native 64-bit support, add our own */ - -UInt64 -UInt64Create(UInt32 high, UInt32 low) -{ - UInt64 x; - - x.i[0] = low; - x.i[1] = high; - - return x; -} - -UInt64 -UInt64Add(UInt64 x, UInt64 y) -{ - UInt64 z = UInt64Create(0, 0); - int carry; - - z.i[0] = x.i[0] + y.i[0]; - carry = z.i[0] < x.i[0]; - z.i[1] = x.i[1] + y.i[1] + carry; - - return z; -} - -UInt64 -UInt64Sub(UInt64 x, UInt64 y) -{ - UInt64 twosCompl = UInt64Add(UInt64Not(y), UInt64Create(0, 1)); - - return UInt64Add(x, twosCompl); -} - -UInt64 -UInt64Mul(UInt64 x, UInt64 y) -{ - UInt64 z = UInt64Create(0, 0); - - /* while (y > 0) */ - while (UInt64Gt(y, UInt64Create(0, 0))) - { - /* if (y & 1 != 0) */ - if (UInt64Neq(UInt64And(y, UInt64Create(0, 1)), UInt64Create(0, 0))) - { - z = UInt64Add(z, x); - } - - x = UInt64Sll(x, 1); - y = UInt64Srl(y, 1); - } - - return z; -} - -typedef struct -{ - UInt64 q; - UInt64 r; -} UInt64Ldiv; - -static UInt64Ldiv -UInt64LongDivision(UInt64 n, UInt64 d) -{ - UInt64Ldiv o; - - int i; - - o.q = UInt64Create(0, 0); - o.r = UInt64Create(0, 0); - - if (UInt64Eq(d, UInt64Create(0, 0))) - { - raise(SIGFPE); - return o; - } - - for (i = 63; i >= 0; i--) - { - UInt64 bit = UInt64And(UInt64Srl(n, i), UInt64Create(0, 1)); - - o.r = UInt64Sll(o.r, 1); - o.r = UInt64Or(o.r, bit); - - if (UInt64Geq(o.r, d)) - { - o.r = UInt64Sub(o.r, d); - o.q = UInt64Or(o.q, UInt64Sll(UInt64Create(0, 1), i)); - } - } - - return o; -} - -UInt64 -UInt64Div(UInt64 x, UInt64 y) -{ - return UInt64LongDivision(x, y).q; -} - -UInt64 -UInt64Rem(UInt64 x, UInt64 y) -{ - return UInt64LongDivision(x, y).r; -} - -UInt64 -UInt64Sll(UInt64 x, int y) -{ - UInt64 z; - - if (!y) - { - return x; - } - - z = UInt64Create(0, 0); - - if (y < 32) - { - z.i[1] = (x.i[0] >> (32 - y)) | (x.i[1] << y); - z.i[0] = x.i[0] << y; - } - else - { - z.i[1] = x.i[0] << (y - 32); - } - - return z; -} - -UInt64 -UInt64Srl(UInt64 x, int y) -{ - UInt64 z; - - if (!y) - { - return x; - } - - z = UInt64Create(0, 0); - - if (y < 32) - { - z.i[0] = (x.i[1] << (32 - y)) | (x.i[0] >> y); - z.i[1] = x.i[1] >> y; - } - else - { - z.i[0] = x.i[1] >> (y - 32); - } - - return z; -} - -UInt64 -UInt64And(UInt64 x, UInt64 y) -{ - return UInt64Create(x.i[1] & y.i[1], x.i[0] & y.i[0]); -} - -UInt64 -UInt64Or(UInt64 x, UInt64 y) -{ - return UInt64Create(x.i[1] | y.i[1], x.i[0] | y.i[0]); -} - -UInt64 -UInt64Xor(UInt64 x, UInt64 y) -{ - return UInt64Create(x.i[1] ^ y.i[1], x.i[0] ^ y.i[0]); -} - -UInt64 -UInt64Not(UInt64 x) -{ - return UInt64Create(~(x.i[1]), ~(x.i[0])); -} - -int -UInt64Eq(UInt64 x, UInt64 y) -{ - return x.i[0] == y.i[0] && x.i[1] == y.i[1]; -} - -int -UInt64Lt(UInt64 x, UInt64 y) -{ - return x.i[1] < y.i[1] || (x.i[1] == y.i[1] && x.i[0] < y.i[0]); -} - -int -UInt64Gt(UInt64 x, UInt64 y) -{ - return x.i[1] > y.i[1] || (x.i[1] == y.i[1] && x.i[0] > y.i[0]); -} - -#endif diff --git a/src/Util.c b/src/Util.c index 183c26e..6701eb7 100644 --- a/src/Util.c +++ b/src/Util.c @@ -40,8 +40,6 @@ #include #include -#include - #ifndef PATH_MAX #define PATH_MAX 256 #endif @@ -50,14 +48,14 @@ #define SSIZE_MAX LONG_MAX #endif -UInt64 -UtilServerTs(void) +uint64_t +UtilTsMillis(void) { struct timeval tv; - UInt64 ts; - UInt64 sec; - UInt64 usec; + uint64_t ts; + uint64_t sec; + uint64_t usec; gettimeofday(&tv, NULL); @@ -77,54 +75,31 @@ UtilServerTs(void) * * The same goes for suseconds_t. */ - if (sizeof(time_t) == sizeof(UInt64)) - { - /* 64 bit time_t: convert it to a 64 bit integer */ - time_t ms = tv.tv_sec * 1000; - UInt32 high = (UInt32) (ms >> 32); - UInt32 low = (UInt32) ms; - sec = UInt64Create(high, low); - } - else - { - /* Assume 32 bit time_t: promote to 64 bit, then multiply, in - * case multiplication overflows 32 bits. */ - sec = UInt64Create(0, tv.tv_sec); - sec = UInt64Mul(sec, UInt64Create(0, 1000)); - } + // Two separate steps because time_t might be 32-bit. In that + // case, we want the multiplication to happen after the promotion + // to uint64_t. + sec = tv.tv_sec; + sec *= 1000; - usec = UInt64Create(0, tv.tv_usec / 1000); - ts = UInt64Add(sec, usec); + usec = tv.tv_usec / 1000; + + ts = sec + usec; return ts; } -UInt64 +uint64_t UtilLastModified(char *path) { struct stat st; - UInt64 ts = UInt64Create(0, 0); + uint64_t ts = 0; if (stat(path, &st) == 0) { - if (sizeof(time_t) == sizeof(UInt64)) - { - /* 64 bit time_t: convert it to a 64 bit integer */ - time_t ms = st.st_mtim.tv_sec * 1000; - UInt32 high = (UInt32) (ms >> 32); - UInt32 low = (UInt32) ms; - - ts = UInt64Create(high, low); - } - else - { - ts = UInt64Create(0, st.st_mtim.tv_sec); - ts = UInt64Mul(ts, UInt64Create(0, 1000)); - } - - /* nsec gauanteed to fit in 32 bits */ - ts = UInt64Add(ts, UInt64Create(0, st.st_mtim.tv_nsec / 1000000)); + ts = st.st_mtim.tv_sec; + ts *= 1000; + ts += st.st_mtim.tv_nsec / 1000000; } return ts; @@ -202,21 +177,13 @@ UtilMkdir(const char *dir, const mode_t mode) } int -UtilSleepMillis(UInt64 ms) +UtilSleepMillis(uint64_t ms) { struct timespec ts; int res; - if (sizeof(time_t) == sizeof(UInt64)) - { - ts.tv_sec = ((time_t) UInt64High(ms) << 32 | UInt64Low(ms)) / 1000; - } - else - { - ts.tv_sec = UInt64Low(ms) / 1000; - } - - ts.tv_nsec = UInt64Low(UInt64Rem(ms, UInt64Create(0, 1000))) * 1000000; + ts.tv_sec = ms / 1000; + ts.tv_nsec = (ms % 1000) * 1000000; res = nanosleep(&ts, &ts); @@ -312,14 +279,14 @@ ThreadNoDestructor(void *p) free(p); } -UInt32 +uint32_t UtilThreadNo(void) { static pthread_key_t key; static int createdKey = 0; static unsigned long count = 0; - UInt32 *no; + uint32_t *no; if (!createdKey) { @@ -330,7 +297,7 @@ UtilThreadNo(void) no = pthread_getspecific(key); if (!no) { - no = malloc(sizeof(UInt32)); + no = malloc(sizeof(uint32_t)); *no = count++; pthread_setspecific(key, no); } diff --git a/src/include/Array.h b/src/include/Array.h index 0ba1335..0705b2b 100644 --- a/src/include/Array.h +++ b/src/include/Array.h @@ -52,6 +52,7 @@ #include #include +#include /** * The functions in this API operate on an array structure which is @@ -98,7 +99,7 @@ extern void *ArrayGet(Array *, size_t); * This function returns a boolean value indicating whether or not it * suceeded. */ -extern int ArrayInsert(Array *, size_t, void *); +extern bool ArrayInsert(Array *, size_t, void *); /** * Set the value at the specified index in the specified array to the @@ -115,7 +116,7 @@ extern void *ArraySet(Array *, size_t, void *); * return value as * .Fn ArrayInsert . */ -extern int ArrayAdd(Array *, void *); +extern bool ArrayAdd(Array *, void *); /** * Remove the element at the specified index from the specified array. @@ -146,7 +147,7 @@ extern void ArraySort(Array *, int (*) (void *, void *)); * .P * This is a relatively expensive operation. The array must first be * duplicated. Then it is sorted, then it is iterated from beginning - * to end to remove duplicate entires. Note that the comparison + * to end to remove duplicate entries. Note that the comparison * function is executed on each element at least twice. */ extern Array *ArrayUnique(Array *, int (*) (void *, void *)); @@ -167,7 +168,7 @@ extern Array *ArrayReverse(Array *); * array. This function is intended to be used by functions that return * relatively read-only arrays that will be long-lived. */ -extern int ArrayTrim(Array *); +extern bool ArrayTrim(Array *); /** * Convert a variadic arguments list into an Array. In most cases, the diff --git a/src/include/Base64.h b/src/include/Base64.h index b36a48c..74c8956 100644 --- a/src/include/Base64.h +++ b/src/include/Base64.h @@ -39,6 +39,7 @@ */ #include +#include /** * This function computes the amount of bytes needed to store a message @@ -93,7 +94,7 @@ extern void * this means it will only fail if a bigger string is necessary, but it * could not be automatically allocated on the heap. */ -extern int +extern bool Base64Pad(char **, size_t); #endif /* CYTOPLASM_BASE64_H */ diff --git a/src/include/Cron.h b/src/include/Cron.h index 23053c6..00280cc 100644 --- a/src/include/Cron.h +++ b/src/include/Cron.h @@ -24,6 +24,8 @@ #ifndef CYTOPLASM_CRON_H #define CYTOPLASM_CRON_H +#include + /*** * @Nm Cron * @Nd Basic periodic job scheduler. @@ -56,8 +58,6 @@ * by any means. */ -#include "Int.h" - /** * All functions defined here operate on a structure opaque to the * caller. @@ -82,7 +82,7 @@ typedef void (JobFunc) (void *); * .Pp * This function takes the tick interval in milliseconds. */ -extern Cron * CronCreate(UInt32); +extern Cron * CronCreate(uint64_t); /** * Schedule a one-off job to be executed only at the next tick, and @@ -110,7 +110,7 @@ extern void * and a pointer to pass to that function when it is executed. */ extern void - CronEvery(Cron *, unsigned long, JobFunc *, void *); + CronEvery(Cron *, uint64_t, JobFunc *, void *); /** * Start ticking the clock and executing registered jobs. diff --git a/src/include/Cytoplasm.h b/src/include/Cytoplasm.h index f965f2f..97a4a54 100644 --- a/src/include/Cytoplasm.h +++ b/src/include/Cytoplasm.h @@ -24,6 +24,17 @@ #ifndef CYTOPLASM_CYTOPLASM_H #define CYTOPLASM_CYTOPLASM_H +#define CYTOPLASM_VERSION_MAJOR 0 +#define CYTOPLASM_VERSION_MINOR 4 +#define CYTOPLASM_VERSION_PATCH 1 +#define CYTOPLASM_VERSION ((CYTOPLASM_VERSION_MAJOR * 10000) + (CYTOPLASM_VERSION_MINOR * 100) + (CYTOPLASM_VERSION_PATCH)) + +#define CYTOPLASM_VERSION_ALPHA 1 +#define CYTOPLASM_VERSION_BETA 0 +#define CYTOPLASM_VERSION_STABLE (!CYTOPLASM_VERSION_ALPHA && !CYTOPLASM_VERSION_BETA) + +#define STRINGIFY(x) #x + /*** * @Nm Cytoplasm * @Nd A simple API that provides metadata on the library itself. @@ -34,18 +45,8 @@ * currently loaded library. */ - -/** - * Get the name that this library was compiled with. In most cases, - * this will be hard-coded to "Cytoplasm", but it may differ if, for - * some reason, there exists another ABI-compatible library that - * wishes to report its name. - * - * This function really only exists because the information is - * available along side of the version information so for - * consistency, it made sense to include both. - */ -extern char * CytoplasmGetName(void); +/** */ +extern int CytoplasmGetVersion(void); /** * Get the library version. This will be useful mostly for printing @@ -55,6 +56,6 @@ extern char * CytoplasmGetName(void); * This function returns a string, which should usually be able to be * parsed using sscanf() if absolutely necessary. */ -extern char * CytoplasmGetVersion(void); +extern const char * CytoplasmGetVersionStr(void); -#endif /* CYTOPLASM_CYTOPLASM_H */ \ No newline at end of file +#endif /* CYTOPLASM_CYTOPLASM_H */ diff --git a/src/include/Db.h b/src/include/Db.h index da98a39..9aa0758 100644 --- a/src/include/Db.h +++ b/src/include/Db.h @@ -37,6 +37,7 @@ */ #include +#include #include "HashMap.h" #include "Array.h" @@ -113,7 +114,7 @@ extern DbRef * DbLock(Db *, size_t,...); * This function assumes the object is not locked, otherwise undefined * behavior will result. */ -extern int DbDelete(Db *, size_t,...); +extern bool DbDelete(Db *, size_t,...); /** * Unlock an object and return it back to the database. This function @@ -121,7 +122,7 @@ extern int DbDelete(Db *, size_t,...); * read cache; writes are always immediate to ensure data integrity in * the event of a system failure. */ -extern int DbUnlock(Db *, DbRef *); +extern bool DbUnlock(Db *, DbRef *); /** * Check the existence of the given database object in a more efficient @@ -130,7 +131,7 @@ extern int DbUnlock(Db *, DbRef *); * This function does not lock the object, nor does it load it into * memory if it exists. */ -extern int DbExists(Db *, size_t,...); +extern bool DbExists(Db *, size_t,...); /** * List all of the objects at a given path. Unlike the other varargs @@ -164,6 +165,6 @@ extern HashMap * DbJson(DbRef *); * replace it with new JSON. This is more efficient than duplicating * a separate object into the database reference. */ -extern int DbJsonSet(DbRef *, HashMap *); +extern bool DbJsonSet(DbRef *, HashMap *); #endif diff --git a/src/include/HashMap.h b/src/include/HashMap.h index f0ee7f3..716dacc 100644 --- a/src/include/HashMap.h +++ b/src/include/HashMap.h @@ -150,7 +150,7 @@ extern void * HashMapDelete(HashMap *, const char *); * insertions or deletions occur during the iteration. This * functionality has not been tested, and will likely not work. */ -extern int HashMapIterate(HashMap *, char **, void **); +extern bool HashMapIterate(HashMap *, char **, void **); /** * A reentrant version of @@ -163,7 +163,7 @@ extern int HashMapIterate(HashMap *, char **, void **); * .Pp * The cursor should be initialized to 0 at the start of iteration. */ -extern int +extern bool HashMapIterateReentrant(HashMap *, char **, void **, size_t *); /** diff --git a/src/include/HttpRouter.h b/src/include/HttpRouter.h index a0950b0..2df3db7 100644 --- a/src/include/HttpRouter.h +++ b/src/include/HttpRouter.h @@ -74,7 +74,7 @@ extern void HttpRouterFree(HttpRouter *); * .Pa /some/path/(.*)/parts * to work as one would expect. */ -extern int HttpRouterAdd(HttpRouter *, char *, HttpRouteFunc *); +extern bool HttpRouterAdd(HttpRouter *, char *, HttpRouteFunc *); /** * Route the specified request path using the specified routing @@ -86,6 +86,6 @@ extern int HttpRouterAdd(HttpRouter *, char *, HttpRouteFunc *); * how to handle, and the pointer to a void pointer is where the * route function's response will be placed. */ -extern int HttpRouterRoute(HttpRouter *, char *, void *, void **); +extern bool HttpRouterRoute(HttpRouter *, char *, void *, void **); #endif /* CYTOPLASM_HTTPROUTER_H */ diff --git a/src/include/HttpServer.h b/src/include/HttpServer.h index 78ef2f8..c539ac7 100644 --- a/src/include/HttpServer.h +++ b/src/include/HttpServer.h @@ -47,6 +47,7 @@ */ #include +#include #include "Http.h" #include "HashMap.h" @@ -133,7 +134,7 @@ extern void HttpServerFree(HttpServer *); * caller can continue working while the HTTP server is running in a * separate thread and managing a pool of threads to handle responses. */ -extern int HttpServerStart(HttpServer *); +extern bool HttpServerStart(HttpServer *); /** * Typically, at some point after calling diff --git a/src/include/Int.h b/src/include/Int.h deleted file mode 100644 index 7933a69..0000000 --- a/src/include/Int.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef CYTOPLASM_INT_H -#define CYTOPLASM_INT_H - -/*** - * @Nm Int - * @Nd Fixed-width integer types. - * @Dd April 27 2023 - * - * This header provides cross-platform, fixed-width integer types. - * Specifically, it uses preprocessor magic to define the following - * types: - * .Bl -bullet -offset indent - * .It - * Int8 and UInt8 - * .It - * Int16 and UInt16 - * .It - * Int32 and UInt32 - * .El - * .Pp - * Note that there is no 64-bit integer type, because the ANSI C - * standard makes no guarantee that such a type will exist, even - * though it does on most platforms. - * .Pp - * The reason Cytoplasm provides its own header for this is - * because ANSI C does not define fixed-width types, and while it - * should be safe to rely on C99 fixed-width types in most cases, - * there may be cases where even that is not possible. - * - * @ignore-typedefs - */ - -#include - -#define BIT32_MAX 4294967295UL -#define BIT16_MAX 65535UL -#define BIT8_MAX 255UL - -#ifndef UCHAR_MAX -#error Size of char data type is unknown. Define UCHAR_MAX. -#endif - -#ifndef USHRT_MAX -#error Size of short data type is unknown. Define USHRT_MAX. -#endif - -#ifndef UINT_MAX -#error Size of int data type is unknown. Define UINT_MAX. -#endif - -#ifndef ULONG_MAX -#error Size of long data type is unknown. Define ULONG_MAX. -#endif - -#if UCHAR_MAX == BIT8_MAX -typedef signed char Int8; -typedef unsigned char UInt8; - -#else -#error Unable to determine suitable data type for 8-bit integers. -#endif - -#if UINT_MAX == BIT16_MAX -typedef signed int Int16; -typedef unsigned int UInt16; - -#elif USHRT_MAX == BIT16_MAX -typedef signed short Int16; -typedef unsigned short UInt16; - -#elif UCHAR_MAX == BIT16_MAX -typedef signed char Int16; -typedef unsigned char UInt16; - -#else -#error Unable to determine suitable data type for 16-bit integers. -#endif - -#if ULONG_MAX == BIT32_MAX -typedef signed long Int32; -typedef unsigned long UInt32; - -#elif UINT_MAX == BIT32_MAX -typedef signed int Int32; -typedef unsigned int UInt32; - -#elif USHRT_MAX == BIT32_MAX -typedef signed short Int32; -typedef unsigned short UInt32; - -#elif UCHAR_MAX == BIT32_MAX -typedef signed char Int32; -typedef unsigned char UInt32; - -#else -#error Unable to determine suitable data type for 32-bit integers. -#endif - -#endif /* CYTOPLASM_INT_H */ diff --git a/src/include/Int64.h b/src/include/Int64.h deleted file mode 100644 index e380ab4..0000000 --- a/src/include/Int64.h +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef CYTOPLASM_INT64_H -#define CYTOPLASM_INT64_H - -/*** - * @Nm Int64 - * @Nd Fixed-width 64 bit integers. - * @Dd August 11, 2023 - * - * .Pp - * ANSI C89 (or C99 for that matter) provides no required mechanism - * for 64 bit integers. Nevertheless, many compilers provide them as - * extensions. However, since it is not a gaurantee, and to be fully - * standards-compliant and thus portable, a platform-agnostic interface - * is required. This header provides such an interface. If the platform - * has a 64 bit integer type, that is used, and native operations are - * performed by C preprocessor macro expansion. Otherwise, a - * compatibility layer is provided, which implements 64-bit - * arithmetic on an array of 2 32-bit numbers which are provided by - * .Xr Int 3 . - * .Pp - * Note that 64-bit emulation is certainly not as performant as using - * native 64-bit operations, so whenever possible, the native - * operations should be preferred. However, since C provides no required - * 64 bit integer on 32-bit and less platforms, this API can be used as - * a "good enough" fallback mechanism. - * .Pp - * Also note that this implementation, both in the native and - * non-native forms, makes some assumptions: - * .Bl -bullet -width Ds - * .It - * When a cast from a larger integer to a smaller integer is performed, - * the upper bits are truncated, not the lower bits. - * .It - * Negative numbers are represented in memory and in registers in two's - * compliment form. - * .El - * .Pp - * This API may provide unexpected output if these assumptions are - * false for a given platform. - * - * @ignore-typedefs - */ - -#include "Int.h" -#include "UInt64.h" - -#include - -#ifndef INT64_FORCE_EMULATED - -#define BIT64_MAX 18446744073709551615UL - -#if UINT_MAX == BIT64_MAX -typedef signed int Int64; - -#define INT64_NATIVE - -#elif ULONG_MAX == BIT64_MAX -typedef signed long Int64; - -#define INT64_NATIVE - -#endif - -#endif /* ifndef INT64_FORCE_EMULATED */ - -#ifdef INT64_NATIVE - -#define Int64Create(high, low) ((Int64) (((UInt64) (high) << 32) | (low))) -#define Int64Neg(x) (-(x)) - -#define Int64Low(a) ((UInt32) (a)) -#define Int64High(a) ((UInt32) ((a) >> 32)) - -#define Int64Add(a, b) ((a) + (b)) -#define Int64Sub(a, b) ((a) - (b)) -#define Int64Mul(a, b) ((a) * (b)) -#define Int64Div(a, b) ((a) / (b)) -#define Int64Rem(a, b) ((a) % (b)) - -#define Int64Sll(a, b) ((a) << (b)) -#define Int64Sra(a, b) ((a) >> (b)) - -#define Int64And(a, b) ((a) & (b)) -#define Int64Or(a, b) ((a) | (b)) -#define Int64Xor(a, b) ((a) ^ (b)) -#define Int64Not(a) (~(a)) - -#define Int64Eq(a, b) ((a) == (b)) -#define Int64Lt(a, b) ((a) < (b)) -#define Int64Gt(a, b) ((a) > (b)) - -#define Int64Neq(a, b) ((a) != (b)) -#define Int64Leq(a, b) ((a) <= (b)) -#define Int64Geq(a, b) ((a) >= (b)) - -#else - -#define Int64Neg(x) (Int64Add(Int64Not(x), Int64Create(0, 1))) - -/** - * The internal bit representation of a signed integer is identical - * to an unsigned integer, the difference is in the algorithms and - * the way the bits are interpreted. - */ -typedef UInt64 Int64; - -/** - * Create a new signed 64 bit integer using the given high and low - * bits. - */ -extern Int64 Int64Create(UInt32, UInt32); - -/** - * Add two signed 64 bit integers together. - */ -extern Int64 Int64Add(Int64, Int64); - -/** - * Subtract the second 64 bit integer from the first. - */ -extern Int64 Int64Sub(Int64, Int64); - -/** - * Multiply two 64 bit integers together. The non-native version of - * this function uses the Russian Peasant method of multiplication, - * which should afford more performance than a naive multiplication by - * addition, but it is still rather slow and depends on the size of - * the integers being multiplied. - */ -extern Int64 Int64Mul(Int64, Int64); - -/** - * Divide the first 64 bit integer by the second and return the - * quotient. The non-native version of this function uses naive binary - * long division, which is slow, but gauranteed to finish in constant - * time. - */ -extern Int64 Int64Div(Int64, Int64); - -/** - * Divide the first 64 bit integer by the second and return the - * remainder. The non-native version of this function uses naive binary - * long division, which is slow, but gauranteed to finish in constant - * time. - */ -extern Int64 Int64Rem(Int64, Int64); - -/** - * Perform a left logical bit shift of a 64 bit integer. The second - * parameter is how many places to shift, and is declared as a regular - * integer because anything more than 64 does not make sense. - */ -extern Int64 Int64Sll(Int64, int); - -/** - * Perform a right arithmetic bit shift of a 64 bit integer. The second - * parameter is how many places to shift, and is declared as a regular - * integer because anything more than 64 does not make sense. - * .Pp - * Note that on platforms that use the native 64-bit implementation, - * this is technically implementation-defined, and may in fact be a - * logical shift instead of an arithmetic shift. Note that typically - * this operation is not performed on signed integers. - */ -extern Int64 Int64Sra(Int64, int); - -/** - * Perform a bitwise AND (&) of the provided 64 bit integers. - */ -extern Int64 Int64And(Int64, Int64); - -/** - * Perform a bitwise OR (|) of the provided 64 bit integers. - */ -extern Int64 Int64Or(Int64, Int64); - -/** - * Perform a bitwise XOR (^) of the provided 64 bit integers. - */ -extern Int64 Int64Xor(Int64, Int64); - -/** - * Perform a bitwise NOT (~) of the provided 64 bit integer. - */ -extern Int64 Int64Not(Int64); - -/** - * Perform a comparison of the provided 64 bit integers and return a C - * boolean that is true if and only if they are equal. - */ -extern int Int64Eq(Int64, Int64); - -/** - * Perform a comparison of the provided 64 bit integers and return a C - * boolean that is true if and only if the second operand is strictly - * less than the first. - */ -extern int Int64Lt(Int64, Int64); - -/** - * Perform a comparison of the provided 64 bit integers and return a C - * boolean that is true if and only if the second operand is strictly - * greater than the first. - */ -extern int Int64Gt(Int64, Int64); - -#define Int64Low(a) ((a).i[0]) -#define Int64High(a) ((a).i[1]) - -#define Int64Neq(a, b) (!Int64Eq(a, b)) -#define Int64Leq(a, b) (Int64Eq(a, b) || Int64Lt(a, b)) -#define Int64Geq(a, b) (Int64Eq(a, b) || Int64Gt(a, b)) - -#endif - -#define INT64_STRBUF 65 /* Base 2 representation with '\0' */ - -/** - * Convert a 64 bit integer to a string in an arbitrary base - * representation specified by the second parameter, using the provided - * buffer and length specified by the third and fourth parameters. To - * guarantee that the string will fit in the buffer, allocate it of - * size INT64_STRBUF or larger. Note that a buffer size smaller than - * INT64_STRBUF will invoke undefined behavior. - */ -extern size_t Int64Str(Int64, int, char *, size_t); - -#endif /* CYTOPLASM_INT64_H */ diff --git a/src/include/Json.h b/src/include/Json.h index 5a14aab..e74c77d 100644 --- a/src/include/Json.h +++ b/src/include/Json.h @@ -71,10 +71,10 @@ #include "HashMap.h" #include "Array.h" #include "Stream.h" -#include "Int64.h" #include #include +#include #define JSON_DEFAULT -1 #define JSON_PRETTY 0 @@ -152,7 +152,7 @@ extern char * JsonValueAsString(JsonValue *); * Encode a number as a JSON value that can be added to an object or * an array. */ -extern JsonValue * JsonValueInteger(Int64); +extern JsonValue * JsonValueInteger(uint64_t); /** * Unwrap a JSON value that represents a number. This function will @@ -160,7 +160,7 @@ extern JsonValue * JsonValueInteger(Int64); * misleading. Check the type of the value before making assumptions * about its value. */ -extern Int64 JsonValueAsInteger(JsonValue *); +extern uint64_t JsonValueAsInteger(JsonValue *); /** * Encode a floating point number as a JSON value that can be added @@ -181,7 +181,7 @@ extern double JsonValueAsFloat(JsonValue *); * expressions as a JSON value that can be added to an object or an * array. */ -extern JsonValue * JsonValueBoolean(int); +extern JsonValue * JsonValueBoolean(bool); /** * Unwrap a JSON value that represents a boolean. This function will @@ -189,7 +189,7 @@ extern JsonValue * JsonValueBoolean(int); * misleading. Check the type of the value before making assumptions * about its type. */ -extern int JsonValueAsBoolean(JsonValue *); +extern bool JsonValueAsBoolean(JsonValue *); /** * This is a special case that represents a JSON null. Because the @@ -253,7 +253,7 @@ extern void JsonFree(HashMap *); * or if the stream is NULL, the number of bytes that would have * been written. */ -extern int JsonEncodeString(const char *, Stream *); +extern size_t JsonEncodeString(const char *, Stream *); /** * Serialize a JSON value as it would appear in JSON output. This is @@ -277,7 +277,7 @@ extern int JsonEncodeString(const char *, Stream *); * or if the stream is NULL, the number of bytes that would have * been written. */ -extern int JsonEncodeValue(JsonValue *, Stream *, int); +extern size_t JsonEncodeValue(JsonValue *, Stream *, int); /** * Encode a JSON object as it would appear in JSON output, writing it @@ -289,7 +289,7 @@ extern int JsonEncodeValue(JsonValue *, Stream *, int); * or if the stream is NULL, the number of bytes that would have * been written. */ -extern int JsonEncode(HashMap *, Stream *, int); +extern size_t JsonEncode(HashMap *, Stream *, int); /** * Decode a JSON object from the given input stream and parse it into diff --git a/src/include/Memory.h b/src/include/Memory.h index 5d5ecec..d6836ee 100644 --- a/src/include/Memory.h +++ b/src/include/Memory.h @@ -76,6 +76,7 @@ * macros. */ #include +#include /** * These values are passed into the memory hook function to indicate diff --git a/src/include/Queue.h b/src/include/Queue.h index 35821d3..1c148b7 100644 --- a/src/include/Queue.h +++ b/src/include/Queue.h @@ -46,6 +46,7 @@ */ #include +#include /** * These functions operate on a queue structure that is opaque to the @@ -73,7 +74,7 @@ extern void QueueFree(Queue *); * value indicating whether or not the push succeeded. Pushing items * into the queue will fail if the queue is full. */ -extern int QueuePush(Queue *, void *); +extern bool QueuePush(Queue *, void *); /** * Pop an element out of the queue. This function returns NULL if the @@ -95,11 +96,11 @@ extern void * QueuePeek(Queue *); /** * Determine whether or not the queue is full. */ -extern int QueueFull(Queue *); +extern bool QueueFull(Queue *); /** * Determine whether or not the queue is empty. */ -extern int QueueEmpty(Queue *); +extern bool QueueEmpty(Queue *); #endif diff --git a/src/include/Rand.h b/src/include/Rand.h index a5be3ce..69fdb7f 100644 --- a/src/include/Rand.h +++ b/src/include/Rand.h @@ -58,11 +58,13 @@ */ #include +#include /** - * Generate a single random integer between 0 and the passed value. + * Generate a single random 32-bit integer between 0 and the + * passed value. */ -extern int RandInt(unsigned int); +extern uint32_t RandInt(uint32_t); /** * Generate the number of integers specified by the second argument @@ -76,6 +78,6 @@ extern int RandInt(unsigned int); * has to lock and unlock a mutex. It is therefore better to obtain * multiple random numbers in one pass if multiple are needed. */ -extern void RandIntN(int *, size_t, unsigned int); +extern void RandIntN(uint32_t *, size_t, uint32_t); #endif /* CYTOPLASM_RAND_H */ diff --git a/src/include/Str.h b/src/include/Str.h index cae9062..87bc92b 100644 --- a/src/include/Str.h +++ b/src/include/Str.h @@ -39,21 +39,21 @@ * is a standard library header. */ -#include "Int.h" - #include +#include +#include /** * Convert UTF-16 into a Unicode codepoint. */ -extern UInt32 StrUtf16Decode(UInt16, UInt16); +extern uint32_t StrUtf16Decode(uint16_t, uint16_t); /** * Take a Unicode codepoint and encode it into a string buffer containing * between 1 and 4 bytes. The string buffer is allocated on the heap, * so it should be freed when it is no longer needed. */ -extern char * StrUtf8Encode(UInt32); +extern char * StrUtf8Encode(uint32_t); /** * Duplicate a null-terminated string, returning a new string on the @@ -87,7 +87,7 @@ extern char * StrConcat(size_t,...); * string consists only of blank characters, as determined by * .Xr isblank 3 . */ -extern int StrBlank(const char *str); +extern bool StrBlank(const char *str); /** * Generate a string of the specified length, containing random @@ -124,6 +124,6 @@ extern char * StrLower(char *); * function returns a boolean value indicating whether or not * strcmp() returned 0. */ -extern int StrEquals(const char *, const char *); +extern bool StrEquals(const char *, const char *); #endif /* CYTOPLASM_STR_H */ diff --git a/src/include/Stream.h b/src/include/Stream.h index 7c6a1a5..a62a033 100644 --- a/src/include/Stream.h +++ b/src/include/Stream.h @@ -39,6 +39,8 @@ #include "Io.h" #include +#include +#include /** * An opaque structure analogous to C's FILE pointers. @@ -172,7 +174,7 @@ extern off_t StreamSeek(Stream *, off_t, int); * .Xr feof 3 * function. */ -extern int StreamEof(Stream *); +extern bool StreamEof(Stream *); /** * Test the stream for an error condition, returning a boolean value @@ -181,7 +183,7 @@ extern int StreamEof(Stream *); * .Xr ferror 3 * function. */ -extern int StreamError(Stream *); +extern bool StreamError(Stream *); /** * Clear the error condition associated with the given stream, allowing diff --git a/src/include/UInt64.h b/src/include/UInt64.h deleted file mode 100644 index c16fc22..0000000 --- a/src/include/UInt64.h +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef CYTOPLASM_UINT64_H -#define CYTOPLASM_UINT64_H - -/*** - * @Nm UInt64 - * @Nd Fixed-width 64 bit integers. - * @Dd August 11, 2023 - * - * .Pp - * ANSI C89 (or C99 for that matter) provides no required mechanism - * for 64 bit integers. Nevertheless, many compilers provide them as - * extensions. However, since it is not a gaurantee, and to be fully - * standards-compliant and thus portable, a platform-agnostic interface - * is required. This header provides such an interface. If the platform - * has a 64 bit integer type, that is used, and native operations are - * performed by C preprocessor macro expansion. Otherwise, a - * compatibility layer is provided, which implements 64-bit - * arithmetic on an array of 2 32-bit numbers which are provided by - * .Xr Int 3 . - * .Pp - * Note that 64-bit emulation is certainly not as performant as using - * native 64-bit operations, so whenever possible, the native - * operations should be preferred. However, since C provides no required - * 64 bit integer on 32-bit and less platforms, this API can be used as - * a "good enough" fallback mechanism. - * .Pp - * Also note that this implementation, both in the native and - * non-native forms, makes some assumptions: - * .Bl -bullet -width Ds - * .It - * When a cast from a larger integer to a smaller integer is performed, - * the upper bits are truncated, not the lower bits. - * .It - * Negative numbers are represented in memory and in registers in two's - * compliment form. - * .El - * .Pp - * This API may provide unexpected output if these assumptions are - * false for a given platform. - * - * @ignore-typedefs - */ - -#include "Int.h" - -#include - -#ifndef INT64_FORCE_EMULATED - -#define BIT64_MAX 18446744073709551615UL - -#if UINT_MAX == BIT64_MAX -/* typedef signed int Int64; */ -typedef unsigned int UInt64; - -#define UINT64_NATIVE - -#elif ULONG_MAX == BIT64_MAX -/* typedef signed int Int64; */ -typedef unsigned long UInt64; - -#define UINT64_NATIVE - -#endif - -#endif /* ifndef INT64_FORCE_EMULATED */ - -#ifdef UINT64_NATIVE - -#define UInt64Create(high, low) (((UInt64) (high) << 32) | (low)) -#define UInt64Low(a) ((UInt32) ((a) & 0x00000000FFFFFFFF)) -#define UInt64High(a) ((UInt32) ((a) >> 32)) - -#define UInt64Add(a, b) ((a) + (b)) -#define UInt64Sub(a, b) ((a) - (b)) -#define UInt64Mul(a, b) ((a) * (b)) -#define UInt64Div(a, b) ((a) / (b)) -#define UInt64Rem(a, b) ((a) % (b)) - -#define UInt64Sll(a, b) ((a) << (b)) -#define UInt64Srl(a, b) ((a) >> (b)) - -#define UInt64And(a, b) ((a) & (b)) -#define UInt64Or(a, b) ((a) | (b)) -#define UInt64Xor(a, b) ((a) ^ (b)) -#define UInt64Not(a) (~(a)) - -#define UInt64Eq(a, b) ((a) == (b)) -#define UInt64Lt(a, b) ((a) < (b)) -#define UInt64Gt(a, b) ((a) > (b)) - -#define UInt64Neq(a, b) ((a) != (b)) -#define UInt64Leq(a, b) ((a) <= (b)) -#define UInt64Geq(a, b) ((a) >= (b)) - -#else - -/** - * For platforms that do not have a native integer large enough to - * store a 64 bit integer, this struct is used. i[0] contains the low - * bits of integer, and i[1] contains the high bits of the integer. - * .Pp - * This struct should not be accessed directly, because UInt64 may not - * actually be this struct, it might be an actual integer type. For - * maximum portability, only use the functions defined here to - * manipulate 64 bit integers. - */ -typedef struct -{ - UInt32 i[2]; -} UInt64; - -/** - * Create a new unsigned 64 bit integer using the given high and low - * bits. - */ -extern UInt64 UInt64Create(UInt32, UInt32); - -/** - * Add two unsigned 64 bit integers together. - */ -extern UInt64 UInt64Add(UInt64, UInt64); - -/** - * Subtract the second 64 bit integer from the first. - */ -extern UInt64 UInt64Sub(UInt64, UInt64); - -/** - * Multiply two 64 bit integers together. The non-native version of - * this function uses the Russian Peasant method of multiplication, - * which should afford more performance than a naive multiplication by - * addition, but it is still rather slow and depends on the size of - * the integers being multiplied. - */ -extern UInt64 UInt64Mul(UInt64, UInt64); - -/** - * Divide the first 64 bit integer by the second and return the - * quotient. The non-native version of this function uses naive binary - * long division, which is slow, but gauranteed to finish in constant - * time. - */ -extern UInt64 UInt64Div(UInt64, UInt64); - -/** - * Divide the first 64 bit integer by the second and return the - * remainder. The non-native version of this function uses naive binary - * long division, which is slow, but gauranteed to finish in constant - * time. - */ -extern UInt64 UInt64Rem(UInt64, UInt64); - -/** - * Perform a left logical bit shift of a 64 bit integer. The second - * parameter is how many places to shift, and is declared as a regular - * integer because anything more than 64 does not make sense. - */ -extern UInt64 UInt64Sll(UInt64, int); - -/** - * Perform a right logical bit shift of a 64 bit integer. The second - * parameter is how many places to shift, and is declared as a regular - * integer because anything more than 64 does not make sense. - */ -extern UInt64 UInt64Srl(UInt64, int); - -/** - * Perform a bitwise AND (&) of the provided 64 bit integers. - */ -extern UInt64 UInt64And(UInt64, UInt64); - -/** - * Perform a bitwise OR (|) of the provided 64 bit integers. - */ -extern UInt64 UInt64Or(UInt64, UInt64); - -/** - * Perform a bitwise XOR (^) of the provided 64 bit integers. - */ -extern UInt64 UInt64Xor(UInt64, UInt64); - -/** - * Perform a bitwise NOT (~) of the provided 64 bit integer. - */ -extern UInt64 UInt64Not(UInt64); - -/** - * Perform a comparison of the provided 64 bit integers and return a C - * boolean that is true if and only if they are equal. - */ -extern int UInt64Eq(UInt64, UInt64); - -/** - * Perform a comparison of the provided 64 bit integers and return a C - * boolean that is true if and only if the second operand is strictly - * less than the first. - */ -extern int UInt64Lt(UInt64, UInt64); - -/** - * Perform a comparison of the provided 64 bit integers and return a C - * boolean that is true if and only if the second operand is strictly - * greater than the first. - */ -extern int UInt64Gt(UInt64, UInt64); - -#define UInt64Low(a) ((a).i[0]) -#define UInt64High(a) ((a).i[1]) - -#define UInt64Neq(a, b) (!UInt64Eq(a, b)) -#define UInt64Leq(a, b) (UInt64Eq(a, b) || UInt64Lt(a, b)) -#define UInt64Geq(a, b) (UInt64Eq(a, b) || UInt64Gt(a, b)) - -#endif - -#define UINT64_STRBUF 65 /* Base 2 representation with '\0' */ - -/** - * Convert a 64 bit integer to a string in an arbitrary base - * representation specified by the second parameter, using the provided - * buffer and length specified by the third and fourth parameters. To - * guarantee that the string will fit in the buffer, allocate it of - * size UINT64_STRBUF or larger. Note that a buffer size smaller than - * UINT64_STRBUF will invoke undefined behavior. - */ -extern size_t UInt64Str(UInt64, int, char *, size_t); - -#endif /* CYTOPLASM_UINT64_H */ diff --git a/src/include/Util.h b/src/include/Util.h index e7bef57..feafcff 100644 --- a/src/include/Util.h +++ b/src/include/Util.h @@ -43,7 +43,6 @@ #include #include "Stream.h" -#include "UInt64.h" /** * Get the current timestamp in milliseconds since the Unix epoch. This @@ -61,7 +60,7 @@ * overflow before it even gets to this function, which will cause this * function to produce unexpected results. */ -extern UInt64 UtilServerTs(void); +extern uint64_t UtilTsMillis(void); /** * Use @@ -70,7 +69,7 @@ extern UInt64 UtilServerTs(void); * was an error getting the last modified time of a file. This is * primarily useful for caching file data. */ -extern UInt64 UtilLastModified(char *); +extern uint64_t UtilLastModified(char *); /** * This function behaves just like the system call @@ -86,7 +85,7 @@ extern int UtilMkdir(const char *, const mode_t); * .Xr nanosleep 2 * to make its usage much, much simpler. */ -extern int UtilSleepMillis(UInt64); +extern int UtilSleepMillis(uint64_t); /** * This function works identically to the POSIX @@ -112,6 +111,6 @@ extern ssize_t UtilGetLine(char **, size_t *, Stream *); * .Fn pthread_self * to a number. */ -extern UInt32 UtilThreadNo(void); +extern uint32_t UtilThreadNo(void); #endif /* CYTOPLASM_UTIL_H */