Merge branch 'dev'

This commit is contained in:
Nils O. Selåsdal
2013-10-27 13:33:56 +01:00
39 changed files with 1474 additions and 146 deletions
+2 -10
View File
@@ -1,5 +1,5 @@
#ifndef BITEVEC_H_
#define BITEVEC_H_
#ifndef UC_BITEVEC_H_
#define UC_BITEVEC_H_
#ifdef __cplusplus
extern "C" {
@@ -65,14 +65,6 @@ void uc_bv_set_all(struct UCBitVec *v);
* */
void uc_bv_set_bits_from_array(struct UCBitVec *v,char *array,size_t array_len);
// The _s ("secure") versions does boundary checking and assert() if they
// try to access a bit out of bounds.
void uc_bv_set_bit_s(struct UCBitVec *v,int b);
void uc_bv_clear_bit_s(struct UCBitVec *v,int b);
int uc_bv_get_bit_s(const struct UCBitVec *v,int b);
#ifdef __cplusplus
}
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef UCORE_BUFFER_H_
#define UCORE_BUFFER_H_
#ifndef UC_BUFFER_H_
#define uc_BUFFER_H_
#include <stddef.h>
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef dbuf_H_
#define dbuf_H_
#ifndef UC_DBUF_H_
#define UC_DBUF_H_
#include <stdlib.h>
#ifdef __cplusplus
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef FD_UTILS_H_
#define FD_UTILS_H_
#ifndef UC_FD_UTILS_H_
#define UC_FD_UTILS_H_
#ifdef __cplusplus
extern "C" {
#endif
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef UCORE_HASH_H_
#define UCORE_HASH_H_
#ifndef UC_HASH_H_
#define UC_HASH_H_
#include <stddef.h>
#include <stdint.h>
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef UCORE_HEAPSORT_H_
#define UCORE_HEAPSORT_H_
#ifndef UC_HEAPSORT_H_
#define UC_HEAPSORT_H_
#include <stddef.h>
+279
View File
@@ -0,0 +1,279 @@
#ifndef UC_HTABLE_H_
#define UC_HTABLE_H_
#include <stddef.h>
/** Building block for hash table.
* The hash table is stored using a chained list of buckets.
* Nodes with different hash value can be stored in the same bucket.
*
*
* The hash table manages only the hash value, not the equality
* between nodes.
*
* It's up to the user to check for duplicate values
* before adding nodes if dublicates are not desired.
*
* Finding a node must be done in a user specific way,
* normally by iterating over all nodes with the desidred
* hash, and deciding in some other way whether it is the desidred
* node.
*/
/** Node the hashtable tracks.
* Will normally be embedded inside another struct
*/
struct UHNode {
//cached value of the hash
size_t hash;
//pointer to next in same bucket
struct UHNode *next;
};
/**
* The hash table struct
*/
struct UHTable {
size_t cnt_elements;
size_t cnt_buckets;
struct UHNode **buckets;
};
/**
* Initialize a hash table.
* @param table hash table to initialize
* @param buckets number of buckets
* @return 0 on success, errno if malloc fails or buckets == 0
*/
int uc_htable_init(struct UHTable *table, size_t buckets);
/**
* Free resources of the hash table.
* @param table hash table to free (does not free @table itself
*/
void uc_htable_destroy(struct UHTable *table);
/**
* @param table
* @param hash find the bucket from this hash value
* @return the bucket number for the given hash
*/
static inline size_t uc_htable_bucket(const struct UHTable *table, size_t hash)
{
return hash % table->cnt_buckets;
}
/**
* Get the first bucket node for the given hash.
* The returned node might not have the same hash, since different
* nodes can share the same bucket.
*
* @param table table
* @param hash hash
*/
static inline struct UHNode *uc_htable_first_bucket(const struct UHTable *table, size_t hash)
{
size_t bucket = uc_htable_bucket(table, hash);
return table->buckets[bucket];
}
/**
* Get the next node in the bucket.
* @return next node or NULL
*/
static inline struct UHNode *uc_htable_next_bucket(const struct UHNode *node)
{
return node->next;
}
/**
* Get the first node that have the given hash
* @param table table
* @param hash hash
* @return first node with the given hash or NULL
*/
struct UHNode *uc_htable_first_hash(const struct UHTable *table, size_t hash);
//internal helper
struct UHNode *uc_htable_next_hash_hlp(struct UHNode *next, size_t hash);
/**
* Get the next node with the same hash
* @param node previous node
* @return next node with the same hash as node or NULL
*/
static inline struct UHNode *uc_htable_next_hash(const struct UHNode *node)
{
return uc_htable_next_hash_hlp(node->next, node->hash);
}
//internal helper
struct UHNode *uc_htable_iter_hlp(struct UHTable *table, size_t bucket);
/** Get the first node in the hash table
*
* @param table table
* @return first node or NULL
*/
static inline struct UHNode *uc_htable_first(struct UHTable *table)
{
return uc_htable_iter_hlp(table, 0);
}
/** Get the next node in the hash table
*
* @param table table
* @param node previous node
* @return first node or NULL
*/
struct UHNode *uc_htable_next(struct UHTable *table, struct UHNode *node);
/**
* Swap 2 hash tables.
*
* @param a first table
* @param b second table
*/
void uc_htable_swap(struct UHTable *a, struct UHTable *b);
/**
* Iterate over all nodes in a bucket.
* The table must not be changed while iterating.
*
* @param table the struct UHTable*
* @param node_iter struct UHNode* for the current node being iterated
* @param hash size_t hash for the bucket to iterate
*/
#define UC_HTABLE_FOREACH_BUCKET(table, node_iter, hash)\
for ((node_iter) = uc_htable_first_bucket((table), (hash));\
(node_iter) != NULL;\
(node_iter) = uc_htable_next_bucket((node_iter)))
/**
* Iterate over all nodes that has the given hash.
* The table must not be changed while iterating.
* Normally the user would check in a user specific way
* if the node_iter is equal to the node one wants to find.
*
* @param table the struct UHTable*
* @param node_iter struct UHNode* for the current node being iterated
* @param hash size_t hash for the node(s) to iterate over
*/
#define UC_HTABLE_FOREACH_HASH(table, node_iter, hash)\
for ((node_iter) = uc_htable_first_hash((table), (hash));\
(node_iter) != NULL;\
(node_iter) = uc_htable_next_hash((node_iter)))
/**
* "Safe" variant of UC_HTABLE_FOREACH_HASH, the iterated node
* (or any previously iterated nodes) can be freed while iterating
*
* @param table the struct UHTable*
* @param node_iter struct UHNode* for the current node being iterated
* @param next_iter struct UHNode* for the next node, required by the
* iteration, next_iter must not be altered while iterating.
* @param hash size_t hash for the node(s) to iterate over
*/
#define UC_HTABLE_FOREACH_HASH_SAFE(table, node_iter, next_iter, hash)\
for ((node_iter) = uc_htable_first_hash((table), (hash));\
(node_iter) != NULL && (((next_iter) = (node_iter->next)), 1);\
(node_iter) = (next))
/**
* Iterate over all nodes in a table
* The table must not be changed while iterating.
*
* @param table the struct UHTable*
* @param node_iter struct UHNode* for the current node being iterated
*/
#define UC_HTABLE_FOREACH(table, node_iter)\
for ((node_iter) = uc_htable_first((table));\
(node_iter) != NULL;\
(node_iter) = uc_htable_next((table), (node_iter)))
/**
* "Safe" variant of UC_HTABLE_FOREACH, the iterated node
* (or any previously iterated nodes) can be freed while iterating
*
* @param table the struct UHTable*
* @param node_iter struct UHNode* for the current node being iterated
* @param next_iter struct UHNode* for the next node, required by the
* iteration, next_iter must not be altered while iterating.
*/
#define UC_HTABLE_FOREACH_SAFE(table, node_iter, next_iter)\
for ((node_iter) = uc_htable_first((table));\
(node_iter) != NULL &&\
((next_iter) = uc_htable_next((table), (node_iter)), 1);\
(node_iter) = (next))
/**
* Check if the given node pointer exists in the hash table
*
* @param table table
* @param node node to check for
* @return 0 if the node does not exist in table non-0 if it does
*/
int uc_htable_has_node(struct UHTable *table, struct UHNode *node);
/**
*
* @return 0 if table is empty non-0 if it contains any nodes
*/
static inline int uc_htable_isempty(const struct UHTable *table)
{
return table->cnt_elements == 0;
}
/**
* Get number of elements in the hash table.
*
* @rparam table table
* @return number of elements
*/
static inline size_t uc_htable_count(const struct UHTable *table)
{
return table->cnt_elements;
}
/** Clears all nodes from the hash table, making it empty.
* No memory is released.
* @param table table to clear
*/
void uc_htable_clear(struct UHTable *table);
/** Insert a new node.
* The new node pointer must exist as long as it is part of the
* hash table. The hash table does not check for duplicates in any way.
*
* @param table table to insert into
* @param node new node to insert.
* @param hash hash value of the new node
*/
void uc_htable_insert(struct UHTable *table, struct UHNode *node, size_t hash);
/** Remove a node.
* If the node pointer is not part of the table,
* no action is taken
*
* @param table table to remove from.
* @param node node to remove.
*/
void uc_htable_remove(struct UHTable *table, struct UHNode *node);
/** Resize the hash table. This changes the number of buckets, and re-inserts
* all nodes.
*
* @param table table to resize
* @param buckets new number of buckets, must be > 0
* @return 0 on success, errno if malloc fails or buckets == 0
*/
int uc_htable_resize(struct UHTable *table, size_t buckets);
#endif
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef IO_MUX_H_
#define IO_MUX_H_
#ifndef UC_IO_MUX_H_
#define UC_IO_MUX_H_
#include "timers.h"
/** @addtogroup IOMux
+12 -9
View File
@@ -1,5 +1,6 @@
#ifndef UCORE_LOGGING_H_
#define UCORE_LOGGING_H_
#ifndef UC_LOGGING_H_
#define UC_LOGGING_H_
#include "utils.h"
/** Logging functions.
* All logging functions except uc_log_init are thread safe,
@@ -268,14 +269,16 @@ int uc_log_reopen_files(void);
void uc_log_init(struct uc_log_modules *user_modules);
void uc_logf(int log_level, int module, int raw,
const char *file, int line, const char *fmt, ...)
__attribute__((format(printf, 6, 7)));
const char *location, const char *fmt, ...)
__attribute__((format(printf, 5, 6)));
#ifdef DEBUG
// only compile in UC_DEBUG log calls in debug mode, but allow the user
// to override that by defining UC_DEBUG_ALWAYS
#if defined(DEBUG) || defined(UC_DEBUG_ALWAYS)
# define UC_DEBUGF(mod, fmt, ...)\
uc_logf(UC_LL_DEBUG, mod,0 , __FILE__, __LINE__, fmt, ## __VA_ARGS__)
uc_logf(UC_LL_DEBUG, mod,0 , UC_SRC_LOCATION, fmt, ## __VA_ARGS__)
# define UC_DEBUGFR(mod, fmt, ...)\
uc_logf(UC_LL_DEBUG, mod,1 , __FILE__, __LINE__, fmt, ## __VA_ARGS__)
uc_logf(UC_LL_DEBUG, mod,1 , UC_SRC_LOCATION, fmt, ## __VA_ARGS__)
#else
# define UC_DEBUGF(mod, fmt, ...)
# define UC_DEBUGFR(mod, fmt, ...)
@@ -292,14 +295,14 @@ void uc_logf(int log_level, int module, int raw,
* @param ... printf style arguments
*/
#define UC_LOGF(lvl, mod, fmt, ...) \
uc_logf(lvl, mod, 0, __FILE__, __LINE__, fmt, ## __VA_ARGS__)
uc_logf(lvl, mod, 0, UC_SRC_LOCATION, fmt, ## __VA_ARGS__)
/** Raw logging ,Like UC_LOGF, but only prints the supplied
* data, not timestamp, log level etc.
*/
#define UC_LOGFR(lvl, mod, fmt, ...) \
uc_logf(lvl, mod, 1, __FILE__, __LINE__, fmt, ## __VA_ARGS__)
uc_logf(lvl, mod, 1, UC_SRC_LOCATION, fmt, ## __VA_ARGS__)
#ifdef __cplusplus
}
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef UCORE_MATH_H_
#define UCORE_MATH_H_
#ifndef UC_MATH_H_
#define UC_MATH_H_
#include <stdint.h>
+1
View File
@@ -30,6 +30,7 @@ struct MBuf {
/**Arbitary pointer user can associate with the mbuf*/
void *cookie;
/*UC_MBUF_FLAGS. The upper 16 bits can be used by the application */
uint32_t flags;
/** Total no of bytes from bufstart*/
uint32_t allocated;
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef UCORE_MERSENNE_TWISTER_H
#define UCORE_MERSENNE_TWISTER_H
#ifndef UC_MERSENNE_TWISTER_H
#define UC_MERSENNE_TWISTER_H
#ifdef __cplusplus
extern "C" {
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef UCORE_PACK_H_
#define UCORE_PACK_H_
#ifndef UC_PACK_H_
#define UC_PACK_H_
#include <stdint.h>
#ifdef __GNUC__
+106
View File
@@ -0,0 +1,106 @@
#ifndef UC_RATE_LIMIT_H_
#define UC_RATE_LIMIT_H_
/** This is a rate limiter, based on the token bucket principle.
* We have X amount of tickets(=our rate) per Y amount of time,
*
* The allowed tickets increases with X per Y amount of time.
*
* Bursts will be allowed up till the number of tickets initially
* specified.
* e.g. if we are limited to 50 tickets * per 2 second, 50 tickets
* can be immedietely handed out in the
* first second. At the 2. second, 25 more tickets become available
* handed out, at the 3. second 25 more, and so on.
* (So this is throttleed, so no more than the initial tickets, 50 in
* this case, can be handed out in any given period)
*
* Another example is if we rate 1000 tickets per 60 seconds,
* 1000 tickets can be handed out the 1. second, 16/17 more the
* next second, 16/17 more the 3. second and so on.
*
* Specify how many tickes we have available per period of time.
* when work is performed, call uc_ratelimit_cllow() with the current
* time.
* The unit of time passed to uc_ratelimit_allow must be the same as
* for uc_ratelimit_init.
*
* Example for rate limiting accepting connections:
* struct RateLimit r;
* //Limit to 20 per 1 second, which also limits us to max 20
* per second. (1 second since we will pass in time that have 1 second resolution)
* 40 per 2 second would even out to the same rate, but allow a burst of 40
* (if there's 40 tickets available)
*
* uc_ratelimit_init(&r,20, 1, time(NULL));
*
* NOTE. (period + 1) * tickets must not exceed the range of the RateLimit.funds
*
* for (;;) {
* int fd = accept(..);
* if (uc_ratelimit_allow(&r, time(NULL)) {
* //handle new connection
* } else {
* //exceeded limit
* close(fd);
* }
* }
*/
struct RateLimit {
//how many tickets we want
long tickets;
//per this period of time
long period;
//internal fields:
//money we have to "buy" tickets
long funds;
//time of the previos period
long last_ts;
};
/** Static initializer for a struct RateLimit
*
* @param tickets number of tickets (bucket depth)
* @param period per this period
*/
#define UC_RATELIMIT_INITIALIZER(tickets)\
{ tickets, period, 0, -period}
/**
* Initialize a struct RateLimit, which can hand out @tickets per @period
* the perioid must be in the same units as the current_ts
*
* NOTE. 2 * (period + 1) * tickets must not exceed the range of the RateLimit.funds
*
* @param r RateLimit to initialize
* @param tickets number of tickets (bucket depth)
* @param period per this period
*/
void uc_ratelimit_init(struct RateLimit *r, long tickets, long period);
/**
* Reset a RateLimit, filling up the tickets again.
*
* @param r RateLimit to reset
* @param current ts, if non-zero, re-sets the last_ts to the current_ts
*/
void uc_ratelimit_reset(struct RateLimit *r, long current_ts);
/**
* Check if we have 1 ticket available, and can therefore allow
* the work. Removes 1 ticket if we can, and replenishes the tickets
* based on the elapsed time since last time the function was called.
*
* @param r the RateLimit
* @param current_ts the current timestamp. Used to calculate the
* replenisment of tichets since the previous check.
* @return 1 if we can allow, 0 if we don't.
*/
int uc_ratelimit_allow(struct RateLimit *r, long current_ts);
#endif
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef RBTREE_H_
#define RBTREE_H_
#ifndef UC_RBTREE_H_
#define UC_RBTREE_H_
#ifdef __cplusplus
extern "C" {
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef UCORE_READ_FILE_H_
#define UCORE_READ_FILE_H_y
#ifndef UC_READ_FILE_H_
#define UC_READ_FILE_H_y
#include <stddef.h>
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef SALLOC_H_
#define SALLOC_H_
#ifndef UC_SALLOC_H_
#define UC_SALLOC_H_
#include <stddef.h>
+3
View File
@@ -1,3 +1,5 @@
#ifndef UC_SATMATH_H_
#define UC_SATMATH_H_
#include <stdint.h>
/** Implementation of saturated operation on uintxx_t.
@@ -79,3 +81,4 @@ static inline uint64_t uc_sat_multu64(uint64_t a, uint64_t b)
return UC_SAT_MULT(a, b, uint64_t, UINT64_MAX);
}
#endif
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef SEQ_H_
#define SEQ_H_
#ifndef UC_SEQ_H_
#define UC_SEQ_H_
#include <stdint.h>
// Check if a is less than b, taking care of wrap arounds
+39 -4
View File
@@ -1,5 +1,5 @@
#ifndef UCORE_STRING_H_
#define UCORE_STRING_H_
#ifndef UC_STRING_H_
#define UC_STRING_H_
#include <stddef.h>
#include <stdint.h>
@@ -17,16 +17,48 @@ uc_hex_decode(const char *in, size_t maxlen,uint8_t *out);
char*
uc_hex_encode_delim(const uint8_t *in, size_t inlen, char *out, int outlen, char *delim);
/**
* Convert the string to lowercase, calls tolower() on each char.
* @param s string to lowercase
*/
void
uc_str_tolower(char *s);
/**
* Convert the string to uppercase, calls toupper() on each char.
* @param s string to uppercase
*/
void
uc_str_toupper(char *s);
/** Macro to calculate the number of bytes required to BCD encode
* the number of ascii digits
*/
#define UC_BCD_LEN(ascii_len) ((ascii_len) / 2 + ((ascii_len) % 2))
#define UC_ASCII_LEN(bcd_len) ((bcd_len) * 2 + 1)
/** Macro to calculate the number of bytes required to ASCII encode
* the number of BCD digits
*/
#define UC_ASCII_LEN(bcd_len) ((bcd_len) * 2)
/** Convert the ascii digits to BCD. Digits not in 0..9 are skipped.
*
* @param ascii string to BCD encode.
* @param bcdout resulting BCD data. Must be at least UC_BCD_LEN(strlen(asciii)) big
* @param filler filler byte(not the ascii digit) to write in the last BCD nibble
* if the number of ASCII digits is odd. This would usually be 0x0 or 0xf.
* @return the number of bytes written to bcdout
*/
size_t
uc_ascii2bcd(const char *ascii, unsigned char *bcdout, unsigned char filler);
/** Convert the BCD digits to ascii.
* The resulting ascii string is 0 terminated.
*
* @param bcd Buffer with BCD data to convert to ascii
* @param bcdlen number of bytes in @bcd to convert
* @param asciiout buffer to place ASCII in, must be UC_ASCII_LEN(bcdlen)+1 big
* @return the number of characters written to bcdout (this will always be UC_ASCII_LEN(bcdlen)
*/
size_t
uc_bcd2ascii(const unsigned char *bcd, size_t bcdlen, char *asciiout);
@@ -39,10 +71,13 @@ uc_sprintbll(char *result, unsigned long long value);
char*
uc_sprintbs(char *result, unsigned short value);
/** Like http://swtch.com/plan9port/man/man3/getfields.html
*/
int
getfields(char *str, char **args, int max, int mflag, const char *set);
//ocnvert bytes to a human representable test, (i.e. 12kB, 160 MB 1.78 GB etc.
//Converts bytes to a human representable test, (i.e. 12kB, 160 MB 1.78 GB etc.)
//Conversion is done in decimal (base 10 ,1 kB == 1000 bytes)
///result should be at least of size 12,
///returns the result argument
char *
+3 -2
View File
@@ -1,8 +1,9 @@
#include <stddef.h>
#ifndef UC_STRVEC_H_
#define UC_STRVEC_H_
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef UCORE_SUPERVISOR_H_
#define UCORE_SUPERVISOR_H_
#ifndef UC_SUPERVISOR_H_
#define UC_SUPERVISOR_H_
/** Supervises this process - restart if it dies.
*
+23 -6
View File
@@ -1,5 +1,5 @@
#ifndef _THREADQUEUE_H_
#define _THREADQUEUE_H_ 1
#ifndef UC_THREADQUEUE_H_
#define UC_THREADQUEUE_H_
#include <pthread.h>
@@ -44,7 +44,7 @@ struct uc_threadmsg{
/**
* Callback function for the walk and destroy functions.
*/
typedef void (*uc_thread_queue_walk_func) (struct uc_threadmsg *msg);
typedef void (*uc_thread_queue_walk_func) (struct uc_threadmsg *msg, void *cookie);
/**
@@ -240,23 +240,40 @@ long uc_thread_queue_length( struct uc_threadqueue *queue );
* @param queue Pointer to the queue that should be cleaned
* @param free_func pointer to function that will be called for each item.
* The function must not in anyway interact with the queue.
* @param cookie pointer passed back to the uc_thread_queue_walk_func
* @return 0 on success EINVAL if queue is NULL EBUSY if someone is holding any locks on the queue
*/
int uc_thread_queue_destroy(struct uc_threadqueue *queue, uc_thread_queue_walk_func free_func);
int uc_thread_queue_destroy(struct uc_threadqueue *queue, uc_thread_queue_walk_func free_func, void *cookie);
/**
* Walk the elements of the queue, intended for debugging
*
* The supplied function will be called for each item in the queue, internal queue
* locks are held while the function is called, so the supplied function must not
* interact with the queue, else deadlock occors.
* interact with the queue, else deadlock occurs.
*
* @param queue Pointer to the queue to walk
* @param free_func pointer to function that will be called for each item.
* @param cookie pointer passed back to the uc_thread_queue_walk_func
* The function must not in anyway interact with the queue.
* @return 0 on success
*/
int uc_thread_queue_walk(struct uc_threadqueue *queue, uc_thread_queue_walk_func walk_func);
int uc_thread_queue_walk(struct uc_threadqueue *queue, uc_thread_queue_walk_func walk_func, void *cookie);
/**
* Clear the queue.
* The free_func unless NULL, will be called for each element
* locks are held while the function is called, so the supplied function must not
* interact with the queue, else deadlock occurs.
*
* @param queue Pointer to the queue to clear
* @param free_func pointer to function that will be called for each item, intended to e.g. release memory
* @param cookie pointer passed back to the uc_thread_queue_walk_func
* @return 0 on success
*/
int uc_thread_queue_clear(struct uc_threadqueue *queue, uc_thread_queue_walk_func free_func, void *cookie);
/**
* @}*/
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef UCORE_TIMERS_H_
#define UCORE_TIMERS_H_
#ifndef UC_TIMERS_H_
#define UC_TIMERS_H_
#include <stddef.h>
#include <sys/queue.h>
+34 -21
View File
@@ -1,23 +1,16 @@
#ifndef UCORE_UTILS_H_
#define UCORE_UTILS_H_
#ifndef UC_UTILS_H_
#define UC_UTILS_H_
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include "backtrace.h"
//Gnerate a compiler error if the compile time
//constant expression fails
#define UC_STATIC_ASSERT(expr) \
do { \
enum { assert_static__ = 1/(expr) }; \
} while (0)
enum { assert_static__ = 1/(expr) };
#ifdef DEBUG
#define TRACEF(fmt, ...)\
do { \
fprintf(stdout, "%s:%d (%s)\t" fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);\
fflush(stdout);\
} while(0)
#else
#define TRACEF(fmt, ...)
#endif
//MAX of a and b
#define UC_MAX(a,b) \
@@ -78,22 +71,42 @@ const typeof( ((const type *)0)->member ) *__mptr = (ptr); \
#define UC_STRINGIFY(x) UC_STRINGIFY_HLP(x)
#define UC_STRINGIFY_HLP(x) #x
/** Macro that expands to a string for the current file:line
*/
#define UC_SRC_LOCATION __FILE__ ":" UC_STRINGIFY(__LINE__)
/**
* assert() that is not affected by NDEBUG define
*/
#define UC_ASSERT(expr) do {\
if (!(expr) ) {\
fprintf(stderr,\
"UC_ASSERT failed '%s' %s:%d\n", UC_STRINGIFY(expr), __FILE__, __LINE__);\
uc_backtrace_fd(3);\
abort();\
#define UC_ASSERT(expr)\
do {\
if (!(expr) ) {\
fprintf(stderr,\
"UC_ASSERT failed '%s' %s\n", UC_STRINGIFY(expr), UC_SRC_LOCATION);\
uc_backtrace_fd(2);\
abort();\
}\
} while (0)
#ifdef DEBUG
#define TRACEF(fmt, ...)\
do { \
fprintf(stdout, "%s (%s)\t" fmt, UC_SRC_LOCATION, __FUNCTION__, ##__VA_ARGS__);\
fflush(stdout);\
} while(0)
#else
#define TRACEF(fmt, ...)
#endif
/**
* Macro for asserting code that should not be reached,
* terminates the program if executed
*/
#define UC_NOT_REACED() abort()
#define UC_NOT_REACED()\
do {\
fprintf(stderr, "UC_NOT_REACED at %s\n", UC_SRC_LOCATION);\
uc_backtrace_fd(2);\
abort();\
while (0)
/**
* Round up X / y
+2 -2
View File
@@ -1,5 +1,5 @@
#ifndef UCORE_VERSION_H_
#define UCORE_VERSION_H_
#ifndef UC_VERSION_H_
#define UC_VERSION_H_
/**
* @mainpage
* @htmlonly