diff options
| author | Mattias Andrée <maandree@kth.se> | 2017-11-12 16:16:33 +0100 | 
|---|---|---|
| committer | Mattias Andrée <maandree@kth.se> | 2017-11-12 16:16:33 +0100 | 
| commit | 8cef2ca2598cfd0587faf29d0025d68c7dc598ea (patch) | |
| tree | ee4737fed27a213869eb5ca005194cadf24b9cd2 | |
| parent | Split into multiple units (diff) | |
| download | libsimple-8cef2ca2598cfd0587faf29d0025d68c7dc598ea.tar.gz libsimple-8cef2ca2598cfd0587faf29d0025d68c7dc598ea.tar.bz2 libsimple-8cef2ca2598cfd0587faf29d0025d68c7dc598ea.tar.xz | |
m + add readme
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
| -rw-r--r-- | Makefile | 1 | ||||
| -rw-r--r-- | README | 334 | ||||
| -rw-r--r-- | TODO | 3 | ||||
| -rw-r--r-- | isutf8.c | 8 | ||||
| -rw-r--r-- | libsimple.h | 14 | ||||
| -rw-r--r-- | strcaseends.c | 13 | 
6 files changed, 369 insertions, 4 deletions
| @@ -34,6 +34,7 @@ OBJ =\  	recvfd.o\  	recvfrom_timestamped.o\  	sendfd.o\ +	strcaseends.o\  	strcasestr.o\  	strchrnul.o\  	strends.o\ @@ -0,0 +1,334 @@ +libsimple.h includes most POSIX header files so you do need to include lots of +headers in your code, and defines macros and functions that are useful for most +programs and libraries to simplify the code. It also provides *_MIN and *_MAX +values for integer data types. + +Most functions are namespaced with `libsimple_` and aliased with macro +definitions to unnamespaced names unless there already is a macro with that +name. + +Programs using this library should define `char *argv0` and set it to +the 0:th command line argument. + + + +CLOCK_MONOTONIC_RAW is defined to CLOCK_MONOTONIC unless CLOCK_MONOTONIC_RAW +already exists. + +AF_LOCAL, AF_UNIX, AF_FILE, PF_LOCAL, PF_UNIX, and PF_FILE are defined to +appropriate values provided that AF_LOCAL, AF_UNIX, or AF_FILE is already +defined. + +The following macros are defined, unless already defined: + +	MIN(A, B) +		Select the least of two values. + +	MAX(A, B) +		Select the greatest of two values. + +	MIN3(A, B, C) +		Select the least of three values. + +	MAX3(A, B, C) +		Select the greatest of three values. + +	ELEMSOF(ARR) +		Gets the number of elements in an array. + +	STRLEN(STR) +		Gets the length of a string literal. + +	INTSTRLEN(TYPE) +		Gets the maximum length any value with the integer type TYPE can +		have in base 10. + +	TYPE_MAX(TYPE) +		Get the greatest value storable in an integer type. + +	TYPE_MIN(TYPE) +		Get the least value storable in an integer type. + +	FREE(PTR) +		(free(PTR), (PTR) = NULL, 0) +		Ensures that a pointer is not freed twiced. + +	CLOSE(FD) +		((FD) >= 0 ? (close(FD), (FD) = -1, 0) : 0) +		Ensures that errno is not modified when closing an +		already closed file descriptor. + +	Maximum values: +		BLKCNT64_MAX, BLKCNT_MAX, BLKSIZE_MAX, CC_MAX, CLOCKID_MAX, +		CLOCK_MAX, DEV_MAX, FSBLKCNT64_MAX, FSBLKCNT_MAX, +		FSFILCNT64_MAX, FSFILCNT_MAX, FSID_MAX, FSWORD_MAX, GID_MAX, +		ID_MAX, INO64_MAX, INO_MAX, KEY_MAX, LOFF_MAX, MODE_MAX, +		NLINK_MAX, OFF64_MAX, OFF_MAX, PID_MAX, QUAD_MAX, REGISTER_MAX, +		RLIM64_MAX, RLIM_MAX, SOCKLEN_MAX, SPEED_MAX, SUSECONDS_MAX, +		TCFLAG_MAX, TIMER_MAX, TIME_MAX, UID_MAX, USECONDS_MAX, +		U_QUAD_MAX + +	Minimum values: +		BLKCNT64_MIN, BLKCNT_MIN, BLKSIZE_MIN, CC_MIN, CLOCKID_MIN, +		CLOCK_MIN, DEV_MIN, FSBLKCNT64_MIN, FSBLKCNT_MIN, +		FSFILCNT64_MIN, FSFILCNT_MIN, FSID_MIN, FSWORD_MIN, GID_MIN, +		ID_MIN, INO64_MIN, INO_MIN, KEY_MIN, LOFF_MIN, MODE_MIN, +		NLINK_MIN, OFF64_MIN, OFF_MIN, PID_MIN, QUAD_MIN, REGISTER_MIN, +		RLIM64_MIN, RLIM_MIN, SOCKLEN_MIN, SPEED_MIN, SUSECONDS_MIN, +		TCFLAG_MIN, TIMER_MIN, TIME_MIN, UID_MIN, USECONDS_MIN, +		U_QUAD_MIN + +The following functions are defined (some as inline functions): + +	void *libsimple_rawmemchr(const void *, int) +		Memchr without boundary check. + +	void *libsimple_memrchr(const void *, int, size_t) +		Like memchr, except finds the last occurrence. + +	void *libsimple_rawmemrchr(const void *, int, size_t) +		libsimple_memrchr without boundary check. + +	char *libsimple_strchrnul(const char *, int) +		Like strchr, except returns the end if not found. + +	char *libsimple_strend(const char *s) +		strchr(s, '\0') + +	char *libsimple_inchrset(int c, const char *s) +		c && strchr(s, c) + +	void *libsimple_memdup(const void *, size_t) +		Duplicate a memory segment. + +	char *libsimple_strndup(const char *, size_t) +		Duplicate a substring. + +	void *libsimple_mempcpy(void *, const void *, size_t) +		Like memcpy, except returns the byte after the +		last written byte. + +	int libsimple_isutf8(const char *s, int allow_modified_nul) +		Returns 1 if `s` is valid UTF-8 (Unicode codepoints are not +		validated) and 0 otherwise. If `allow_modified_nul` is non-zero, +		the byte sequence 0xC0 0x80 is allowed. + +	int libsimple_asprintf(char **, const char *, ...) +		Like sprintf accept allocated the buffer. + +	int libsimple_vasprintf(char **, const char *, va_list); +		Like vsprintf accept allocated the buffer. + +	void *libsimple_memmem(const void *s, size_t sn, const void *t, size_t tn) +		Finds the first occurrence of `t` in `s`. +		Length of `s` is `sn`. Length of `t` is `tn`. + +	int libsimple_memstarts(const void *s, size_t sn, const void *t, size_t tn) +		Returns 1 if `s` starts with `t`, 0 otherwise. +		Length of `s` is `sn`. Length of `t` is `tn`. + +	int libsimple_memends(const void *s, size_t sn, const void *t, size_t tn) +		Returns 1 if `s` ends with `t`, 0 otherwise. +		Length of `s` is `sn`. Length of `t` is `tn`. + +	int libsimple_strstarts(const char *s, const char *t) +		Returns 1 if `s` starts with `t`, 0 otherwise. + +	int libsimple_strcasestarts(const char *, const char *) +		Like strstarts except case-insensitive. + +	int libsimple_strends(const char *s, const char *t) +		Returns 1 if `s` ends with `t`, 0 otherwise. + +	int libsimple_strcaseends(const char *, const char *) +		Like strends except case-insensitive. + +	char *libsimple_strcasestr(const char *, const char *) +		Like strstr except case-insensitive. + +	int libsimple_streq(const char *a, const char *b) +		!strncmp(a, b) + +	int libsimple_strneq(const char *a, const char *b, size_t n) +		!strncmp(a, b, n) + +	char *getenv_ne(const char *) +		Like getenv, except returns NULL if the value +		of the environment variable is the empty string. + +	int putenvf(const char *, ...) +		Format a string a call putenv. + +	int vputenvf(const char *, va_list) +		Format a string a call putenv. + +	int libsimple_sendfd(int sock, int fd) +		Send a file descriptor over a socket. + +	int libsimple_recvfd(int sock) +		Receive a file descriptor over a socket. + +	ssize_t libsimple_recvfrom_timestamped(int, void *restrict, size_t, int, +	  struct sockaddr *restrict, socklen_t, struct timespec *restrict) +		Like recvfrom except also returns the a SCM_TIMESTAMP or +		SCM_TIMESTAMPNS timestamp, returns zero as the timestamp +		if missing. + +	ssize_t libsimple_recv_timestamped(int, void *restrict, size_t, int, +	  struct timespec *restrict) +		Like recv except also returns the a SCM_TIMESTAMP or +		SCM_TIMESTAMPNS timestamp, returns zero as the timestamp +		if missing. + +	int libsimple_sumtimespec(struct timespec *, const struct timespec *, +	  const struct timespec *) +		Returns the sum of two timestamps. + +	int libsimple_difftimespec(struct timespec *, const struct timespec *, +	  const struct timespec *) +		Returns the difference of two timestamps. + +	int libsimple_multimespec(struct timespec *, const struct timespec *, int) +		Multiplies a timestamp with an integer. + +	int libsimple_cmptimespec(const struct timespec *, const struct timespec *) +		Compares two timestamps, same return semantics as strcmp. + +	int libsimple_sumtimeval(struct timeval *, const struct timeval *, +	  const struct timeval *) +		Returns the sum of two timestamps. + +	int libsimple_difftimeval(struct timeval *, const struct timeval *, +	  const struct timeval *) +		Returns the difference of two timestamps. + +	int libsimple_multimeval(struct timeval *, const struct timeval *, int) +		Multiplies a timestamp with an integer. + +	int libsimple_cmptimeval(const struct timeval *, const struct timeval *) +		Compares two timestamps, same return semantics as strcmp. + +	void libsimple_timeval2timespec(struct timespec *restrict, +	  const struct timeval *restrict) +		Converts a struct timeval to a struct timespec. + +	int libsimple_timespec2timeval(struct timeval *restrict, +	  const struct timespec *restrict) +		Converts a struct timespec to a struct timeval. + +	int libsimple_strtotimespec(struct timespec *restrict, +	  const char *restrict, char **restrict) +		Converts a string to a struct timespec. + +	int libsimple_strtotimeval(struct timeval *restrict, +	  const char *restrict, char **restrict) +		Converts a string to a struct timeval. + +	char *libsimple_timespectostr(char *restrict, +	  const struct timespec *restrict) +		Converts a struct timespec to a string. + +	char *libsimple_timevaltostr(char *restrict, +	  const struct timeval *restrict) +		Converts a struct timeval to a string. + +	double libsimple_timespectodouble(const struct timespec *) +		Converts a struct timespec to a double. + +	double libsimple_timevaltodouble(const struct timeval *) +		Converts a struct timeval to a double. + +	void libsimple_doubletotimespec(struct timespec *, double) +		Converts a double to a struct timespec. + +	void libsimple_doubletotimeval(struct timeval *, double) +		Converts a double to a struct timeval. + +	void libsimple_unlist(void *list, size_t i, size_t *np, size_t width) +		Removes element `i` from the list `list`. `*np` shall be the +		number of elements in the list, it will be updated by the +		function. `width` shall be the byte-width of each element. + +		The macro LIBSIMPLE_UNLIST(LIST, I, NP) (alias to UNLIST if no +		such macro already exists) is idential to libsimple_unlist +		except `width` is automatically. + +	char *strdupa(const char *) +		Like `strdup`, except the returned pointer is stack-allocated. +		This function is implemented as a macro and is only available +		when compiling with GCC or clang. + +	char *strndupa(const char *, size_t) +		Like `strndup`, except the returned pointer is stack-allocated. +		This function is implemented as a macro and is only available +		when compiling with GCC or clang. + +	void *memdupa(const void *, size_t) +		Like `memdup`, except the returned pointer is stack-allocated. +		This function is implemented as a macro and is only available +		when compiling with GCC or clang. + +	char *asprintfa(const char *, ...) +		Like `asprintf` accept the the buffer is stack-allocated and +		returned instead of stored in a pointer. This function is +		implemented as a macro and is only available when compiling with +		GCC or clang. + +	char *vasprintfa(const char *, va_list) +		Like `vasprintf` accept the the buffer is stack-allocated and +		returned instead of stored in a pointer. This function is +		implemented as a macro and is only available when compiling with +		GCC or clang. + +	void weprintf(const char *fmt, ...) +		Similar to printf, except prints to stderr and: +		* unless `fmt` starts with "usage: " the `argv` follow by +		  ": " is prepended to the printed string, +		* if `fmt` ends with ":", " " followed by `strerror(errno)` +		  and "\n" and appended to the printed string, and +		* if `fmt` does not end with ":" or "\n", "\n" and appended to +		  the printed string. + +	void vweprintf(const char *, va_list) +		Identical to weprintf, except using va_list. + +	void eprintf(const char *fmt, ...) +		Like weprintf, but calls exit(libsimple_default_failure_exit) +		afterwards. + +		libsimple.h defines `extern int libsimple_default_failure_exit`. + +	void veprintf(const char *fmt, va_list) +		Like veprintf, but calls exit(libsimple_default_failure_exit) +		afterwards. + +		libsimple.h defines `extern int libsimple_default_failure_exit`. + +	void enprintf(int status, const char *, ...) +		Like weprintf, but calls exit(stats) afterwards. + +	void venprintf(int status, const char *, va_list) +		Like vweprintf, but calls exit(stats) afterwards. + +The following functions, which call `eprintf` on failure, are also defined: + +	void eputenvf(const char *, ...) +	void evputenvf(const char *, va_list) +	void *emalloc(size_t) +	void *ecalloc(size_t, size_t) +	void *erealloc(void *, size_t) +	char *estrdup(const char *) +	char *estrndup(const char *, size_t) +	void *ememdup(const void *, size_t) + +The following functions, which call `enprintf` on failure, are also defined, +the first argument is used as the first argument for `enprintf`: + +	void enputenvf(int, const char *, ...) +	void envputenvf(int, const char *, va_list) +	void *enmalloc(int, size_t) +	void *encalloc(int, size_t, size_t) +	void *enrealloc(int, void *, size_t) +	char *enstrdup(int, const char *) +	char *enstrndup(int, const char *, size_t) +	void *enmemdup(int, const void *, size_t) @@ -0,0 +1,3 @@ +memrmem +strrstr +strnstr @@ -29,7 +29,7 @@ libsimple_isutf8(const char *string, int allow_modified_nul)                          if ((c & 0xC0) == 0x80)                                  /* Single-byte character marked as multibyte, or                                     a non-first byte in a multibyte character. */ -                                return -1; +                                return 0;                          /* Multibyte character. */                          while ((c & 0x80)) @@ -39,14 +39,14 @@ libsimple_isutf8(const char *string, int allow_modified_nul)                          if (bytes > 6)                                  /* 31-bit characters can be encoded with 6-bytes,                                     and UTF-8 does not cover higher code points. */ -                                return -1; +                                return 0;                  } else {                          /* Not first byte of the character. */                          if ((c & 0xC0) != 0x80)                                  /* Beginning of new character before a                                     multibyte character has ended. */ -                                return -1; +                                return 0;                          character = (character << 6) | (c & 0x7F); @@ -59,7 +59,7 @@ libsimple_isutf8(const char *string, int allow_modified_nul)                                  character >>= 1, bits++;                          bits = (!bits && bytes == 2 && allow_modified_nul) ? 8 : bits;                          if (bits < BYTES_TO_MIN_BITS[bytes] || BYTES_TO_MAX_BITS[bytes] < bits) -                                return -1; +                                return 0;                          read_bytes = bytes = bits = 0;                  } diff --git a/libsimple.h b/libsimple.h index 019d261..575d36d 100644 --- a/libsimple.h +++ b/libsimple.h @@ -717,6 +717,13 @@ int libsimple_strstarts(const char *, const char *);  _LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__))) +int libsimple_strcasestarts(const char *__s, const char *__t) { return !strncasecmp(__s, __t, strlen(__t)); } +#ifndef strcasestarts +# define strcasestarts libsimple_strcasestarts +#endif + + +_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))  int libsimple_strends(const char *, const char *);  #ifndef strends  # define strends libsimple_strends @@ -724,6 +731,13 @@ int libsimple_strends(const char *, const char *);  _LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__))) +int libsimple_strcaseends(const char *, const char *); +#ifndef strcaseends +# define strcaseends libsimple_strcaseends +#endif + + +_LIBSIMPLE_GCC_ONLY(__attribute__((__pure__, __nonnull__, __warn_unused_result__)))  char *libsimple_strcasestr(const char *, const char *);  #ifndef strcasestr  # define strcasestr libsimple_strcasestr diff --git a/strcaseends.c b/strcaseends.c new file mode 100644 index 0000000..a672b0a --- /dev/null +++ b/strcaseends.c @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include "libsimple.h" + + +int +libsimple_strcaseends(const char *s, const char *t) +{ +	size_t sn = strlen(s); +	size_t tn = strlen(t); +	if (tn > sn) +		return 0; +	return !strcasecmp(&s[sn - tn], t); +} | 
