aboutsummaryrefslogblamecommitdiffstats
path: root/libsimple.h
blob: 5758582ef13d5fcb8cbede1ce666f0f95fde2060 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13




                                                         







                                                                   


                        
                      









                       
                   

                   

                  
                

                     




                   
                   
                   




                    
                 
                   

                   

 




                                                                                                                              
 
                                            






                                            

                                    
     

                                      

      





                                            
                               

                                    
     

                                      

      
                               

                                    
     

                                      
      
 
                               

                                    
     

                                      


                               

                                    
     

                                      


      


                                                                                           

 








                                                         
                               
                             

                                  

                                     



                                      





                                      



                              
                                      





                                
                                     
                                    



                                      
                          
                              
                            

                           
                               
                             
                             
                          
                          
                           

                            
                           
                            

 









                                                        
                                                  
          
                           
 

                       
                         


                              
 
 

   













                                                                                                      









                                                                                             
                                                                                          
              
                                                                

      








                                                                             
                                                  
           
                                                                        
 

                                                                                               





                                

                                                                                                           





                                                                                          
                                                                      





                                                                                        
                                                                      




                                                                
                                                        




                                                                                                       











                                                                                                        
                                                                                                                            




                                          
                                                                                                                     





                                    
 








                                            
      
/* See LICENSE file for copyright and license details. */
#ifndef LIBSIMPLE_H
#define LIBSIMPLE_H


#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdocumentation"
# pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
# pragma clang diagnostic ignored "-Wreserved-identifier"
# pragma clang diagnostic ignored "-Wdisabled-macro-expansion"
#endif

#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <aio.h>
#include <alloca.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
#include <inttypes.h>
#include <limits.h>
#include <netdb.h>
#include <poll.h>
#include <pwd.h>
#include <setjmp.h>
#include <signal.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <time.h>
#include <unistd.h>
#include <wchar.h>
#include <wctype.h>


#if defined(__GLIBC__) && (__GLIBC_PREREQ(2, 29) ? defined(_DEFAULT_SOURCE) : (__GLIBC_PREREQ(2, 26) && defined(_GNU_SOURCE)))
# define reallocarray reallocarray
#endif



#if defined(__GNUC__) && !defined(__clang__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Winline"
#endif



#if defined(__GNUC__) && !defined(__clang__)
# define LIBSIMPLE_GCC_ONLY__(x) x
# define LIBSIMPLE_NON_GCC_ONLY__(x)
#else
# define LIBSIMPLE_GCC_ONLY__(x)
# define LIBSIMPLE_NON_GCC_ONLY__(x) x
#endif

#if defined(__GNUC__)
# define LIBSIMPLE_EXTENSION__ __extension__
#else
# define LIBSIMPLE_EXTENSION__
#endif

#if __STDC_VERSION__ >= 199409L
# define LIBSIMPLE_C95_ONLY__(x) x
# define LIBSIMPLE_PRE_C95_ONLY__(x)
#else
# define LIBSIMPLE_C95_ONLY__(x)
# define LIBSIMPLE_PRE_C95_ONLY__(x) x
#endif

#if __STDC_VERSION__ >= 199901L
# define LIBSIMPLE_C99_ONLY__(x) x
# define LIBSIMPLE_PRE_C99_ONLY__(x)
#else
# define LIBSIMPLE_C99_ONLY__(x)
# define LIBSIMPLE_PRE_C99_ONLY__(x) x
#endif

#if __STDC_VERSION__ >= 201112L
# define LIBSIMPLE_C11_ONLY__(x) x
# define LIBSIMPLE_PRE_C11_ONLY__(x)
#else
# define LIBSIMPLE_C11_ONLY__(x)
# define LIBSIMPLE_PRE_C11_ONLY__(x) x
#endif

#if __STDC_VERSION__ >= 201710L
# define LIBSIMPLE_C17_ONLY__(x) x
# define LIBSIMPLE_PRE_C17_ONLY__(x)
#else
# define LIBSIMPLE_C17_ONLY__(x)
# define LIBSIMPLE_PRE_C17_ONLY__(x) x
#endif


#define libsimple_assume_aligned_as__(TYPE)\
	LIBSIMPLE_C11_ONLY__(__assume_aligned__(_Alignof(TYPE)))\
	LIBSIMPLE_PRE_C11_ONLY__(LIBSIMPLE_GCC_ONLY__(__assume_aligned__(__alignof(TYPE))))


#if __STDC_VERSION__ >= 201112L
# define LIBSIMPLE_NORETURN _Noreturn /* TODO doc, man */
#elif defined(__GNUC__) || defined(__clang__)
# define LIBSIMPLE_NORETURN __attribute__((noreturn))
#else
# define LIBSIMPLE_NORETURN
#endif


#include "libsimple/overflow.h"
#include "libsimple/printf.h"
#include "libsimple/definitions.h"
#include "libsimple/memalloc.h"
#include "libsimple/memdup.h"
#include "libsimple/aligned_memdup.h"
#include "libsimple/strdup.h"
#include "libsimple/aligned_strdup.h"
#include "libsimple/strndup.h"
#include "libsimple/aligned_strndup.h"
#include "libsimple/wmemdup.h"
#include "libsimple/aligned_wmemdup.h"
#include "libsimple/wcsdup.h"
#include "libsimple/aligned_wcsdup.h"
#include "libsimple/wcsndup.h"
#include "libsimple/aligned_wcsndup.h"
#include "libsimple/mallocz.h"
#include "libsimple/malloc.h"
#include "libsimple/calloc.h"
#include "libsimple/realloc.h"
#include "libsimple/aligned_realloc.h"
#include "libsimple/memalignz.h"
#include "libsimple/memalign.h"
#include "libsimple/vallocz.h"
#include "libsimple/valloc.h"
#include "libsimple/pvallocz.h"
#include "libsimple/pvalloc.h"
#include "libsimple/aligned_allocz.h"
#include "libsimple/aligned_alloc.h"
#include "libsimple/posix_memalignz.h"
#include "libsimple/posix_memalign.h"
#include "libsimple/env.h"
#include "libsimple/time.h"
#include "libsimple/mem.h"
#include "libsimple/memelem.h"
#include "libsimple/array.h"
#include "libsimple/str.h"
#include "libsimple/strn.h"
#include "libsimple/strtoint.h"
#include "libsimple/search.h"
#include "libsimple/random.h"
#include "libsimple/abs.h"
#include "libsimple/net.h"
#include "libsimple/path.h"
#include "libsimple/ascii.h"
#include "libsimple/exec.h"
#include "libsimple/sort.h"
#include "libsimple/stack.h"


/**
 * Wrapper for close(3) that only calls close(3)
 * if the file descriptor number is non-negative,
 * and that will set it to -1 after closing
 * 
 * @param   fdp  Pointer to file descriptor number, will
 *               be update to -1 if it is non-negative
 * @return       Return value of close(3) (0 on success,
 *               -1 on error), 0 if `*fdp < 0`
 */
LIBSIMPLE_GCC_ONLY__(__attribute__((__nonnull__)))
inline int
libsimple_close(int *fdp__)
{
	int ret__;
	if (*fdp__ < 0)
		return 0;
	ret__ = close(*fdp__);
	*fdp__ = -1;
	return ret__;
}


/**
 * Close a range of file descriptors
 *
 * @param   first   The lowest file descriptor to close
 * @param   last    The highest file descriptor to close
 * @param   next    Output parameter for the potentially first unclosed file descriptor; may be `NULL`
 * @return          0 on successful completion, -1 on failure
 * @throws  EINVAL  If `first > last`
 * @throws          Any error for close(3) except EBADF
 */
int libsimple_close_range(unsigned int first, unsigned int last, unsigned int *next);
#define LIBSIMPLE_CLOSE_RANGE_MAX (~0U)


/**
 * Remove an item from a list, keeping the list ordered
 * 
 * `list` must be non-void pointer to a complete type,
 * the type of the pointer will be used to infer the
 * width of the items in the list
 * 
 * @param  list:non-void pointer  The list
 * @param  i:size_t               The index of the item to remove
 * @param  n:size_t               Pointer to the number of items in the list, will be updated
 */
#define LIBSIMPLE_UNLIST(LIST, I, NP) libsimple_unlist((LIST), (I), (NP), sizeof(*(LIST)))
#ifndef UNLIST
# define UNLIST(LIST, I, NP) LIBSIMPLE_UNLIST((LIST), (I), (NP))
#endif


/**
 * Remove an item from a list, keeping the list ordered
 * 
 * @param  list   The list
 * @param  i      The index of the item to remove
 * @param  n      Pointer to the number of items in the list, will be updated
 * @param  width  The width, in bytes, of each item in the list
 */
LIBSIMPLE_GCC_ONLY__(__attribute__((__nonnull__)))
inline void
libsimple_unlist(void *list__, size_t i__, size_t *np__, size_t width__)
{
        char *lst__ = list__;
        memmove(&lst__[i__ * width__], &lst__[(i__ + 1) * width__], (--*np__ - i__) * width__);
}
#ifndef unlist
# define unlist libsimple_unlist
#endif


#define LIBSIMPLE_REMOVE_CONST__(X, TYPE, ...) (*(TYPE *)(void *)&(X))
#define LIBSIMPLE_REMOVE_CONST(...) LIBSIMPLE_REMOVE_CONST__(__VA_ARGS__, void *) /* TODO test, doc, man */
#ifndef REMOVE_CONST
# define REMOVE_CONST(...) LIBSIMPLE_REMOVE_CONST(__VA_ARGS__)
#endif


#define LIBSIMPLE_PREFETCH_RDONLY(ADDRESS, LOCALITY) /* void */ /* TODO test, doc, man */\
	LIBSIMPLE_GCC_ONLY__(__builtin_prefetch(ADDRESS, 0, LOCALITY))
#ifndef PREFETCH_RDONLY
# define PREFETCH_RDONLY(...) LIBSIMPLE_PREFETCH_RDONLY(__VA_ARGS__)
#endif


#define LIBSIMPLE_PREFETCH_RDWR(ADDRESS, LOCALITY) /* void */ /* TODO test, doc, man */\
	LIBSIMPLE_GCC_ONLY__(__builtin_prefetch(ADDRESS, 1, LOCALITY))
#ifndef PREFETCH_RDWR
# define PREFETCH_RDWR(...) LIBSIMPLE_PREFETCH_RDWR(__VA_ARGS__)
#endif


#define LIBSIMPLE_ASSUME_ALIGNED__(PTR, ALIGNMENT, ...)\
	LIBSIMPLE_GCC_ONLY__(__builtin_assume_aligned(PTR, ALIGNMENT))\
	LIBSIMPLE_NON_GCC_ONLY__(PTR)
#define LIBSIMPLE_ASSUME_ALIGNED(PTR, ...) /* returns PTR */ /* TODO test, doc, man */\
	LIBSIMPLE_ASSUME_ALIGNED__(PTR, ##__VA_ARGS__, LIBSIMPLE_C11_ONLY__(_Alignof(*PTR)) /* no , */\
	                           LIBSIMPLE_PRE_C11_ONLY__(__alignof(*PTR)))
#ifndef ASSUME_ALIGNED
# define ASSUME_ALIGNED(...) LIBSIMPLE_ASSUME_ALIGNED(__VA_ARGS__)
#endif


#define LIBSIMPLE_ASSUME_MISALIGNED(PTR, ALIGNMENT, OFFSET) /* returns PTR */ /* TODO test, doc, man */\
	__builtin_assume_aligned(PTR, ALIGNMENT, OFFSET)
#ifndef ASSUME_MISALIGNED
# define ASSUME_MISALIGNED(...) LIBSIMPLE_ASSUME_MISALIGNED(__VA_ARGS__)
#endif


#define LIBSIMPLE_UNROLLED(N) LIBSIMPLE_GCC_ONLY__(LIBSIMPLE_C11_ONLY__(_Pragma("GCC unroll "#N))) /* TODO test, doc, man */
#ifndef UNROLLED
# define UNROLLED(N) LIBSIMPLE_UNROLLED(N)
#endif


#define LIBSIMPLE_SIMDLOOP LIBSIMPLE_GCC_ONLY__(LIBSIMPLE_C11_ONLY__(_Pragma("GCC ivdep"))) /* TODO test, doc, man */
#ifndef SIMDLOOP
# define SIMDLOOP LIBSIMPLE_SIMDLOOP
#endif




#if defined(__GNUC__) && !defined(__clang__)
# pragma GCC diagnostic pop
#endif

#if defined(__clang__)
# pragma clang diagnostic pop
#endif


#endif