Merge branch 'cmake'
This commit is contained in:
@@ -8,3 +8,6 @@ log_subdir/
|
|||||||
coverage/
|
coverage/
|
||||||
install/
|
install/
|
||||||
libucore-*
|
libucore-*
|
||||||
|
src/version.c
|
||||||
|
.cache/
|
||||||
|
compile_commands.json
|
||||||
|
|||||||
Vendored
+15
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Mac",
|
||||||
|
"includePath": [
|
||||||
|
"${default}",
|
||||||
|
"${workspaceFolder}/include"
|
||||||
|
],
|
||||||
|
"defines": [],
|
||||||
|
"compilerPath": "/usr/bin/clang",
|
||||||
|
"intelliSenseMode": "macos-clang-arm64"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 4
|
||||||
|
}
|
||||||
Vendored
+11
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"*.h": "c",
|
||||||
|
},
|
||||||
|
"C_Cpp.default.includePath": [
|
||||||
|
"/opt/homebrew/include/",
|
||||||
|
"$(workspaceFolder)/include/",
|
||||||
|
|
||||||
|
],
|
||||||
|
"C_Cpp.default.cStandard": "gnu99"
|
||||||
|
}
|
||||||
Vendored
+19
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"type": "cmake",
|
||||||
|
"label": "CMake: build",
|
||||||
|
"command": "build",
|
||||||
|
"targets": [
|
||||||
|
"all"
|
||||||
|
],
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"problemMatcher": [],
|
||||||
|
"detail": "CMake template build task"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.12)
|
||||||
|
project(libucore C)
|
||||||
|
|
||||||
|
execute_process(COMMAND git -C ${CMAKE_SOURCE_DIR} describe --abbrev=5 --dirty --always OUTPUT_VARIABLE version_revision WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
cmake_host_system_information(RESULT build_host QUERY HOSTNAME)
|
||||||
|
set(libucore_VERSION_MAJOR 1)
|
||||||
|
set(libucore_VERSION_MINOR 0)
|
||||||
|
set(libucore_VERSION_PATCH 0)
|
||||||
|
set(libucore_VERSION ${libucore_VERSION_MAJOR}.${libucore_VERSION_MINOR}.${libucore_VERSION_PATCH}.${version_revision})
|
||||||
|
|
||||||
|
set(CMAKE_VERBOSE_MAKEFILE ON)
|
||||||
|
|
||||||
|
set(CMAKE_C_STANDARD 11)
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wundef -Wcast-qual -Wshadow -Wcast-align -pipe -Wno-unused-parameter -Werror=implicit-function-declaration -Winit-self")
|
||||||
|
add_definitions(-D_FILE_OFFSET_BITS=64)
|
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -O2")
|
||||||
|
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
option(CODE_COVERAGE "build with code coverage intrumentation" OFF)
|
||||||
|
|
||||||
|
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||||
|
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
|
||||||
|
# Set the property for multi-config generators as well, if applicable
|
||||||
|
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Debug Release RelWithDebInfo MinSizeRel)
|
||||||
|
endif()
|
||||||
|
set(build_type ${CMAKE_BUILD_TYPE})
|
||||||
|
if (CODE_COVERAGE)
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage")
|
||||||
|
add_definitions(-DCOVERAGE)
|
||||||
|
set(build_type "${build_type}-coverage")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
option(BUILD_SANITIZE "build with address sanitizer" OFF)
|
||||||
|
if (BUILD_SANITIZE)
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
|
||||||
|
set(build_type "${build_type}-sanitize")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
include_directories(include)
|
||||||
|
|
||||||
|
add_subdirectory(src)
|
||||||
|
add_subdirectory(test)
|
||||||
|
add_subdirectory(include)
|
||||||
|
|
||||||
@@ -1192,7 +1192,7 @@ MATHJAX_EXTENSIONS =
|
|||||||
# typically be disabled. For large projects the javascript based search engine
|
# typically be disabled. For large projects the javascript based search engine
|
||||||
# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
|
# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
|
||||||
|
|
||||||
SEARCHENGINE = NO
|
SEARCHENGINE = YES
|
||||||
|
|
||||||
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
|
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
|
||||||
# implemented using a PHP enabled web server instead of at the web client
|
# implemented using a PHP enabled web server instead of at the web client
|
||||||
|
|||||||
+11
-1
@@ -66,6 +66,13 @@ AddOption('--stack-protection',
|
|||||||
help = 'Build with stack protection support'
|
help = 'Build with stack protection support'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
AddOption('--sanitizer',
|
||||||
|
dest = 'sanitizer',
|
||||||
|
action='store_true',
|
||||||
|
default=False,
|
||||||
|
help = 'Build with gcc sanitizer'
|
||||||
|
)
|
||||||
|
|
||||||
AddOption('--32',
|
AddOption('--32',
|
||||||
dest='force32bit',
|
dest='force32bit',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
@@ -126,6 +133,10 @@ if GetOption('coverage'):
|
|||||||
env.Append(CFLAGS = ['--coverage'])
|
env.Append(CFLAGS = ['--coverage'])
|
||||||
env.Append(LINKFLAGS = ['--coverage'])
|
env.Append(LINKFLAGS = ['--coverage'])
|
||||||
|
|
||||||
|
if GetOption('sanitizer'):
|
||||||
|
env.Append(CFLAGS = ['-fsanitize=undefined', '-fsanitize=address'])
|
||||||
|
env.Append(LINKFLAGS = ['-fsanitize=undefined', '-fsanitize=address'])
|
||||||
|
|
||||||
# Generate substitute dictionary
|
# Generate substitute dictionary
|
||||||
subst_info = dict(('@' + key + '@', version_info[key]) for key in version_info)
|
subst_info = dict(('@' + key + '@', version_info[key]) for key in version_info)
|
||||||
subst_info['@prefix@'] = prefix
|
subst_info['@prefix@'] = prefix
|
||||||
@@ -164,4 +175,3 @@ env.Package(target = 'libucore-' + version_info['version_str'] + '.tar.gz',
|
|||||||
X_RPM_GROUP = 'Development/Libraries'
|
X_RPM_GROUP = 'Development/Libraries'
|
||||||
)
|
)
|
||||||
|
|
||||||
env.Default('src')
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
install(DIRECTORY ucore DESTINATION include)
|
||||||
@@ -27,7 +27,7 @@ struct UCBitVec {
|
|||||||
* Use as
|
* Use as
|
||||||
* @code
|
* @code
|
||||||
* uc_bv_integer v[10];
|
* uc_bv_integer v[10];
|
||||||
* struct UCBitVec v = BITVEC_STATIC_INIT(v);
|
* struct UCBitVec v = UC_BV_STATIC_INIT(v);
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
#define UC_BV_STATIC_INIT(vec_data)\
|
#define UC_BV_STATIC_INIT(vec_data)\
|
||||||
@@ -68,11 +68,16 @@ void uc_bv_set_all(struct UCBitVec *v);
|
|||||||
/** Initialize bits from a array of ints, each array element maps to one bit.
|
/** Initialize bits from a array of ints, each array element maps to one bit.
|
||||||
* The bits are initialized from the int array so zero maps to zero and non-zero maps to one.
|
* The bits are initialized from the int array so zero maps to zero and non-zero maps to one.
|
||||||
* e..g to set the 5 first bits, to 01110:
|
* e..g to set the 5 first bits, to 01110:
|
||||||
* int a[] = {0,1,1,1,0};
|
* int a[] = {0,1,1,1,0};
|
||||||
* set_bits_from_array(v,a,5);
|
* set_bits_from_array(v,a,5);
|
||||||
* */
|
* */
|
||||||
void uc_bv_set_bits_from_array(struct UCBitVec *v,const char *array,size_t array_len);
|
void uc_bv_set_bits_from_array(struct UCBitVec *v,const char *array,size_t array_len);
|
||||||
|
|
||||||
|
/** Find the index of the first zero bit in the bitvec.
|
||||||
|
* @param v The bitvec to search
|
||||||
|
* @return The index of the first zero bit, or -1 if all bits are set
|
||||||
|
*/
|
||||||
|
int uc_bv_find_first_zero(const struct UCBitVec *v);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,15 @@
|
|||||||
#define UC_IOMUX_SIGNAL_H_
|
#define UC_IOMUX_SIGNAL_H_
|
||||||
|
|
||||||
#include "ucore/iomux.h"
|
#include "ucore/iomux.h"
|
||||||
|
|
||||||
|
/** @addtogroup IOMux
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Callback signature for handling unix signals.
|
/** Callback signature for handling unix signals.
|
||||||
* @param mux associated mux
|
* @param mux associated mux
|
||||||
* @param signo unix signal number
|
* @param signo unix signal number
|
||||||
@@ -45,4 +54,10 @@ int iomux_register_unixsignal(struct IOMux *mux,
|
|||||||
*/
|
*/
|
||||||
int iomux_unregister_unixsignal(struct IOMux *mux, int signo);
|
int iomux_unregister_unixsignal(struct IOMux *mux, int signo);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** @} (addtogroup)*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -10,10 +10,34 @@
|
|||||||
*
|
*
|
||||||
* multiplication, subtraction and addition operations are provided.*/
|
* multiplication, subtraction and addition operations are provided.*/
|
||||||
|
|
||||||
|
//Use gcc builtins, supported since GCC 5
|
||||||
|
#if __GNUC__ >= 5
|
||||||
|
|
||||||
|
#define UC_SAT_ADD(a, b, type, max_val)\
|
||||||
|
({type res ;\
|
||||||
|
if (__builtin_add_overflow(a, b, &res)) {\
|
||||||
|
res = max_val;}\
|
||||||
|
res;})
|
||||||
|
|
||||||
|
|
||||||
|
#define UC_SAT_SUB(a, b, type)\
|
||||||
|
({type res ;\
|
||||||
|
if (__builtin_sub_overflow(a, b, &res)) {\
|
||||||
|
res = 0;}\
|
||||||
|
res;})
|
||||||
|
|
||||||
|
#define UC_SAT_MULT(a, b, type, max_val)\
|
||||||
|
({type res ;\
|
||||||
|
if (__builtin_mul_overflow(a, b, &res)) {\
|
||||||
|
res = max_val;}\
|
||||||
|
res;})
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
#define UC_SAT_ADD(a, b, type, max_val)\
|
#define UC_SAT_ADD(a, b, type, max_val)\
|
||||||
((type)((a) + (b)) >= (a) ? (a) + (b) : (max_val))
|
((type)((a) + (b)) >= (a) ? (a) + (b) : (max_val))
|
||||||
|
|
||||||
#define UC_SAT_SUB(a, b)\
|
#define UC_SAT_SUB(a, b, type)\
|
||||||
((a) >= (b) ? (a) - (b) : 0)
|
((a) >= (b) ? (a) - (b) : 0)
|
||||||
|
|
||||||
#define UC_SAT_MULT(a, b, type, max_val)\
|
#define UC_SAT_MULT(a, b, type, max_val)\
|
||||||
@@ -21,6 +45,7 @@
|
|||||||
(a) <= (max_val) / (b) ? (type) (a) * (type) (b) \
|
(a) <= (max_val) / (b) ? (type) (a) * (type) (b) \
|
||||||
: (max_val))
|
: (max_val))
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline uint8_t uc_sat_addu8(uint8_t a, uint8_t b)
|
static inline uint8_t uc_sat_addu8(uint8_t a, uint8_t b)
|
||||||
{
|
{
|
||||||
@@ -29,7 +54,7 @@ static inline uint8_t uc_sat_addu8(uint8_t a, uint8_t b)
|
|||||||
|
|
||||||
static inline uint8_t uc_sat_subu8(uint8_t a, uint8_t b)
|
static inline uint8_t uc_sat_subu8(uint8_t a, uint8_t b)
|
||||||
{
|
{
|
||||||
return UC_SAT_SUB(a, b);
|
return UC_SAT_SUB(a, b, uint8_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint8_t uc_sat_multu8(uint8_t a, uint8_t b)
|
static inline uint8_t uc_sat_multu8(uint8_t a, uint8_t b)
|
||||||
@@ -44,7 +69,7 @@ static inline uint16_t uc_sat_addu16(uint16_t a, uint16_t b)
|
|||||||
|
|
||||||
static inline uint16_t uc_sat_subu16(uint16_t a, uint16_t b)
|
static inline uint16_t uc_sat_subu16(uint16_t a, uint16_t b)
|
||||||
{
|
{
|
||||||
return UC_SAT_SUB(a, b);
|
return UC_SAT_SUB(a, b, uint16_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint16_t uc_sat_multu16(uint16_t a, uint16_t b)
|
static inline uint16_t uc_sat_multu16(uint16_t a, uint16_t b)
|
||||||
@@ -59,7 +84,7 @@ static inline uint32_t uc_sat_addu32(uint32_t a, uint32_t b)
|
|||||||
|
|
||||||
static inline uint32_t uc_sat_subu32(uint32_t a, uint32_t b)
|
static inline uint32_t uc_sat_subu32(uint32_t a, uint32_t b)
|
||||||
{
|
{
|
||||||
return UC_SAT_SUB(a, b);
|
return UC_SAT_SUB(a, b, uint32_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t uc_sat_multu32(uint32_t a, uint32_t b)
|
static inline uint32_t uc_sat_multu32(uint32_t a, uint32_t b)
|
||||||
@@ -74,7 +99,7 @@ static inline uint64_t uc_sat_addu64(uint64_t a, uint64_t b)
|
|||||||
|
|
||||||
static inline uint64_t uc_sat_subu64(uint64_t a, uint64_t b)
|
static inline uint64_t uc_sat_subu64(uint64_t a, uint64_t b)
|
||||||
{
|
{
|
||||||
return UC_SAT_SUB(a, b);
|
return UC_SAT_SUB(a, b, uint64_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint64_t uc_sat_multu64(uint64_t a, uint64_t b)
|
static inline uint64_t uc_sat_multu64(uint64_t a, uint64_t b)
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
#ifndef UC_SLOT_ALLOCATOR_H_
|
||||||
|
#define UC_SLOT_ALLOCATOR_H_
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "ucore/bitvec.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/** @file
|
||||||
|
* Fixed size slot memory allocator
|
||||||
|
*
|
||||||
|
* UCSlotAlloc is used to allocate fixed slots of memory from a pre-allocated
|
||||||
|
* piece of memory.
|
||||||
|
*
|
||||||
|
* The main use case is to keep allocated memory in a contiguous block for use
|
||||||
|
* maximum number of objects(slots) is known and relatively small. More than 131072 slots
|
||||||
|
* is not recommended.
|
||||||
|
*
|
||||||
|
* Note that this allocator is not thread safe.
|
||||||
|
*
|
||||||
|
* A bitmap is used to track which slots are allocated.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct UCSlotAlloc UCSlotAlloc;
|
||||||
|
struct UCSlotAlloc {
|
||||||
|
const uint32_t slot_size;
|
||||||
|
const uint32_t num_slots;
|
||||||
|
struct UCBitVec bitmap;
|
||||||
|
uint8_t *slots;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** Initialize a UCSlotAlloc with an array as the backing memory to allocate slots from.
|
||||||
|
* The macro can be used at local scope to allocate memory automatic (stack) storage,
|
||||||
|
* or at global scope where the backin array will have static storage duration
|
||||||
|
*
|
||||||
|
* Use as:
|
||||||
|
* @code
|
||||||
|
* UC_SLOT_ALLOC_DEF(my_allocator, sizeof foo, 1024)
|
||||||
|
* struct foo *foo = uc_slot_alloc(&my_allocator);
|
||||||
|
* if (foo == NULL) {
|
||||||
|
* // out of memory
|
||||||
|
* } else {
|
||||||
|
* .. use foo
|
||||||
|
* uc_slot_free(&my_allocator, foo);
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* @param var_name Variable name for the allocator
|
||||||
|
* @param v slot_size Memory size allocated for each slot
|
||||||
|
* @param v num_slots Number of slots to reserve memory for
|
||||||
|
*/
|
||||||
|
#define UC_SLOT_ALLOC_DEF(var_name, slot_size_, num_slots_) \
|
||||||
|
struct {\
|
||||||
|
uc_bv_integer bitmap[UC_BV_LEN((num_slots_))]; \
|
||||||
|
uint8_t memory[(num_slots_) * (slot_size_)] __attribute__((aligned)); \
|
||||||
|
} var_name ## _memory = { \
|
||||||
|
}; \
|
||||||
|
UCSlotAlloc var_name = { \
|
||||||
|
.slot_size = (slot_size_), \
|
||||||
|
.num_slots = (num_slots_), \
|
||||||
|
.bitmap = UC_BV_STATIC_INIT(var_name ## _memory.bitmap), \
|
||||||
|
.slots = var_name ## _memory.memory \
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Similar to UC_SLOT_ALLOC_DEF but allows you to specify the backing memory that must
|
||||||
|
* be atleast as large as num_slots * slot_size. Note that an array of num_slots * slot_size
|
||||||
|
* bits is also allocated for the bitmap with this definition
|
||||||
|
*/
|
||||||
|
#define UC_SLOT_ALLOC_DEF_EX(var_name, slot_size_, num_slots_, memory) \
|
||||||
|
uc_bv_integer var_name ## _bitmap[UC_BV_LEN((num_slots_))] = {}; \
|
||||||
|
UCSlotAlloc var_name = { \
|
||||||
|
.slot_size = (slot_size_), \
|
||||||
|
.num_slots = (num_slots_), \
|
||||||
|
.bitmap = UC_BV_STATIC_INIT(var_name ## _bitmap), \
|
||||||
|
.slots = (memory) \
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Allocate a memory slot
|
||||||
|
*
|
||||||
|
* @param sa The allocator to allocate from
|
||||||
|
* @return A pointer to the memory slot that's sa.slot_size big, or NULL if
|
||||||
|
* all slots are allocated
|
||||||
|
*/
|
||||||
|
void *uc_slot_alloc(UCSlotAlloc *sa);
|
||||||
|
|
||||||
|
|
||||||
|
/** Free a memory slot previously returned from uc_slot_alloc()
|
||||||
|
*
|
||||||
|
* @param sa The allocator to free from.
|
||||||
|
* @param slot The memory slot to free. Passing a NULL pointer is undefined behavior
|
||||||
|
*/
|
||||||
|
void uc_slot_free(UCSlotAlloc *restrict sa, void *restrict slot);
|
||||||
|
|
||||||
|
/** uc_slot_free() where the slot can be a NULL pointer */
|
||||||
|
#define uc_slot_free_safe(sa, slot) \
|
||||||
|
do { \
|
||||||
|
if ((slot) != NULL) { \
|
||||||
|
uc_slot_free((sa), (slot)); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -96,7 +96,8 @@ char* uc_sprintbs(char *result, unsigned short value);
|
|||||||
|
|
||||||
/** Like http://swtch.com/plan9port/man/man3/getfields.html
|
/** Like http://swtch.com/plan9port/man/man3/getfields.html
|
||||||
*/
|
*/
|
||||||
int getfields(char *str, char **args, int max, int mflag, const char *set);
|
int uc_getfields(char *str, char **args, int max, int mflag, const char *sep);
|
||||||
|
int uc_gettokens(char *str, char **args, int max, const char *sep);
|
||||||
|
|
||||||
//Converts 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.)
|
||||||
///result should be at least of size 12,
|
///result should be at least of size 12,
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ void uc_strv_init(struct UCStrv *strv);
|
|||||||
int uc_strv_grow(struct UCStrv *strv, size_t cnt);
|
int uc_strv_grow(struct UCStrv *strv, size_t cnt);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expand the UCStrv to hold attleast 1 more item if needed
|
* If needed, grow the UCStrv to hold atleast 1 more item.
|
||||||
*
|
*
|
||||||
* @param strv UCStrv to expand
|
* @param strv UCStrv to expand
|
||||||
* @return 0 on success, otherwise failure
|
* @return 0 on success, otherwise failure
|
||||||
@@ -46,7 +46,7 @@ int uc_strv_grow(struct UCStrv *strv, size_t cnt);
|
|||||||
int uc_strv_check_expand(struct UCStrv *strv);
|
int uc_strv_check_expand(struct UCStrv *strv);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append a string to the UCStrv, the string will be copied in
|
* Append a string to the UCStrv, the string will be copied in.
|
||||||
*
|
*
|
||||||
* @param strv UCStrv to append to
|
* @param strv UCStrv to append to
|
||||||
* @param str String to append, the string will be copied.
|
* @param str String to append, the string will be copied.
|
||||||
@@ -55,7 +55,7 @@ int uc_strv_check_expand(struct UCStrv *strv);
|
|||||||
int uc_strv_append(struct UCStrv *strv, const char *restrict str);
|
int uc_strv_append(struct UCStrv *strv, const char *restrict str);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append a string to the strvec, nocopy variang.
|
* Append a string to the strvec without making a copy of the string.
|
||||||
* The string shold be dynamically allocated, as
|
* The string shold be dynamically allocated, as
|
||||||
* destroying the UCStrv will free() all items.
|
* destroying the UCStrv will free() all items.
|
||||||
*
|
*
|
||||||
@@ -67,7 +67,7 @@ int uc_strv_append_nocopy(struct UCStrv *strv, char *restrict str);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Append a NULL pointer to the UCStrv, (cnt is not increased,
|
* Append a NULL pointer to the UCStrv, (cnt is not increased,
|
||||||
* so another _appended item will overwrite this NULL terminator)
|
* so another appended item will overwrite this NULL terminator)
|
||||||
*
|
*
|
||||||
* @param strv UCStrv to append to
|
* @param strv UCStrv to append to
|
||||||
* @return 0 on success, otherwise failure
|
* @return 0 on success, otherwise failure
|
||||||
@@ -101,6 +101,11 @@ void uc_strv_destroy(struct UCStrv *strv);
|
|||||||
*/
|
*/
|
||||||
int uc_strv_append_all(struct UCStrv *restrict a, struct UCStrv *restrict b, int copy);
|
int uc_strv_append_all(struct UCStrv *restrict a, struct UCStrv *restrict b, int copy);
|
||||||
|
|
||||||
|
/** Reverse the order of strings in a UCStrv
|
||||||
|
*
|
||||||
|
* @param strv strv to reverse.
|
||||||
|
*/
|
||||||
|
void uc_strv_reverse(struct UCStrv *strv);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -96,6 +96,8 @@ void uc_timers_init_ex(struct UCTimers *t, struct UCoreClock *uclock);
|
|||||||
* will be called when the timer expires, and the timer is removed from the engine
|
* will be called when the timer expires, and the timer is removed from the engine
|
||||||
* User is responsible for the lifetime and memory of the UCTimer, which must exist until
|
* User is responsible for the lifetime and memory of the UCTimer, which must exist until
|
||||||
* te timer is fired or removed.
|
* te timer is fired or removed.
|
||||||
|
* If the timer has previously been added, it will be removed first. So there
|
||||||
|
* is no need to call uc_timers_remove() to "re-schedule" a timer.
|
||||||
*
|
*
|
||||||
* @param timers timer engine to add timer to.
|
* @param timers timer engine to add timer to.
|
||||||
* @param timer timer to add
|
* @param timer timer to add
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
// int i;
|
// int i;
|
||||||
// struct bar zap;
|
// struct bar zap;
|
||||||
//};
|
//};
|
||||||
// ...
|
// ...
|
||||||
//struct bar *p = ..; //the local p is a pointer to
|
//struct bar *p = ..; //the local p is a pointer to
|
||||||
//a 'zap' member inside a struct foo.
|
//a 'zap' member inside a struct foo.
|
||||||
//give us the struct foo*:
|
//give us the struct foo*:
|
||||||
@@ -55,7 +55,7 @@ const typeof( ((const type *)0)->member ) *__mptr = (ptr); \
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if x is a power of 2
|
* Test if x is a power of 2
|
||||||
*
|
*
|
||||||
* @param x value, must be an unsigned type
|
* @param x value, must be an unsigned type
|
||||||
* @return 1 if x is a power of 20, 0 if it is not
|
* @return 1 if x is a power of 20, 0 if it is not
|
||||||
*/
|
*/
|
||||||
@@ -90,7 +90,7 @@ const typeof( ((const type *)0)->member ) *__mptr = (ptr); \
|
|||||||
*
|
*
|
||||||
* @param x numerator, must be positive
|
* @param x numerator, must be positive
|
||||||
* @param y denominator
|
* @param y denominator
|
||||||
* @return x/y rounded up
|
* @return x/y rounded up
|
||||||
*/
|
*/
|
||||||
#define UC_DIV_ROUND_UP(x, y) (((x) + ((y) - 1))/(y))
|
#define UC_DIV_ROUND_UP(x, y) (((x) + ((y) - 1))/(y))
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ const typeof( ((const type *)0)->member ) *__mptr = (ptr); \
|
|||||||
* @param y denominator
|
* @param y denominator
|
||||||
* @return x rounded up to nearest multiple of y
|
* @return x rounded up to nearest multiple of y
|
||||||
*/
|
*/
|
||||||
#define UC_ROUND_UP(x, y) (UC_DIV_ROUND_UP((x), (y)) * (y))
|
#define UC_ROUND_UP(x, y) (UC_DIV_ROUND_UP((x), (y)) * (y))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Round x down to nearest multiple of y
|
* Round x down to nearest multiple of y
|
||||||
|
|||||||
+51
-4
@@ -4,6 +4,17 @@
|
|||||||
#include "mbuf.h"
|
#include "mbuf.h"
|
||||||
#include "iomux.h"
|
#include "iomux.h"
|
||||||
|
|
||||||
|
/** @addtogroup IOMux
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return code from users write callback
|
||||||
|
*/
|
||||||
enum UC_WQ_RESULT {
|
enum UC_WQ_RESULT {
|
||||||
/** INdicates the MBuf was fully processed and can be freed*/
|
/** INdicates the MBuf was fully processed and can be freed*/
|
||||||
UC_WQ_DONE = 1,
|
UC_WQ_DONE = 1,
|
||||||
@@ -13,6 +24,8 @@ enum UC_WQ_RESULT {
|
|||||||
UC_WQ_ABORT = -1
|
UC_WQ_ABORT = -1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct UCWQueue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback that will be called when data can be written to the fd.
|
* Callback that will be called when data can be written to the fd.
|
||||||
* The return value from this function must be strictly followed.
|
* The return value from this function must be strictly followed.
|
||||||
@@ -38,7 +51,9 @@ enum UC_WQ_RESULT {
|
|||||||
* for this event.
|
* for this event.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef enum UC_WQ_RESULT (*wqueue_write_cb)(struct IOMux *mux, struct IOMuxFD *fd, struct MBuf *mbuf);
|
typedef enum UC_WQ_RESULT (*wqueue_write_cb)(struct IOMux *mux,
|
||||||
|
struct UCWQueue *wqueue,
|
||||||
|
struct MBuf *mbuf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback when read events are indicated.
|
* Callback when read events are indicated.
|
||||||
@@ -49,17 +64,43 @@ typedef enum UC_WQ_RESULT (*wqueue_write_cb)(struct IOMux *mux, struct IOMuxFD *
|
|||||||
* @param mux associated IOMux
|
* @param mux associated IOMux
|
||||||
* @param the fd of the current wqueue
|
* @param the fd of the current wqueue
|
||||||
*/
|
*/
|
||||||
typedef enum UC_WQ_RESULT (*wqueue_read_cb)(struct IOMux *mux, struct IOMuxFD *fd);
|
typedef enum UC_WQ_RESULT (*wqueue_read_cb)(struct IOMux *mux,
|
||||||
|
struct UCWQueue *wqueue);
|
||||||
|
|
||||||
/** Represents a queue of data to write.
|
/**
|
||||||
|
* Callback to free a MBuf once it's fully written.
|
||||||
|
* @param the fd of the current wqueue
|
||||||
|
*/
|
||||||
|
typedef void (*wqueue_free_mbuf_cb)(struct MBuf *mbuf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a queue of data to write.
|
||||||
|
* UCWQueue replaces a raw IOMuxFD, and manages a queue
|
||||||
|
* of data to write, held as a list of struct MBuf.
|
||||||
|
* See also uc_wqueue_init
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
struct UCWQueue {
|
struct UCWQueue {
|
||||||
|
/** Underlying IOMuxFD. This member needs to be registered
|
||||||
|
* with an IOMux, see the description of uc_wqueue_init
|
||||||
|
*/
|
||||||
struct IOMuxFD fd;
|
struct IOMuxFD fd;
|
||||||
|
/** Linked list of struct MBuf
|
||||||
|
*/
|
||||||
struct TailQ queue;
|
struct TailQ queue;
|
||||||
|
/** Associated mux
|
||||||
|
*/
|
||||||
struct IOMux *mux;
|
struct IOMux *mux;
|
||||||
|
/** Users callback for read events
|
||||||
|
*/
|
||||||
wqueue_read_cb read_cb;
|
wqueue_read_cb read_cb;
|
||||||
|
/** Users callback for write events
|
||||||
|
*/
|
||||||
wqueue_write_cb write_cb;
|
wqueue_write_cb write_cb;
|
||||||
|
/** Function used to free an MBuf - default is uc_mbuf_free()*/
|
||||||
|
wqueue_free_mbuf_cb free_cb;
|
||||||
|
/** Current number of queued struct MBuf
|
||||||
|
*/
|
||||||
unsigned int queue_len;
|
unsigned int queue_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -120,4 +161,10 @@ int uc_wqueue_enqueue(struct UCWQueue *wqueue, struct MBuf *mbuf);
|
|||||||
*/
|
*/
|
||||||
int uc_wqueue_flush(struct UCWQueue *wqueue);
|
int uc_wqueue_flush(struct UCWQueue *wqueue);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** @} (addtogroup)*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
configure_file (
|
||||||
|
"version.c.in"
|
||||||
|
"version.c"
|
||||||
|
)
|
||||||
|
file(GLOB SOURCE_FILES *.c)
|
||||||
|
|
||||||
|
add_library(
|
||||||
|
ucore SHARED
|
||||||
|
${SOURCE_FILES}
|
||||||
|
"${PROJECT_BINARY_DIR}/src/version.c"
|
||||||
|
)
|
||||||
|
set_target_properties(ucore PROPERTIES SOVERSION 1 VERSION 1.0.0)
|
||||||
|
target_link_libraries(ucore Threads::Threads)
|
||||||
|
install (TARGETS ucore DESTINATION lib)
|
||||||
@@ -21,3 +21,5 @@ ucore_env.Alias('install',
|
|||||||
ucore_env.Install(os.path.join(prefix, 'lib'), [ucore_staticlib]))
|
ucore_env.Install(os.path.join(prefix, 'lib'), [ucore_staticlib]))
|
||||||
ucore_env.Alias('install',
|
ucore_env.Alias('install',
|
||||||
ucore_env.InstallVersionedLib(os.path.join(prefix, 'lib'), [ucore_sharedlib]))
|
ucore_env.InstallVersionedLib(os.path.join(prefix, 'lib'), [ucore_sharedlib]))
|
||||||
|
|
||||||
|
ucore_env.Default([ucore_staticlib, ucore_sharedlib])
|
||||||
|
|||||||
+19
-1
@@ -2,6 +2,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include "ucore/utils.h"
|
||||||
#include "ucore/bitvec.h"
|
#include "ucore/bitvec.h"
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
@@ -12,6 +13,8 @@
|
|||||||
#define unlikely(expr) (expr)
|
#define unlikely(expr) (expr)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
UC_STATIC_ASSERT(CHAR_BIT % 8 == 0);
|
||||||
|
|
||||||
static inline int bit_index(int b)
|
static inline int bit_index(int b)
|
||||||
{
|
{
|
||||||
return b / (sizeof(uc_bv_integer) * CHAR_BIT);
|
return b / (sizeof(uc_bv_integer) * CHAR_BIT);
|
||||||
@@ -41,7 +44,7 @@ struct UCBitVec *uc_bv_new(size_t nbits)
|
|||||||
|
|
||||||
void uc_bv_free(struct UCBitVec *v)
|
void uc_bv_free(struct UCBitVec *v)
|
||||||
{
|
{
|
||||||
if (v) {
|
if (likely(v != NULL)) {
|
||||||
free(v);
|
free(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,3 +91,18 @@ void uc_bv_set_all(struct UCBitVec *v)
|
|||||||
memset(v->vec,0xff,v->vec_len * sizeof(uc_bv_integer));
|
memset(v->vec,0xff,v->vec_len * sizeof(uc_bv_integer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int uc_bv_find_first_zero(const struct UCBitVec *v)
|
||||||
|
{
|
||||||
|
const size_t bits_per_word = sizeof(uc_bv_integer) * CHAR_BIT;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < v->vec_len; i++) {
|
||||||
|
uc_bv_integer inverted = ~v->vec[i];
|
||||||
|
|
||||||
|
if (inverted != 0) {
|
||||||
|
int bit_pos = __builtin_ffsl(inverted) - 1; // ffsl returns 1-based index
|
||||||
|
return (int)(i * bits_per_word + bit_pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|||||||
+2
-2
@@ -32,7 +32,7 @@ static void uc_cached_clock_now(const struct UCoreClock *uclock,
|
|||||||
struct timeval *tv)
|
struct timeval *tv)
|
||||||
{
|
{
|
||||||
const struct UCoreCachedClock *cached_clock;
|
const struct UCoreCachedClock *cached_clock;
|
||||||
cached_clock = UC_CONST_CONTAINER_OF(uclock, const struct UCoreCachedClock, clock),
|
cached_clock = UC_CONST_CONTAINER_OF(uclock, struct UCoreCachedClock, clock),
|
||||||
|
|
||||||
*tv = cached_clock->cache;
|
*tv = cached_clock->cache;
|
||||||
}
|
}
|
||||||
@@ -55,7 +55,7 @@ void uc_cached_clock_update(struct UCoreCachedClock *uclock)
|
|||||||
static void uc_settable_clock_now(const struct UCoreClock *uclock, struct timeval *tv)
|
static void uc_settable_clock_now(const struct UCoreClock *uclock, struct timeval *tv)
|
||||||
{
|
{
|
||||||
const struct UCoreSettableClock *cached_clock;
|
const struct UCoreSettableClock *cached_clock;
|
||||||
cached_clock = UC_CONST_CONTAINER_OF(uclock, const struct UCoreSettableClock, clock),
|
cached_clock = UC_CONST_CONTAINER_OF(uclock, struct UCoreSettableClock, clock),
|
||||||
|
|
||||||
*tv = cached_clock->now;
|
*tv = cached_clock->now;
|
||||||
}
|
}
|
||||||
|
|||||||
+769
-35
@@ -1,54 +1,788 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "ucore/string.h"
|
||||||
|
#include "ucore/strvec.h"
|
||||||
|
#include "ucore/utils.h"
|
||||||
|
#include "ucore/backtrace.h"
|
||||||
|
//
|
||||||
enum UCCmdRc {
|
enum UCCmdRc {
|
||||||
/**Executed ok */
|
UC_CMDRC_OK,
|
||||||
UC_CMD_OK,
|
|
||||||
/**Executed with warning */
|
/**Executed with warning */
|
||||||
UC_CMD_WARNING,
|
UC_CMDRC_WARNING,
|
||||||
/*Not executed, incomplete command */
|
/*incomplete command */
|
||||||
UC_CMD_INCOMPLETE,
|
UC_CMDRC_INCOMPLETE,
|
||||||
|
/*Command cann't uniquely be distinguished */
|
||||||
|
UC_CMDRC_AMBIGUOUS,
|
||||||
|
/* Command doesn't exist*/
|
||||||
|
UC_CMDRC_NOT_FOUND,
|
||||||
/*Not executed, generic error */
|
/*Not executed, generic error */
|
||||||
UC_CMD_ERROR,
|
UC_CMDRC_ERROR,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum UCCmdRc (*uc_cmd_handler)(int narg, char *args[]);
|
|
||||||
typedef void (*uc_cmd_write_cfg)(void);
|
|
||||||
|
|
||||||
#define UC_CMD_FL_HIDDEN (1 << 0)
|
enum UCCmdType {
|
||||||
|
UC_CMD_ROOT = 1,
|
||||||
struct UCCmdNode;
|
UC_CMD_KEYWORD,
|
||||||
struct UCCmdDef;
|
UC_CMD_LIST,
|
||||||
|
UC_CMD_STRING,
|
||||||
struct UCCmdSettings {
|
UC_CMD_END,
|
||||||
const char *name;
|
|
||||||
const char *version;
|
|
||||||
const char *boot_cfg_file;
|
|
||||||
|
|
||||||
struct UCCmdNode *initial_node;
|
|
||||||
struct UCCmdNode *node_head;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct UCCmdNode {
|
struct UCCmdWord {
|
||||||
int id;
|
char *word;
|
||||||
uc_cmd_write_cfg write_func;
|
char *descr;
|
||||||
struct UCCmdDef *cmd_head; //linked list of UCCmdDef
|
|
||||||
struct UCCmdNode *next;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct UCCmdList {
|
||||||
|
struct UCStrv words;
|
||||||
|
struct UCStrv descrs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UCCmdArgs;
|
||||||
|
typedef enum UCCmdRc (*UCCmdHandler)(const struct UCCmdArgs *args);
|
||||||
|
|
||||||
struct UCCmdDef {
|
struct UCCmdDef {
|
||||||
const char *cmd;
|
const char *cmd;
|
||||||
const char **help;
|
const char *help;
|
||||||
size_t cmd_len;
|
UCCmdHandler callback;
|
||||||
uc_cmd_handler cb;
|
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
};
|
||||||
|
|
||||||
struct UCCmdDef *next;
|
struct UCCmdArgs {
|
||||||
|
struct UCStrv argv;
|
||||||
|
const struct UCCmdDef *cmd;
|
||||||
|
void *ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UCCmdRunner;
|
||||||
|
typedef int (*UCCmdRootExit)(struct UCCmdRunner *r, int current_id, void *ctx);
|
||||||
|
struct UCCmdRoot {
|
||||||
|
int node_id;
|
||||||
|
UCCmdRootExit exit_callback;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Command are broken into words and inserted into a tree.
|
||||||
|
* the 3 commands:
|
||||||
|
* show all
|
||||||
|
* date
|
||||||
|
* show all bottles
|
||||||
|
* Results in the tree:
|
||||||
|
*
|
||||||
|
* +--------+ child +--------+ child +-------+ child +-----+
|
||||||
|
* | root |------->| show |------->| all |------>| END |
|
||||||
|
* +--------+ +--------+ +-------+ +-----+
|
||||||
|
* | next | next
|
||||||
|
* V V
|
||||||
|
* +--------+ child +-----+ +--------+ child +-----+
|
||||||
|
* | date |-----> | END | | bottles|------>| END |
|
||||||
|
* +--------+ +-----+ +--------+ +-----+
|
||||||
|
*
|
||||||
|
* END nodes are complete commands. Other child/next pointers will be nULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct UCCmdNode {
|
||||||
|
enum UCCmdType type;
|
||||||
|
union {
|
||||||
|
struct UCCmdWord word;
|
||||||
|
struct UCCmdList list;
|
||||||
|
const struct UCCmdDef *cmd;
|
||||||
|
const struct UCCmdRootExit *root;
|
||||||
|
} data;
|
||||||
|
uint32_t flags;
|
||||||
|
struct UCCmdNode *next; //next at same level
|
||||||
|
struct UCCmdNode *child;
|
||||||
|
struct UCCmdNode *parent;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UCCmdRunner {
|
||||||
|
struct UCCmdNode *current_root;
|
||||||
|
struct UCCmdNode _root;
|
||||||
|
};
|
||||||
|
//max words in a single command
|
||||||
|
#define UC_CMD_MAX_WORDS 32
|
||||||
|
|
||||||
|
struct UCCmdTokenizer {
|
||||||
|
char *cmd_copy;
|
||||||
|
char *cmd_words[UC_CMD_MAX_WORDS];
|
||||||
|
int num_words;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void uc_cmd_init(const char *app_name, const char *version);
|
void
|
||||||
int uc_cmd_read_config(const char *filename);
|
print_args(const struct UCStrv *args);
|
||||||
void uc_cmd_set_configfile(const char *filename);
|
|
||||||
void uc_cmd_add_cmd(struct UCCmdDef *cmd, int parent_node_id);
|
|
||||||
void uc_cmd_set_default_node(int node_id);
|
|
||||||
|
|
||||||
|
static int uc_str_empty(const char *str)
|
||||||
|
{
|
||||||
|
while (*str) {
|
||||||
|
if (!isspace(*str++)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
uc_cmd_type_is_variable(enum UCCmdType type)
|
||||||
|
{
|
||||||
|
return type == UC_CMD_LIST ||
|
||||||
|
type == UC_CMD_STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
uc_cmd_tokenize(struct UCCmdTokenizer *t, const char *cmd, const char *delim)
|
||||||
|
{
|
||||||
|
|
||||||
|
t->num_words = 0;
|
||||||
|
t->cmd_copy = strdup(cmd);
|
||||||
|
if (t->cmd_copy == NULL) {
|
||||||
|
assert(t->cmd_copy);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (delim == NULL) {
|
||||||
|
delim = "\r\n\t\v ";
|
||||||
|
}
|
||||||
|
|
||||||
|
t->num_words = uc_getfields(t->cmd_copy,
|
||||||
|
t->cmd_words,
|
||||||
|
ARRAY_SIZE(t->cmd_words),
|
||||||
|
1,
|
||||||
|
delim);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
uc_cmd_tokenize_destroy(struct UCCmdTokenizer *t)
|
||||||
|
|
||||||
|
{
|
||||||
|
free(t->cmd_copy);
|
||||||
|
t->num_words = 0;
|
||||||
|
t->cmd_copy = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
uc_cmd_runner_init(struct UCCmdRunner *r)
|
||||||
|
{
|
||||||
|
memset(r, 0, sizeof *r);
|
||||||
|
r->current_root = &r->_root;
|
||||||
|
r->_root.type = UC_CMD_ROOT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
uc_cmd_node_dealloc(struct UCCmdNode *n)
|
||||||
|
{
|
||||||
|
struct UCCmdNode *next;
|
||||||
|
|
||||||
|
while (n) {
|
||||||
|
uc_cmd_node_dealloc(n->child);
|
||||||
|
next = n->next;
|
||||||
|
if (n->type == UC_CMD_KEYWORD) {
|
||||||
|
free(n->data.word.word);
|
||||||
|
free(n->data.word.descr);
|
||||||
|
} else if (n->type == UC_CMD_LIST) {
|
||||||
|
uc_strv_destroy(&n->data.list.words);
|
||||||
|
uc_strv_destroy(&n->data.list.descrs);
|
||||||
|
} else if (n->type == UC_CMD_STRING) {
|
||||||
|
free(n->data.word.word);
|
||||||
|
free(n->data.word.descr);
|
||||||
|
}
|
||||||
|
free(n);
|
||||||
|
n = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
uc_cmd_runner_destroy(struct UCCmdRunner *r)
|
||||||
|
{
|
||||||
|
uc_cmd_node_dealloc(r->_root.child);
|
||||||
|
r->current_root->child = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct UCCmdNode *
|
||||||
|
uc_cmd_node_alloc(enum UCCmdType type, uint32_t flags)
|
||||||
|
{
|
||||||
|
struct UCCmdNode *n;
|
||||||
|
|
||||||
|
n = calloc(1, sizeof *n);
|
||||||
|
if (n == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
n->type = type;
|
||||||
|
n->flags = flags;
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct
|
||||||
|
UCCmdNode *uc_cmd_node_create_list(const char *word)
|
||||||
|
{
|
||||||
|
struct UCCmdNode *node = NULL;
|
||||||
|
|
||||||
|
struct UCCmdTokenizer t;
|
||||||
|
|
||||||
|
uc_cmd_tokenize(&t, word, "() |\t\v");
|
||||||
|
if (t.num_words > 0) {
|
||||||
|
node = uc_cmd_node_alloc(UC_CMD_LIST, 0);
|
||||||
|
if (node != NULL) {
|
||||||
|
|
||||||
|
uc_strv_init(&node->data.list.words);
|
||||||
|
uc_strv_init(&node->data.list.descrs);
|
||||||
|
|
||||||
|
for (int i = 0; i < t.num_words; i++) {
|
||||||
|
uc_strv_append(&node->data.list.words, t.cmd_words[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uc_cmd_tokenize_destroy(&t);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct UCCmdNode *
|
||||||
|
uc_cmd_node_create_word(enum UCCmdType type, const char *word)
|
||||||
|
{
|
||||||
|
struct UCCmdNode *node;
|
||||||
|
|
||||||
|
node = uc_cmd_node_alloc(type, 0);
|
||||||
|
if (node != NULL) {
|
||||||
|
node->data.word.word = strdup(word);
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct UCCmdNode *
|
||||||
|
uc_cmd_node_create(const char *word)
|
||||||
|
{
|
||||||
|
struct UCCmdNode *node;
|
||||||
|
|
||||||
|
if (word[0] == '(') { //list (foo|bar|baz)
|
||||||
|
node = uc_cmd_node_create_list(word);
|
||||||
|
} else if (isupper(word[0])) {
|
||||||
|
node = uc_cmd_node_create_word(UC_CMD_STRING, word);
|
||||||
|
} else {
|
||||||
|
node = uc_cmd_node_create_word(UC_CMD_KEYWORD, word);
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
uc_cmd_node_match(const struct UCCmdNode *n, const char *word, struct UCStrv *matches)
|
||||||
|
{
|
||||||
|
size_t word_len;
|
||||||
|
int found = 0;
|
||||||
|
|
||||||
|
if (word == NULL || word[0] == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
word_len = strlen(word);
|
||||||
|
|
||||||
|
if (n->type == UC_CMD_KEYWORD) {
|
||||||
|
|
||||||
|
if (strncmp(word, n->data.word.word, word_len) == 0) {
|
||||||
|
if (matches != NULL) {
|
||||||
|
uc_strv_append(matches, n->data.word.word);
|
||||||
|
}
|
||||||
|
found = 1;
|
||||||
|
}
|
||||||
|
} else if (n->type == UC_CMD_LIST) {
|
||||||
|
const struct UCStrv *v = &n->data.list.words;
|
||||||
|
|
||||||
|
assert(v);
|
||||||
|
|
||||||
|
for(size_t i = 0; i < v->cnt; i++) {
|
||||||
|
|
||||||
|
if (strncmp(word, v->strings[i], word_len) == 0) {
|
||||||
|
if (matches != NULL) {
|
||||||
|
uc_strv_append(matches, v->strings[i]);
|
||||||
|
}
|
||||||
|
found = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (n->type == UC_CMD_STRING) {
|
||||||
|
if (matches != NULL) {
|
||||||
|
uc_strv_append(matches, word);
|
||||||
|
}
|
||||||
|
found = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct UCCmdNode *
|
||||||
|
uc_cmd_add(struct UCCmdNode *parent, const char *word)
|
||||||
|
{
|
||||||
|
struct UCCmdNode *new_node;
|
||||||
|
struct UCCmdNode **iter = &parent->child;
|
||||||
|
|
||||||
|
assert(parent);
|
||||||
|
|
||||||
|
new_node = uc_cmd_node_create(word);
|
||||||
|
if (new_node == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
new_node->parent = parent;
|
||||||
|
|
||||||
|
while (*iter) {
|
||||||
|
struct UCCmdNode *n = *iter;
|
||||||
|
|
||||||
|
if (uc_cmd_type_is_variable(new_node->type) && n->type != UC_CMD_END) {
|
||||||
|
//we don't support combinations of keywords and variables
|
||||||
|
//at the same level.
|
||||||
|
uc_cmd_node_dealloc(new_node);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
//TODO check for ambiguous word (e.g. add "short" when "shorter" already exists)
|
||||||
|
if (new_node->type == UC_CMD_KEYWORD && uc_cmd_node_match(n, word, NULL)) {
|
||||||
|
uc_cmd_node_dealloc(new_node);
|
||||||
|
return *iter;
|
||||||
|
}
|
||||||
|
iter = &n->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
*iter = new_node;
|
||||||
|
|
||||||
|
return new_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
uc_cmd_node_add_help(struct UCCmdNode *node)
|
||||||
|
{
|
||||||
|
struct UCCmdTokenizer t;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (node->data.cmd->help == NULL) {
|
||||||
|
//allow helpless commands
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->type != UC_CMD_END) {
|
||||||
|
return -10;
|
||||||
|
}
|
||||||
|
|
||||||
|
uc_cmd_tokenize(&t, node->data.cmd->help, "\n");
|
||||||
|
if (t.num_words <= 0) {
|
||||||
|
uc_cmd_tokenize_destroy(&t);
|
||||||
|
return -11;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = t.num_words - 1;
|
||||||
|
//we have the last node in the tree
|
||||||
|
//Walk it up towards the root(backwards) and fill
|
||||||
|
//in help texts where it's missing.
|
||||||
|
while (node->parent) {
|
||||||
|
|
||||||
|
node = node->parent;
|
||||||
|
if (node->type == UC_CMD_ROOT) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->type == UC_CMD_KEYWORD ||
|
||||||
|
node->type == UC_CMD_STRING) {
|
||||||
|
if (node->data.word.descr == NULL &&
|
||||||
|
!uc_str_empty(t.cmd_words[i])) {
|
||||||
|
node->data.word.descr = strdup(t.cmd_words[i]);
|
||||||
|
}
|
||||||
|
i--;
|
||||||
|
} else if (node->type == UC_CMD_LIST) {
|
||||||
|
if (node->data.list.descrs.cnt == 0) {
|
||||||
|
for (int k = (int)node->data.list.words.cnt -1; k >= 0; k++) {
|
||||||
|
if (i < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
uc_strv_append(&node->data.list.descrs, t.cmd_words[i]);
|
||||||
|
i--;
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
i -= (int)node->data.list.words.cnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uc_cmd_tokenize_destroy(&t);
|
||||||
|
|
||||||
|
if (node->type != UC_CMD_ROOT || i != -1) {
|
||||||
|
//we didn't consume all the help tokens, so the
|
||||||
|
//command definition is screwd up
|
||||||
|
return -20;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
uc_cmd_install_noassert(struct UCCmdRunner *r, struct UCCmdDef *cmd)
|
||||||
|
{
|
||||||
|
struct UCCmdNode *node = r->current_root;
|
||||||
|
struct UCCmdNode *new_node;
|
||||||
|
struct UCCmdTokenizer t;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
uc_cmd_tokenize(&t, cmd->cmd, NULL);
|
||||||
|
if (t.num_words <= 0) {
|
||||||
|
uc_cmd_tokenize_destroy(&t);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < t.num_words; i++) {
|
||||||
|
node = uc_cmd_add(node, t.cmd_words[i]);
|
||||||
|
if (node == NULL) {
|
||||||
|
uc_cmd_tokenize_destroy(&t);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO, check for duplicate command here.
|
||||||
|
|
||||||
|
new_node = uc_cmd_node_alloc(UC_CMD_END, 0);
|
||||||
|
if (new_node == NULL) {
|
||||||
|
uc_cmd_tokenize_destroy(&t);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
new_node->data.cmd = cmd;
|
||||||
|
new_node->next = node->child;
|
||||||
|
node->child = new_node;
|
||||||
|
new_node->parent = node;
|
||||||
|
|
||||||
|
rc = uc_cmd_node_add_help(new_node);
|
||||||
|
|
||||||
|
uc_cmd_tokenize_destroy(&t);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
uc_cmd_install(struct UCCmdRunner *r, struct UCCmdDef *cmd)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = uc_cmd_install_noassert(r, cmd);
|
||||||
|
UC_ASSERT(rc == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum UCCmdRc
|
||||||
|
uc_cmd_find(struct UCCmdNode *first,
|
||||||
|
const struct UCCmdTokenizer *t,
|
||||||
|
struct UCStrv *matches,
|
||||||
|
struct UCCmdNode **result)
|
||||||
|
{
|
||||||
|
struct UCCmdNode *node = first;
|
||||||
|
struct UCCmdNode *found = NULL;
|
||||||
|
enum UCCmdRc rc = UC_CMDRC_NOT_FOUND;
|
||||||
|
|
||||||
|
for (int i = 0; i < t->num_words && node; i++) {
|
||||||
|
int n_found = 0;
|
||||||
|
|
||||||
|
while (node) {
|
||||||
|
if (uc_cmd_node_match(node, t->cmd_words[i], matches)) {
|
||||||
|
if (n_found == 0) {
|
||||||
|
//keep the 1. matched
|
||||||
|
found = node;
|
||||||
|
}
|
||||||
|
n_found++;
|
||||||
|
}
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n_found == 1) {
|
||||||
|
node = found->child;
|
||||||
|
rc = UC_CMDRC_OK;
|
||||||
|
} else if (n_found > 1) {
|
||||||
|
node = found;
|
||||||
|
rc = UC_CMDRC_AMBIGUOUS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*result = found;
|
||||||
|
|
||||||
|
if (found == NULL) {
|
||||||
|
rc = UC_CMDRC_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum UCCmdRc
|
||||||
|
uc_cmd_parse_and_find(struct UCCmdRunner *r, const char *cmd_line,
|
||||||
|
struct UCStrv *matches,
|
||||||
|
struct UCCmdNode **result)
|
||||||
|
{
|
||||||
|
|
||||||
|
struct UCCmdNode *node = r->current_root->child;
|
||||||
|
struct UCCmdTokenizer t;
|
||||||
|
enum UCCmdRc rc = UC_CMDRC_ERROR;
|
||||||
|
|
||||||
|
//make a copy since getfields destroys the original string
|
||||||
|
uc_cmd_tokenize(&t, cmd_line, NULL);
|
||||||
|
|
||||||
|
if (t.num_words > 0) {
|
||||||
|
|
||||||
|
//match the commands towards the command tree
|
||||||
|
//
|
||||||
|
rc = uc_cmd_find(node, &t, matches, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
uc_cmd_tokenize_destroy(&t);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum UCCmdRc
|
||||||
|
uc_cmd_help(struct UCCmdRunner *r, const char *cmd_line, struct UCStrv *completions)
|
||||||
|
{
|
||||||
|
struct UCCmdNode *found = NULL;
|
||||||
|
enum UCCmdRc rc;
|
||||||
|
|
||||||
|
rc = uc_cmd_parse_and_find(r, cmd_line, NULL, &found);
|
||||||
|
if (rc == UC_CMDRC_OK) {
|
||||||
|
struct UCCmdNode *node = found;
|
||||||
|
|
||||||
|
if (node->type == UC_CMD_LIST) {
|
||||||
|
uc_strv_append_all(completions, &node->data.list.descrs, 1);
|
||||||
|
} else if (node->type == UC_CMD_STRING ||
|
||||||
|
node->type == UC_CMD_KEYWORD) {
|
||||||
|
if (node->data.word.descr != NULL) {
|
||||||
|
uc_strv_append(completions, node->data.word.descr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum UCCmdRc
|
||||||
|
uc_cmd_complete(struct UCCmdRunner *r, const char *cmd_line, struct UCStrv *completions)
|
||||||
|
{
|
||||||
|
struct UCCmdNode *found = NULL;
|
||||||
|
enum UCCmdRc rc;
|
||||||
|
|
||||||
|
rc = uc_cmd_parse_and_find(r, cmd_line, NULL, &found);
|
||||||
|
if (rc != UC_CMDRC_NOT_FOUND && found != NULL) {
|
||||||
|
struct UCCmdNode *node = found->child;
|
||||||
|
|
||||||
|
while (node) {
|
||||||
|
if (node->type == UC_CMD_END) {
|
||||||
|
uc_strv_append(completions, "<CR>");
|
||||||
|
} else if (node->type == UC_CMD_LIST) {
|
||||||
|
uc_strv_append_all(completions, &node->data.list.words, 1);
|
||||||
|
} else if (node->type == UC_CMD_STRING ||
|
||||||
|
node->type == UC_CMD_KEYWORD) {
|
||||||
|
uc_strv_append(completions, node->data.word.word);
|
||||||
|
}
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
enum UCCmdRc
|
||||||
|
uc_cmd_run_ctx(struct UCCmdRunner *r, const char *cmd_line, void *ctx)
|
||||||
|
{
|
||||||
|
struct UCCmdArgs args = {
|
||||||
|
.argv = UC_STRV_INITIALIZER,
|
||||||
|
.ctx = ctx,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UCCmdNode *found = NULL;
|
||||||
|
enum UCCmdRc rc;
|
||||||
|
|
||||||
|
rc = uc_cmd_parse_and_find(r, cmd_line, &args.argv, &found);
|
||||||
|
if (rc == UC_CMDRC_OK) {
|
||||||
|
found = found->child;
|
||||||
|
// Now check the current level for any UC_CMD_END
|
||||||
|
// which indicates a complete command
|
||||||
|
while (found) {
|
||||||
|
if (found->type == UC_CMD_END) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
found = found->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found != NULL) {
|
||||||
|
const struct UCCmdDef *cmd = found->data.cmd;
|
||||||
|
args.cmd = cmd;
|
||||||
|
rc = cmd->callback(&args);
|
||||||
|
} else {
|
||||||
|
rc = UC_CMDRC_INCOMPLETE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uc_strv_destroy(&args.argv);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum UCCmdRc
|
||||||
|
uc_cmd_run(struct UCCmdRunner *r, const char *cmd_line)
|
||||||
|
{
|
||||||
|
return uc_cmd_run_ctx(r, cmd_line, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void print_args(const struct UCStrv *args)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < args->cnt; i++) {
|
||||||
|
printf("arg %zu: '%s' ", i, args->strings[i]);
|
||||||
|
}
|
||||||
|
puts("");
|
||||||
|
}
|
||||||
|
|
||||||
|
enum UCCmdRc cmd1_cb(const struct UCCmdArgs *args)
|
||||||
|
{
|
||||||
|
puts(__func__);
|
||||||
|
print_args(&args->argv);
|
||||||
|
|
||||||
|
return UC_CMDRC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum UCCmdRc cmd2_cb(const struct UCCmdArgs *args)
|
||||||
|
{
|
||||||
|
puts(__func__);
|
||||||
|
print_args(&args->argv);
|
||||||
|
|
||||||
|
return UC_CMDRC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum UCCmdRc cmd3_cb(const struct UCCmdArgs *args)
|
||||||
|
{
|
||||||
|
puts(__func__);
|
||||||
|
print_args(&args->argv);
|
||||||
|
|
||||||
|
return UC_CMDRC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum UCCmdRc cmd4_cb(const struct UCCmdArgs *args)
|
||||||
|
{
|
||||||
|
puts(__func__);
|
||||||
|
print_args(&args->argv);
|
||||||
|
|
||||||
|
return UC_CMDRC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_complete(struct UCCmdRunner *r, const char *command)
|
||||||
|
{
|
||||||
|
struct UCStrv completions = UC_STRV_INITIALIZER;
|
||||||
|
|
||||||
|
uc_cmd_complete(r, command, &completions);
|
||||||
|
if (completions.cnt > 0) {
|
||||||
|
printf("Possible completions for '%s' :\n", command);
|
||||||
|
for (size_t i = 0; i < completions.cnt; i++) {
|
||||||
|
printf("\t%s\n", completions.strings[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("No completions for '%s' :\n", command);
|
||||||
|
}
|
||||||
|
|
||||||
|
uc_strv_destroy(&completions);
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_help(struct UCCmdRunner *r, const char *command)
|
||||||
|
{
|
||||||
|
struct UCStrv completions = UC_STRV_INITIALIZER;
|
||||||
|
|
||||||
|
uc_cmd_help(r, command, &completions);
|
||||||
|
if (completions.cnt > 0) {
|
||||||
|
printf("help for '%s' :\n", command);
|
||||||
|
for (size_t i = 0; i < completions.cnt; i++) {
|
||||||
|
printf("\t%s\n", completions.strings[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("No help for '%s' :\n", command);
|
||||||
|
}
|
||||||
|
|
||||||
|
uc_strv_destroy(&completions);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char line[128];
|
||||||
|
struct UCCmdRunner r;
|
||||||
|
struct UCCmdDef cmd1 = {
|
||||||
|
"show all",
|
||||||
|
"show stuff\nEverything\n",
|
||||||
|
cmd1_cb,
|
||||||
|
0,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UCCmdDef cmd2 = {
|
||||||
|
"show empty",
|
||||||
|
" \n everyhing that's empty\n",
|
||||||
|
cmd2_cb,
|
||||||
|
0,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UCCmdDef cmd3 = {
|
||||||
|
"show empty bottle",
|
||||||
|
NULL,
|
||||||
|
cmd3_cb,
|
||||||
|
0,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UCCmdDef cmd4 = {
|
||||||
|
"delete file NAME",
|
||||||
|
"delete\nfile\nName of the file\n",
|
||||||
|
cmd4_cb,
|
||||||
|
0,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
uc_cmd_runner_init(&r);
|
||||||
|
uc_cmd_install(&r, &cmd1);
|
||||||
|
uc_cmd_install(&r, &cmd2);
|
||||||
|
uc_cmd_install(&r, &cmd3);
|
||||||
|
uc_cmd_install(&r, &cmd4);
|
||||||
|
|
||||||
|
uc_cmd_run(&r, "delete file /tmp/a");
|
||||||
|
uc_cmd_run(&r, "show all");
|
||||||
|
uc_cmd_run(&r, "show empty");
|
||||||
|
uc_cmd_run(&r, "sh emp b");
|
||||||
|
uc_cmd_run(&r, "");
|
||||||
|
|
||||||
|
do_help(&r, "delete file /tmp/a");
|
||||||
|
do_help(&r, "show empty");
|
||||||
|
do_help(&r, "show all");
|
||||||
|
do_help(&r, "sh");
|
||||||
|
do_help(&r, "");
|
||||||
|
/*
|
||||||
|
while (fgets(line,sizeof line, stdin)) {
|
||||||
|
enum UCCmdRc rc = uc_cmd_run(&r, line);
|
||||||
|
if (rc != UC_CMDRC_OK) {
|
||||||
|
printf("Command failed with code %d\n", rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
do_complete(&r, "sho em");
|
||||||
|
do_complete(&r, "show ");
|
||||||
|
do_complete(&r, "");
|
||||||
|
do_complete(&r, "delet ");
|
||||||
|
do_complete(&r, "delete ");
|
||||||
|
do_complete(&r, "delete file");
|
||||||
|
do_complete(&r, "delete fil");
|
||||||
|
uc_cmd_runner_destroy(&r);
|
||||||
|
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
#include "ucore/string.h"
|
#include "ucore/string.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
getfields(char *str, char **args, int max, int mflag, const char *set)
|
uc_getfields(char *str, char **args, int max, int mflag, const char *set)
|
||||||
{
|
{
|
||||||
char r;
|
char r;
|
||||||
int intok, narg;
|
int intok, narg;
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include "ucore/string.h"
|
||||||
|
|
||||||
|
//tokenize string, and exclude the quotes
|
||||||
|
static char *qtoken(char *s, const char *sep)
|
||||||
|
{
|
||||||
|
int inquote = 0;
|
||||||
|
char *t = s;
|
||||||
|
while (*t != 0 && (inquote || strchr(sep, *t) == NULL)) {
|
||||||
|
if (*t != '"') {
|
||||||
|
*s++ = *t++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inquote) {
|
||||||
|
inquote = 1;
|
||||||
|
t++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t[1] != '"') {
|
||||||
|
t++;
|
||||||
|
inquote = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//double quotes, merged to 1 quote
|
||||||
|
t++;
|
||||||
|
*s++ = *t++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*s != 0) {
|
||||||
|
*s = 0;
|
||||||
|
if (t == s) {
|
||||||
|
t++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uc_gettokens(char *str, char **args, int maxargs, const char *sep)
|
||||||
|
{
|
||||||
|
int nargs;
|
||||||
|
|
||||||
|
for (nargs = 0; nargs < maxargs; nargs++) {
|
||||||
|
while (*str != 0 && strchr(sep, *str) != NULL) {
|
||||||
|
*str++ = 0;
|
||||||
|
}
|
||||||
|
if (*str == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
args[nargs] = str;
|
||||||
|
str = qtoken(str, sep);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nargs;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -151,7 +151,6 @@ int iomux_update_events(struct IOMux *mux, struct IOMuxFD *fd, unsigned int what
|
|||||||
if (fd->what != what) {
|
if (fd->what != what) {
|
||||||
fd->what = what;
|
fd->what = what;
|
||||||
rc = mux->ops.update_events_impl(mux, fd);
|
rc = mux->ops.update_events_impl(mux, fd);
|
||||||
fd->what = what;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
|||||||
+2
-2
@@ -44,7 +44,7 @@ static int iomux_select_update_events(struct IOMux *mux_, struct IOMuxFD *fd)
|
|||||||
struct IOMuxSelect *mux = mux_->instance;
|
struct IOMuxSelect *mux = mux_->instance;
|
||||||
|
|
||||||
if (fd->fd < 0 || fd->fd >= FD_SETSIZE) {
|
if (fd->fd < 0 || fd->fd >= FD_SETSIZE) {
|
||||||
return EINVAL;
|
return ENFILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd->what & MUX_EV_READ)
|
if (fd->what & MUX_EV_READ)
|
||||||
@@ -70,7 +70,7 @@ static int iomux_select_register_fd(struct IOMux *mux_, struct IOMuxFD *fd)
|
|||||||
|
|
||||||
rc = iomux_select_update_events(mux_, fd);
|
rc = iomux_select_update_events(mux_, fd);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
return ENFILE;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
mux->descriptors[fd->fd] = fd;
|
mux->descriptors[fd->fd] = fd;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/*Copyright (c) 2004 Nils O. Selåsdal <NOS {on} Utel {dot} no> */
|
/*Copyright (c) 2004 Nils O. Sel�sdal <NOS {on} Utel {dot} no> */
|
||||||
/*Straight forward attempt at a Mersenne Twister PRNG */
|
/*Straight forward attempt at a Mersenne Twister PRNG */
|
||||||
|
|
||||||
#include "ucore/mersenne_twister.h"
|
#include "ucore/mersenne_twister.h"
|
||||||
@@ -24,7 +24,7 @@ enum {
|
|||||||
|
|
||||||
void mtsrand(int seed, MTRand *r)
|
void mtsrand(int seed, MTRand *r)
|
||||||
{
|
{
|
||||||
int j;
|
unsigned j;
|
||||||
for (j = 0 ; j < N ; j++) {
|
for (j = 0 ; j < N ; j++) {
|
||||||
r->x[j] = seed * ((j+1)<< 3)|0x1;
|
r->x[j] = seed * ((j+1)<< 3)|0x1;
|
||||||
}
|
}
|
||||||
@@ -36,16 +36,16 @@ unsigned int mtrand(MTRand *r)
|
|||||||
{
|
{
|
||||||
unsigned int y;
|
unsigned int y;
|
||||||
unsigned int ch[] = {0, a};
|
unsigned int ch[] = {0, a};
|
||||||
|
|
||||||
y = r->x[r->i] & U;
|
y = r->x[r->i] & U;
|
||||||
y |= r->x[r->i % N];
|
y |= r->x[r->i % N];
|
||||||
y &= LL;
|
y &= LL;
|
||||||
|
|
||||||
r->x[r->i] = r->x[(r->i + M ) %N];
|
r->x[r->i] = r->x[(r->i + M ) %N];
|
||||||
r->x[r->i] ^= y >> 1;
|
r->x[r->i] ^= y >> 1;
|
||||||
|
|
||||||
r->x[r->i] ^= ch[y&0x1];
|
r->x[r->i] ^= ch[y&0x1];
|
||||||
|
|
||||||
y = r->x[r->i];
|
y = r->x[r->i];
|
||||||
y ^= y >> u;
|
y ^= y >> u;
|
||||||
y ^= (y << s) & b;
|
y ^= (y << s) & b;
|
||||||
@@ -55,7 +55,7 @@ unsigned int mtrand(MTRand *r)
|
|||||||
r->i = (r->i + 1) % N;
|
r->i = (r->i + 1) % N;
|
||||||
|
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
#ifdef TEST_MT
|
#ifdef TEST_MT
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "ucore/bitvec.h"
|
||||||
|
#include "ucore/slot_allocator.h"
|
||||||
|
|
||||||
|
void *uc_slot_alloc(UCSlotAlloc *sa)
|
||||||
|
{
|
||||||
|
int free_slot = uc_bv_find_first_zero(&sa->bitmap);
|
||||||
|
if (free_slot < 0) {
|
||||||
|
return NULL;
|
||||||
|
} else if ((size_t)free_slot >= sa->num_slots) { // bit vector may have more bits than slots
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uc_bv_set_bit(&sa->bitmap, free_slot);
|
||||||
|
|
||||||
|
return sa->slots + free_slot * sa->slot_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uc_slot_free(UCSlotAlloc *restrict sa, void *restrict slot)
|
||||||
|
{
|
||||||
|
assert((uint8_t *)slot >= sa->slots);
|
||||||
|
int slot_index = ((uint8_t *)slot - sa->slots) / sa->slot_size;
|
||||||
|
assert((size_t)slot_index < sa->num_slots);
|
||||||
|
uc_bv_clr_bit(&sa->bitmap, slot_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
|
||||||
|
UC_SLOT_ALLOC_DEF(sa, 24, 1)
|
||||||
|
|
||||||
|
void *p1 = uc_slot_alloc(&sa);
|
||||||
|
printf("%p\n", &sa_memory.memory[0]);
|
||||||
|
printf("%p\n", p1);
|
||||||
|
|
||||||
|
void *p2 = uc_slot_alloc(&sa);
|
||||||
|
printf("%p\n", p2);
|
||||||
|
uc_slot_free(&sa, p1);
|
||||||
|
|
||||||
|
p2 = uc_slot_alloc(&sa);
|
||||||
|
printf("%p\n", p2);
|
||||||
|
|
||||||
|
printf("__malloc__\n");
|
||||||
|
void *v = malloc(24 * (1<<16));
|
||||||
|
UC_SLOT_ALLOC_DEF_EX(sa2, 24, (1<<16), v)
|
||||||
|
char *v2 = NULL;
|
||||||
|
for (int i = 0; i < 1<<16; i++) {
|
||||||
|
char *c = uc_slot_alloc(&sa2);
|
||||||
|
if (c == NULL) {
|
||||||
|
printf("uc_slot_alloc failed at %d\n", i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*c = i;
|
||||||
|
if (i == 0) {
|
||||||
|
v2 = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = (1<<16) -1 ; i >= 0; i--) {
|
||||||
|
uc_slot_free(&sa2, v2 + 24*i);
|
||||||
|
}
|
||||||
|
free(v);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -130,3 +130,14 @@ int uc_strv_append_all(struct UCStrv *restrict a, struct UCStrv *restrict b, int
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void uc_strv_reverse(struct UCStrv *strv)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < strv->cnt / 2; i++) {
|
||||||
|
|
||||||
|
size_t k = strv->cnt - i - 1;
|
||||||
|
char *tmp = strv->strings[i];
|
||||||
|
|
||||||
|
strv->strings[i] = strv->strings[k];
|
||||||
|
strv->strings[k] = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+4
-4
@@ -1,11 +1,11 @@
|
|||||||
//Various info about the version and build.
|
//Various info about the version and build.
|
||||||
//The SConscript file substitutes these at build time
|
//The SConscript file substitutes these at build time
|
||||||
|
|
||||||
const int ucore_version_major = @version_major@;
|
const int ucore_version_major = @libucore_VERSION_MAJOR@;
|
||||||
const int ucore_version_minor = @version_minor@;
|
const int ucore_version_minor = @libucore_VERSION_MINOR@;
|
||||||
const int ucore_version_patch = @version_patch@;
|
const int ucore_version_patch = @libucore_VERSION_PATCH@;
|
||||||
|
|
||||||
const char ucore_version_str[] = "@version_str@";
|
const char ucore_version_str[] = "@libucore_VERSION@";
|
||||||
const char ucore_build_host[] = "@build_host@";
|
const char ucore_build_host[] = "@build_host@";
|
||||||
const char ucore_build_type[] = "@build_type@";
|
const char ucore_build_type[] = "@build_type@";
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -15,7 +15,7 @@ static int uc_wqueue_handle_write(struct UCWQueue *wqueue)
|
|||||||
q = UC_TAILQ_FIRST(&wqueue->queue);
|
q = UC_TAILQ_FIRST(&wqueue->queue);
|
||||||
|
|
||||||
mbuf = UC_TAILQ_CONTAINER(q, struct MBuf, entry);
|
mbuf = UC_TAILQ_CONTAINER(q, struct MBuf, entry);
|
||||||
rc = wqueue->write_cb(mux, fd, mbuf);
|
rc = wqueue->write_cb(mux, wqueue, mbuf);
|
||||||
if (rc <= 0) {
|
if (rc <= 0) {
|
||||||
//NOTE for rc < 0, nothing can touch the wqueue or fd
|
//NOTE for rc < 0, nothing can touch the wqueue or fd
|
||||||
//any more, as it might been free'd
|
//any more, as it might been free'd
|
||||||
@@ -24,7 +24,7 @@ static int uc_wqueue_handle_write(struct UCWQueue *wqueue)
|
|||||||
|
|
||||||
mbuf = uc_mbuf_dequeue(&wqueue->queue);
|
mbuf = uc_mbuf_dequeue(&wqueue->queue);
|
||||||
assert(mbuf != NULL);
|
assert(mbuf != NULL);
|
||||||
uc_mbuf_free(mbuf);
|
wqueue->free_cb(mbuf);
|
||||||
wqueue->queue_len--;
|
wqueue->queue_len--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ static void uc_wqueue_cb(struct IOMux *mux, struct IOMuxFD *fd, unsigned int wha
|
|||||||
|
|
||||||
|
|
||||||
if (rc >= 0 && what & MUX_EV_READ) {
|
if (rc >= 0 && what & MUX_EV_READ) {
|
||||||
rc = wqueue->read_cb(mux, fd);
|
rc = wqueue->read_cb(mux, wqueue);
|
||||||
//NOTE - can't touch the wqueue or fd after this point,
|
//NOTE - can't touch the wqueue or fd after this point,
|
||||||
//as it might been free'd
|
//as it might been free'd
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ void uc_wqueue_init(struct UCWQueue *wqueue, struct IOMux *mux)
|
|||||||
memset(wqueue, 0, sizeof *wqueue);
|
memset(wqueue, 0, sizeof *wqueue);
|
||||||
wqueue->mux = mux;
|
wqueue->mux = mux;
|
||||||
wqueue->fd.callback = uc_wqueue_cb;
|
wqueue->fd.callback = uc_wqueue_cb;
|
||||||
|
wqueue->free_cb = uc_mbuf_free;
|
||||||
uc_tailq_init(&wqueue->queue);
|
uc_tailq_init(&wqueue->queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ int uc_wqueue_clear(struct UCWQueue *wqueue)
|
|||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
while ((buf = uc_mbuf_dequeue(&wqueue->queue)) != NULL) {
|
while ((buf = uc_mbuf_dequeue(&wqueue->queue)) != NULL) {
|
||||||
uc_mbuf_free(buf);
|
wqueue->free_cb(buf);
|
||||||
wqueue->queue_len--;
|
wqueue->queue_len--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
file(GLOB TEST_SOURCE_FILES test_*.c)
|
||||||
|
|
||||||
|
link_libraries(check ucore Threads::Threads)
|
||||||
|
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||||
|
include_directories("/opt/homebrew/include")
|
||||||
|
link_directories("/opt/homebrew/lib")
|
||||||
|
list(REMOVE_ITEM TEST_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/test_ringbuf.c)
|
||||||
|
else()
|
||||||
|
link_libraries(rt)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_executable(test_runner ${TEST_SOURCE_FILES})
|
||||||
|
|
||||||
|
add_custom_target(test COMMAND test_runner
|
||||||
|
DEPENDS test_runner
|
||||||
|
WORKING_DIRECTORY ${CMAKE_PROJECT_DIR})
|
||||||
+1
-1
@@ -39,4 +39,4 @@ cmd = test_env.Command(target='test_phony' ,
|
|||||||
action= test_env.Dir('.').abspath + '/' + test_executable)
|
action= test_env.Dir('.').abspath + '/' + test_executable)
|
||||||
test_env.Depends(cmd, prog)
|
test_env.Depends(cmd, prog)
|
||||||
test_env.AlwaysBuild(cmd)
|
test_env.AlwaysBuild(cmd)
|
||||||
|
test_env.Default(test_executable)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#include <ucore/fd_utils.h>
|
#include <ucore/fd_utils.h>
|
||||||
|
|
||||||
|
|
||||||
int stdout_read(struct IOMux *mux, struct IOMuxFD *fd)
|
int stdout_read(struct IOMux *mux, struct UCWQueue *wqueue)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -24,9 +24,9 @@ void stdin_read_cb(struct IOMux *mux, struct IOMuxFD *fd, unsigned int event)
|
|||||||
printf("Read %d bytes\n", len);
|
printf("Read %d bytes\n", len);
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
uc_mbuf_free(mbuf);
|
uc_mbuf_free(mbuf);
|
||||||
iomux_unregister_fd(mux, fd);
|
|
||||||
uc_wqueue_clear(wqueue);
|
|
||||||
iomux_unregister_fd(mux, &wqueue->fd);
|
iomux_unregister_fd(mux, &wqueue->fd);
|
||||||
|
uc_wqueue_clear(wqueue);
|
||||||
|
iomux_unregister_fd(mux, fd);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,7 @@ struct IOMuxFD stdin_fd = {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int stdout_write(struct IOMux *mux, struct IOMuxFD *fd, struct MBuf *mbuf)
|
int stdout_write(struct IOMux *mux, struct UCWQueue *wqueue, struct MBuf *mbuf)
|
||||||
{
|
{
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
ssize_t wlen;
|
ssize_t wlen;
|
||||||
@@ -52,7 +52,7 @@ int stdout_write(struct IOMux *mux, struct IOMuxFD *fd, struct MBuf *mbuf)
|
|||||||
|
|
||||||
len = uc_mbuf_len(mbuf);
|
len = uc_mbuf_len(mbuf);
|
||||||
data = uc_mbuf_pull(mbuf, len);
|
data = uc_mbuf_pull(mbuf, len);
|
||||||
wlen = write(fd->fd, data, len);
|
wlen = write(wqueue->fd.fd, data, len);
|
||||||
|
|
||||||
if (wlen < 0) {
|
if (wlen < 0) {
|
||||||
if (errno != EWOULDBLOCK) {
|
if (errno != EWOULDBLOCK) {
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include "ucore/iomux.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void in_cb(struct IOMux *mux, struct IOMuxFD *fd, unsigned int event)
|
||||||
|
{
|
||||||
|
|
||||||
|
char buf[16];
|
||||||
|
ssize_t rc;
|
||||||
|
|
||||||
|
rc = read(fd->fd, buf, sizeof buf);
|
||||||
|
printf("Read returned %ld\n", (long)rc);
|
||||||
|
if (rc <= 0) {
|
||||||
|
if (rc == -1 && errno == EAGAIN) {
|
||||||
|
return;
|
||||||
|
} else if (rc == -1) {
|
||||||
|
perror("read");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
iomux_unregister_fd(mux, fd);
|
||||||
|
close(fd->fd);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void out_cb(struct IOMux *mux, struct IOMuxFD *fd, unsigned int event)
|
||||||
|
{
|
||||||
|
char str[] = "hello";
|
||||||
|
ssize_t rc;
|
||||||
|
|
||||||
|
rc = write(fd->fd, str, strlen(str));
|
||||||
|
printf("write returned %ld\n", (long)rc);
|
||||||
|
if (rc <= 0) {
|
||||||
|
if (rc == -1 && errno == EAGAIN) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
perror("write");
|
||||||
|
}
|
||||||
|
iomux_unregister_fd(mux, fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int pipes[2];
|
||||||
|
pipe(pipes);
|
||||||
|
uc_set_nonblocking(pipes[0]);
|
||||||
|
uc_set_nonblocking(pipes[1]);
|
||||||
|
|
||||||
|
struct IOMuxFD rfd= {
|
||||||
|
.fd = pipes[0],
|
||||||
|
.what = MUX_EV_READ,
|
||||||
|
.callback = in_cb,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IOMuxFD wfd= {
|
||||||
|
.fd = pipes[1],
|
||||||
|
.what = MUX_EV_WRITE,
|
||||||
|
.callback = out_cb,
|
||||||
|
};
|
||||||
|
|
||||||
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
|
||||||
|
struct IOMux *mux = iomux_create(IOMUX_TYPE_SELECT);
|
||||||
|
iomux_register_fd(mux, &rfd);
|
||||||
|
iomux_register_fd(mux, &wfd);
|
||||||
|
|
||||||
|
iomux_run(mux);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
+42
-42
@@ -8,12 +8,12 @@ START_TEST (test_2bcd_1234567890)
|
|||||||
unsigned char bcd[5];
|
unsigned char bcd[5];
|
||||||
size_t len = uc_ascii2bcd(ascii, bcd, 0);
|
size_t len = uc_ascii2bcd(ascii, bcd, 0);
|
||||||
|
|
||||||
fail_if(len != 5, "len is %zu", len);
|
ck_assert_int_eq(len, 5);
|
||||||
fail_if(bcd[0] != 0x21,"was 0x%x",bcd[0]);
|
ck_assert_int_eq(bcd[0], 0x21);
|
||||||
fail_if(bcd[1] != 0x43,"was 0x%x",bcd[1]);
|
ck_assert_int_eq(bcd[1], 0x43);
|
||||||
fail_if(bcd[2] != 0x65,"was 0x%x",bcd[2]);
|
ck_assert_int_eq(bcd[2], 0x65);
|
||||||
fail_if(bcd[3] != 0x87,"was 0x%x",bcd[3]);
|
ck_assert_int_eq(bcd[3], 0x87);
|
||||||
fail_if(bcd[4] != 0x09,"was 0x%x",bcd[4]);
|
ck_assert_int_eq(bcd[4], 0x09);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ START_TEST (test_2bcd_empty)
|
|||||||
unsigned char bcd[1];
|
unsigned char bcd[1];
|
||||||
size_t len = uc_ascii2bcd(ascii, bcd, 3);
|
size_t len = uc_ascii2bcd(ascii, bcd, 3);
|
||||||
|
|
||||||
fail_if(len != 0, "len is %zu", len);
|
ck_assert_int_eq(len, 0);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -33,8 +33,8 @@ START_TEST (test_2bcd_1_filler)
|
|||||||
unsigned char bcd[1];
|
unsigned char bcd[1];
|
||||||
size_t len = uc_ascii2bcd(ascii, bcd, 0xa);
|
size_t len = uc_ascii2bcd(ascii, bcd, 0xa);
|
||||||
|
|
||||||
fail_if(len != 1, "len is %zu", len);
|
ck_assert_int_eq(len, 1);
|
||||||
fail_if(bcd[0] != 0xa1,"was 0x%x",bcd[0]);
|
ck_assert_int_ne(bcd[0], 0);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -44,10 +44,10 @@ START_TEST (test_2bcd_2_filler)
|
|||||||
unsigned char bcd[2];
|
unsigned char bcd[2];
|
||||||
size_t len = uc_ascii2bcd(ascii, bcd, 0xf);
|
size_t len = uc_ascii2bcd(ascii, bcd, 0xf);
|
||||||
|
|
||||||
fail_if(len != 2, "len is %zu", len);
|
ck_assert_int_eq(len , 2);
|
||||||
fail_if(bcd[0] != 0x21,"was 0x%x",bcd[0]);
|
ck_assert_int_eq(bcd[0] , 0x21);
|
||||||
fail_if(bcd[1] != 0xf3,"was 0x%x",bcd[1]);
|
ck_assert_int_eq(bcd[1] , 0xf3);
|
||||||
fail_if(UC_BCD_LEN(strlen(ascii)) != len);
|
ck_assert_int_eq(UC_BCD_LEN(strlen(ascii)) , len);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -58,9 +58,9 @@ START_TEST (test_2bcd_3_filler)
|
|||||||
unsigned char bcd[2];
|
unsigned char bcd[2];
|
||||||
size_t len = uc_ascii2bcd(ascii, bcd, 0x0);
|
size_t len = uc_ascii2bcd(ascii, bcd, 0x0);
|
||||||
|
|
||||||
fail_if(len != 2, "len is %zu", len);
|
ck_assert_int_eq(len , 2);
|
||||||
fail_if(bcd[0] != 0x21,"was 0x%x",bcd[0]);
|
ck_assert_int_eq(bcd[0] , 0x21);
|
||||||
fail_if(bcd[1] != 0x03,"was 0x%x",bcd[1]);
|
ck_assert_int_eq(bcd[1] , 0x03);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ START_TEST (test_2bcd_non_digits)
|
|||||||
unsigned char bcd[10];
|
unsigned char bcd[10];
|
||||||
size_t len = uc_ascii2bcd(ascii, bcd, 0x0);
|
size_t len = uc_ascii2bcd(ascii, bcd, 0x0);
|
||||||
|
|
||||||
fail_if(len != 0, "len is %zu", len);
|
ck_assert_int_eq(len , 0);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -82,12 +82,12 @@ START_TEST (test_2bcd_phoneno)
|
|||||||
unsigned char bcd[24];
|
unsigned char bcd[24];
|
||||||
size_t len = uc_ascii2bcd(ascii, bcd, 0xf);
|
size_t len = uc_ascii2bcd(ascii, bcd, 0xf);
|
||||||
|
|
||||||
fail_if(len != 5, "len is %zu", len);
|
ck_assert_int_eq(len , 5);
|
||||||
fail_if(bcd[0] != 0x00,"was 0x%x",bcd[0]);
|
ck_assert_int_eq(bcd[0] , 0x00);
|
||||||
fail_if(bcd[1] != 0x74,"was 0x%x",bcd[1]);
|
ck_assert_int_eq(bcd[1] , 0x74);
|
||||||
fail_if(bcd[2] != 0x23,"was 0x%x",bcd[1]);
|
ck_assert_int_eq(bcd[2] , 0x23);
|
||||||
fail_if(bcd[3] != 0x33,"was 0x%x",bcd[1]);
|
ck_assert_int_eq(bcd[3] , 0x33);
|
||||||
fail_if(bcd[4] != 0xf4,"was 0x%x",bcd[1]);
|
ck_assert_int_eq(bcd[4] , 0xf4);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -98,8 +98,8 @@ START_TEST (test_2bcd_binary)
|
|||||||
unsigned char bcd[24];
|
unsigned char bcd[24];
|
||||||
size_t len = uc_ascii2bcd(ascii, bcd, 0xf);
|
size_t len = uc_ascii2bcd(ascii, bcd, 0xf);
|
||||||
|
|
||||||
fail_if(len != 1, "len is %zu", len);
|
ck_assert_int_eq(len , 1);
|
||||||
fail_if(bcd[0] != 0xf2,"0 was 0x%x",bcd[0]);
|
ck_assert_int_eq(bcd[0], 0xf2);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -110,13 +110,13 @@ START_TEST (test_2hex_1)
|
|||||||
char ascii[sizeof bcd * 2 + 1];
|
char ascii[sizeof bcd * 2 + 1];
|
||||||
size_t len = uc_bcd2ascii(bcd, sizeof bcd, ascii);
|
size_t len = uc_bcd2ascii(bcd, sizeof bcd, ascii);
|
||||||
|
|
||||||
fail_if(len != 4, "len is %zu", len);
|
ck_assert_int_eq(len, 4);
|
||||||
fail_if(ascii[0] != '1',"0 was %c",ascii[0]);
|
ck_assert_int_eq(ascii[0], '1');
|
||||||
fail_if(ascii[1] != '2',"1 was %c",ascii[1]);
|
ck_assert_int_eq(ascii[1], '2');
|
||||||
fail_if(ascii[2] != '3',"2 was %c",ascii[2]);
|
ck_assert_int_eq(ascii[2], '3');
|
||||||
fail_if(ascii[3] != '4',"3 was %c",ascii[3]);
|
ck_assert_int_eq(ascii[3], '4');
|
||||||
fail_if(ascii[4] != 0, "4 was %c",ascii[4]);
|
ck_assert_int_eq(ascii[4], 0);
|
||||||
fail_if(UC_ASCII_LEN(sizeof bcd) != len);
|
ck_assert_int_eq(UC_ASCII_LEN(sizeof bcd) , len);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -127,14 +127,14 @@ START_TEST (test_2hex_2)
|
|||||||
char ascii[sizeof bcd * 2 + 1];
|
char ascii[sizeof bcd * 2 + 1];
|
||||||
size_t len = uc_bcd2ascii(bcd, sizeof bcd, ascii);
|
size_t len = uc_bcd2ascii(bcd, sizeof bcd, ascii);
|
||||||
|
|
||||||
fail_if(len != 6, "len is %zu", len);
|
ck_assert_int_eq(len , 6);
|
||||||
fail_if(ascii[0] != '0',"0 was %c",ascii[0]);
|
ck_assert_int_eq(ascii[0] , '0');
|
||||||
fail_if(ascii[1] != 'F',"1 was %c",ascii[1]);
|
ck_assert_int_eq(ascii[1] , 'F');
|
||||||
fail_if(ascii[2] != 'F',"2 was %c",ascii[2]);
|
ck_assert_int_eq(ascii[2] , 'F');
|
||||||
fail_if(ascii[3] != 'F',"3 was %c",ascii[3]);
|
ck_assert_int_eq(ascii[3] , 'F');
|
||||||
fail_if(ascii[4] != '0', "4 was %c",ascii[4]);
|
ck_assert_int_eq(ascii[4] , '0');
|
||||||
fail_if(ascii[5] != '0', "5 was %c",ascii[5]);
|
ck_assert_int_eq(ascii[5] , '0');
|
||||||
fail_if(ascii[6] != 0, "6 was %c",ascii[6]);
|
ck_assert_int_eq(ascii[6] , 0);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -146,8 +146,8 @@ START_TEST (test_2hex_empty)
|
|||||||
ascii[0] = 0xFF;
|
ascii[0] = 0xFF;
|
||||||
size_t len = uc_bcd2ascii(bcd, 0, ascii);
|
size_t len = uc_bcd2ascii(bcd, 0, ascii);
|
||||||
|
|
||||||
fail_if(len != 0, "len is %zu", len);
|
ck_assert_int_eq(len, 0);
|
||||||
fail_if(ascii[0] != 0, "0 was %c",ascii[0]);
|
ck_assert_int_eq(ascii[0], 0);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
|||||||
+39
-12
@@ -9,7 +9,7 @@ START_TEST (test_bitvec_1)
|
|||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < sizeof s * 8; i++)
|
for (i = 0; i < sizeof s * 8; i++)
|
||||||
fail_if(uc_bv_get_bit(&v, i), "bit %zu is not 0", i);
|
ck_assert_int_eq(uc_bv_get_bit(&v, i), 0);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ START_TEST (test_bitvec_2)
|
|||||||
uc_bv_set_bit(&v, i);
|
uc_bv_set_bit(&v, i);
|
||||||
|
|
||||||
for (i = 0; i < sizeof s * 8; i++)
|
for (i = 0; i < sizeof s * 8; i++)
|
||||||
fail_if(uc_bv_get_bit(&v, i) != 1 , "bit %zu is not 1", i);
|
ck_assert_int_eq(uc_bv_get_bit(&v, i), 1);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -34,13 +34,13 @@ START_TEST (test_bitvec_clearbit)
|
|||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < sizeof(uc_bv_integer) * 8; i++)
|
for (i = 0; i < sizeof(uc_bv_integer) * 8; i++)
|
||||||
fail_if(uc_bv_get_bit(&v, i) != 1 , "bit %zu is not 1", i);
|
ck_assert_int_eq(uc_bv_get_bit(&v, i), 1);
|
||||||
|
|
||||||
for (i = 0; i < sizeof(uc_bv_integer) * 8; i++)
|
for (i = 0; i < sizeof(uc_bv_integer) * 8; i++)
|
||||||
uc_bv_clr_bit(&v, i);
|
uc_bv_clr_bit(&v, i);
|
||||||
|
|
||||||
for (i = 0; i < sizeof(uc_bv_integer) * 8; i++)
|
for (i = 0; i < sizeof(uc_bv_integer) * 8; i++)
|
||||||
fail_if(uc_bv_get_bit(&v, i) != 0 , "bit %zu is not 0", i);
|
ck_assert_int_eq(uc_bv_get_bit(&v, i), 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
@@ -48,14 +48,14 @@ END_TEST
|
|||||||
START_TEST (test_bitvec_set_bits_from_array)
|
START_TEST (test_bitvec_set_bits_from_array)
|
||||||
{
|
{
|
||||||
struct UCBitVec *v = uc_bv_new(5);
|
struct UCBitVec *v = uc_bv_new(5);
|
||||||
char a[] = {1, 0,1 ,0, 1};
|
char a[] = {1, 0, 1 ,0, 1};
|
||||||
|
|
||||||
uc_bv_set_bits_from_array(v,a , 5);
|
uc_bv_set_bits_from_array(v,a , 5);
|
||||||
fail_if(uc_bv_get_bit(v, 0) != 1 , "bit 0 is wrong");
|
ck_assert_int_eq(uc_bv_get_bit(v, 0), 1);
|
||||||
fail_if(uc_bv_get_bit(v, 1) != 0 , "bit 1 is wrong");
|
ck_assert_int_eq(uc_bv_get_bit(v, 1), 0);
|
||||||
fail_if(uc_bv_get_bit(v, 2) != 1 , "bit 2 is wrong");
|
ck_assert_int_eq(uc_bv_get_bit(v, 2), 1);
|
||||||
fail_if(uc_bv_get_bit(v, 3) != 0 , "bit 3 is wrong");
|
ck_assert_int_eq(uc_bv_get_bit(v, 3), 0);
|
||||||
fail_if(uc_bv_get_bit(v, 4) != 1 , "bit 4 is wrong");
|
ck_assert_int_eq(uc_bv_get_bit(v, 4), 1);
|
||||||
|
|
||||||
uc_bv_free(v);
|
uc_bv_free(v);
|
||||||
}
|
}
|
||||||
@@ -70,15 +70,40 @@ START_TEST (test_bitvec_setall_clearall)
|
|||||||
uc_bv_set_all(v);
|
uc_bv_set_all(v);
|
||||||
|
|
||||||
for (i = 0; i < 511; i++)
|
for (i = 0; i < 511; i++)
|
||||||
fail_if(uc_bv_get_bit(v, i) != 1 , "bit %zu is not 1", i);
|
ck_assert_int_eq(uc_bv_get_bit(v, i), 1);
|
||||||
|
|
||||||
uc_bv_clr_all(v);
|
uc_bv_clr_all(v);
|
||||||
|
|
||||||
for (i = 0; i < sizeof(uc_bv_integer) * 8; i++)
|
for (i = 0; i < sizeof(uc_bv_integer) * 8; i++)
|
||||||
fail_if(uc_bv_get_bit(v, i) != 0 , "bit %zu is not 0", i);
|
ck_assert_int_eq(uc_bv_get_bit(v, i), 0);
|
||||||
|
|
||||||
uc_bv_free(v);
|
uc_bv_free(v);
|
||||||
|
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
START_TEST (test_bitvec_find_first_zero)
|
||||||
|
{
|
||||||
|
uc_bv_integer buf[8];
|
||||||
|
struct UCBitVec v = UC_BV_STATIC_INIT(buf);
|
||||||
|
uc_bv_set_all(&v);
|
||||||
|
|
||||||
|
int bit = uc_bv_find_first_zero(&v);
|
||||||
|
ck_assert_int_eq(bit, -1);
|
||||||
|
|
||||||
|
uc_bv_clr_bit(&v, 0);
|
||||||
|
bit = uc_bv_find_first_zero(&v);
|
||||||
|
ck_assert_int_eq(bit, 0);
|
||||||
|
|
||||||
|
uc_bv_set_bit(&v, 0);
|
||||||
|
uc_bv_clr_bit(&v, 63);
|
||||||
|
bit = uc_bv_find_first_zero(&v);
|
||||||
|
ck_assert_int_eq(bit, 63);
|
||||||
|
|
||||||
|
uc_bv_set_bit(&v, 63);
|
||||||
|
uc_bv_clr_bit(&v, sizeof buf * CHAR_BIT - 1);
|
||||||
|
bit = uc_bv_find_first_zero(&v);
|
||||||
|
ck_assert_int_eq(bit, sizeof buf * CHAR_BIT - 1);
|
||||||
|
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -91,6 +116,8 @@ Suite *bitvec_suite(void)
|
|||||||
tcase_add_test(tc, test_bitvec_set_bits_from_array);
|
tcase_add_test(tc, test_bitvec_set_bits_from_array);
|
||||||
tcase_add_test(tc, test_bitvec_clearbit);
|
tcase_add_test(tc, test_bitvec_clearbit);
|
||||||
tcase_add_test(tc, test_bitvec_setall_clearall);
|
tcase_add_test(tc, test_bitvec_setall_clearall);
|
||||||
|
tcase_add_test(tc, test_bitvec_find_first_zero);
|
||||||
|
|
||||||
suite_add_tcase(s, tc);
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
|||||||
+9
-10
@@ -60,8 +60,8 @@ START_TEST (test_gbuf_printf1)
|
|||||||
fail_if(buf == NULL);
|
fail_if(buf == NULL);
|
||||||
|
|
||||||
rc = uc_gbuf_printf(buf, "test %d", 1);
|
rc = uc_gbuf_printf(buf, "test %d", 1);
|
||||||
fail_if(rc != 6, "rc was %d", rc);
|
fail_if(rc != 6);
|
||||||
fail_if(buf->used != 6, "buf->used was %d", buf->used);
|
fail_if(buf->used != 6);
|
||||||
fail_if(strcmp("test 1", buf->buf) != 0);
|
fail_if(strcmp("test 1", buf->buf) != 0);
|
||||||
uc_gbuf_unref(buf);
|
uc_gbuf_unref(buf);
|
||||||
|
|
||||||
@@ -76,8 +76,8 @@ START_TEST (test_gbuf_printf2)
|
|||||||
fail_if(buf == NULL);
|
fail_if(buf == NULL);
|
||||||
|
|
||||||
rc = uc_gbuf_printf(buf, "test %d test %d test %d", 1, 2, 3);
|
rc = uc_gbuf_printf(buf, "test %d test %d test %d", 1, 2, 3);
|
||||||
fail_if(rc != 20, "rc was %d", rc);
|
fail_if(rc != 20);
|
||||||
fail_if(buf->used != 20, "buf->used was %d", buf->used);
|
fail_if(buf->used != 20);
|
||||||
fail_if(strcmp("test 1 test 2 test 3", buf->buf) != 0);
|
fail_if(strcmp("test 1 test 2 test 3", buf->buf) != 0);
|
||||||
uc_gbuf_unref(buf);
|
uc_gbuf_unref(buf);
|
||||||
|
|
||||||
@@ -92,14 +92,14 @@ START_TEST (test_gbuf_printf3)
|
|||||||
fail_if(buf == NULL);
|
fail_if(buf == NULL);
|
||||||
|
|
||||||
rc = uc_gbuf_printf(buf, "test %d test %d test %d", 1, 2, 3);
|
rc = uc_gbuf_printf(buf, "test %d test %d test %d", 1, 2, 3);
|
||||||
fail_if(rc != 20, "rc was %d", rc);
|
fail_if(rc != 20);
|
||||||
fail_if(buf->used != 20, "buf->used was %d", buf->used);
|
fail_if(buf->used != 20);
|
||||||
fail_if(strcmp("test 1 test 2 test 3", buf->buf) != 0);
|
fail_if(strcmp("test 1 test 2 test 3", buf->buf) != 0);
|
||||||
|
|
||||||
rc = uc_gbuf_printf(buf, " test %d test %d", 4, 5);
|
rc = uc_gbuf_printf(buf, " test %d test %d", 4, 5);
|
||||||
|
|
||||||
fail_if(rc != 14, "rc was %d", rc);
|
fail_if(rc != 14);
|
||||||
fail_if(buf->used != 34, "buf->used was %d", buf->used);
|
fail_if(buf->used != 34);
|
||||||
fail_if(strcmp("test 1 test 2 test 3 test 4 test 5", buf->buf) != 0);
|
fail_if(strcmp("test 1 test 2 test 3 test 4 test 5", buf->buf) != 0);
|
||||||
uc_gbuf_unref(buf);
|
uc_gbuf_unref(buf);
|
||||||
|
|
||||||
@@ -110,11 +110,10 @@ START_TEST (test_gbuf_printf_empty_string)
|
|||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
GBuf *buf = uc_new_gbuf(1);
|
GBuf *buf = uc_new_gbuf(1);
|
||||||
const char *fmt = ""; //tricks gcc to not warn about empty format string
|
|
||||||
|
|
||||||
fail_if(buf == NULL);
|
fail_if(buf == NULL);
|
||||||
|
|
||||||
rc = uc_gbuf_printf(buf, fmt);
|
rc = uc_gbuf_printf(buf, "");
|
||||||
fail_if(rc != 0);
|
fail_if(rc != 0);
|
||||||
fail_if(buf->used != 0);
|
fail_if(buf->used != 0);
|
||||||
uc_gbuf_unref(buf);
|
uc_gbuf_unref(buf);
|
||||||
|
|||||||
+2
-2
@@ -33,7 +33,7 @@ START_TEST (test_dbuf)
|
|||||||
fail_if(uc_dbuf_remaining(&buf) != 105);
|
fail_if(uc_dbuf_remaining(&buf) != 105);
|
||||||
fail_if(uc_dbuf_len(&buf) != 5);
|
fail_if(uc_dbuf_len(&buf) != 5);
|
||||||
ck_assert_str_eq((char *)buf.start, "ABCD");
|
ck_assert_str_eq((char *)buf.start, "ABCD");
|
||||||
|
|
||||||
uc_dbuf_take(&buf, 5);
|
uc_dbuf_take(&buf, 5);
|
||||||
|
|
||||||
fail_if(uc_dbuf_remaining(&buf) != 120);
|
fail_if(uc_dbuf_remaining(&buf) != 120);
|
||||||
@@ -154,7 +154,7 @@ START_TEST (test_dbuf_add_ensure_take)
|
|||||||
fail_if(rc != 0);
|
fail_if(rc != 0);
|
||||||
//ok, dbuf adds the ensured capacity to the existing buflen
|
//ok, dbuf adds the ensured capacity to the existing buflen
|
||||||
//so it becomes 100, not 90 even though the buffer is already empty
|
//so it becomes 100, not 90 even though the buffer is already empty
|
||||||
fail_if(uc_dbuf_remaining(buf) != 100, "remaining %zu", (uc_dbuf_remaining(buf)));
|
fail_if(uc_dbuf_remaining(buf) != 100);
|
||||||
fail_if(uc_dbuf_buflen(buf) != 100);
|
fail_if(uc_dbuf_buflen(buf) != 100);
|
||||||
memset(buf->end, 0xDE, 90);
|
memset(buf->end, 0xDE, 90);
|
||||||
uc_dbuf_added(buf, 90);
|
uc_dbuf_added(buf, 90);
|
||||||
|
|||||||
+14
-14
@@ -22,7 +22,7 @@ START_TEST (test_uc_hex_encode_2)
|
|||||||
|
|
||||||
uc_hex_encode(binary, sizeof binary, hex);
|
uc_hex_encode(binary, sizeof binary, hex);
|
||||||
|
|
||||||
fail_if(strcmp(hex,"7F8081") != 0, "was %s", hex);
|
fail_if(strcmp(hex,"7F8081") != 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
@@ -34,7 +34,7 @@ START_TEST (test_uc_hex_encode_3)
|
|||||||
|
|
||||||
uc_hex_encode(binary, sizeof binary, hex);
|
uc_hex_encode(binary, sizeof binary, hex);
|
||||||
|
|
||||||
fail_if(strcmp(hex,"0001090B") != 0, "was %s", hex);
|
fail_if(strcmp(hex,"0001090B") != 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
@@ -62,7 +62,7 @@ START_TEST (test_uc_hex_decode_1)
|
|||||||
|
|
||||||
fail_if(binary[0] != 0x1f);
|
fail_if(binary[0] != 0x1f);
|
||||||
fail_if(binary[1] != 0x22);
|
fail_if(binary[1] != 0x22);
|
||||||
fail_if(res != binary + 1, "binary %p, res %p", &binary[0], res);
|
fail_if(res != binary + 1);
|
||||||
|
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
@@ -78,7 +78,7 @@ START_TEST (test_uc_hex_decode_2)
|
|||||||
fail_if(binary[0] != 0x00);
|
fail_if(binary[0] != 0x00);
|
||||||
fail_if(binary[1] != 0xFF);
|
fail_if(binary[1] != 0xFF);
|
||||||
fail_if(binary[2] != 0x80);
|
fail_if(binary[2] != 0x80);
|
||||||
fail_if(res != binary + 3, "binary %p, res %p", &binary[0], res);
|
fail_if(res != binary + 3);
|
||||||
|
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
@@ -110,7 +110,7 @@ START_TEST (test_uc_hex_decode_empty_string)
|
|||||||
fail_if(binary[0] != 0x11);
|
fail_if(binary[0] != 0x11);
|
||||||
fail_if(binary[1] != 0x11);
|
fail_if(binary[1] != 0x11);
|
||||||
fail_if(binary[2] != 0x11);
|
fail_if(binary[2] != 0x11);
|
||||||
fail_if(res != binary, "length %zu\n", res - binary);
|
fail_if(res != binary);
|
||||||
|
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
@@ -125,7 +125,7 @@ START_TEST (test_uc_hex_decode_spaces)
|
|||||||
fail_if(binary[0] != 0x11);
|
fail_if(binary[0] != 0x11);
|
||||||
fail_if(binary[1] != 0x12);
|
fail_if(binary[1] != 0x12);
|
||||||
fail_if(binary[2] != 0x13);
|
fail_if(binary[2] != 0x13);
|
||||||
fail_if(res != binary+3, "length %zu\n", res - binary);
|
fail_if(res != binary+3);
|
||||||
|
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
@@ -141,7 +141,7 @@ START_TEST (test_uc_hex_decode_spaces2)
|
|||||||
fail_if(binary[0] != 0x11);
|
fail_if(binary[0] != 0x11);
|
||||||
fail_if(binary[1] != 0x12);
|
fail_if(binary[1] != 0x12);
|
||||||
fail_if(binary[2] != 0x13);
|
fail_if(binary[2] != 0x13);
|
||||||
fail_if(res != binary+3, "length %zu\n", res - binary);
|
fail_if(res != binary+3);
|
||||||
|
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
@@ -156,7 +156,7 @@ START_TEST (test_uc_hex_decode_spaces_empty)
|
|||||||
|
|
||||||
fail_if(binary[0] != 0x11);
|
fail_if(binary[0] != 0x11);
|
||||||
fail_if(binary[1] != 0x12);
|
fail_if(binary[1] != 0x12);
|
||||||
fail_if(res != binary, "length %zu\n", res - binary);
|
fail_if(res != binary);
|
||||||
|
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
@@ -201,7 +201,7 @@ START_TEST (test_uc_hex_encode_delim_1)
|
|||||||
|
|
||||||
res = uc_hex_encode_delim(binary, sizeof binary, hex, sizeof hex, " ");
|
res = uc_hex_encode_delim(binary, sizeof binary, hex, sizeof hex, " ");
|
||||||
|
|
||||||
fail_if(strcmp(hex, "FF 00 7F 0A ") != 0, "hex was '%s'", hex);
|
fail_if(strcmp(hex, "FF 00 7F 0A ") != 0);
|
||||||
*res = 0;
|
*res = 0;
|
||||||
fail_if(res != hex + 12);
|
fail_if(res != hex + 12);
|
||||||
|
|
||||||
@@ -216,8 +216,8 @@ START_TEST (test_uc_hex_encode_delim_2)
|
|||||||
|
|
||||||
res = uc_hex_encode_delim(binary, sizeof binary, hex, sizeof hex, " \n");
|
res = uc_hex_encode_delim(binary, sizeof binary, hex, sizeof hex, " \n");
|
||||||
|
|
||||||
fail_if(strcmp(hex, "FF \n00 ") != 0, "hex was '%s'", hex);
|
fail_if(strcmp(hex, "FF \n00 ") != 0);
|
||||||
fail_if(res != hex + 7, "sz was %zu", res - hex);
|
fail_if(res != hex + 7);
|
||||||
|
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
@@ -230,7 +230,7 @@ START_TEST (test_uc_hex_encode_delim_zero_len)
|
|||||||
|
|
||||||
res = uc_hex_encode_delim(binary, 0, hex, sizeof hex, " \n");
|
res = uc_hex_encode_delim(binary, 0, hex, sizeof hex, " \n");
|
||||||
|
|
||||||
fail_if(strcmp(hex, "") != 0, "hex was '%s'", hex);
|
fail_if(strcmp(hex, "") != 0);
|
||||||
fail_if(res != hex);
|
fail_if(res != hex);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -247,7 +247,7 @@ START_TEST (test_uc_hex_decode_lowercase)
|
|||||||
|
|
||||||
fail_if(binary[0] != 0x1f);
|
fail_if(binary[0] != 0x1f);
|
||||||
fail_if(binary[1] != 0x22);
|
fail_if(binary[1] != 0x22);
|
||||||
fail_if(res != binary + 1, "binary %p, res %p", &binary[0], res);
|
fail_if(res != binary + 1);
|
||||||
|
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
@@ -263,7 +263,7 @@ Suite *hex_suite(void)
|
|||||||
tcase_add_test(tc, test_uc_hex_encode_delim_1);
|
tcase_add_test(tc, test_uc_hex_encode_delim_1);
|
||||||
tcase_add_test(tc, test_uc_hex_encode_delim_2);
|
tcase_add_test(tc, test_uc_hex_encode_delim_2);
|
||||||
tcase_add_test(tc, test_uc_hex_encode_delim_zero_len);
|
tcase_add_test(tc, test_uc_hex_encode_delim_zero_len);
|
||||||
|
|
||||||
|
|
||||||
tcase_add_test(tc, test_uc_hex_decode_1);
|
tcase_add_test(tc, test_uc_hex_decode_1);
|
||||||
tcase_add_test(tc, test_uc_hex_decode_2);
|
tcase_add_test(tc, test_uc_hex_decode_2);
|
||||||
|
|||||||
+44
-45
@@ -10,7 +10,7 @@
|
|||||||
#define FILE_NAME "logfile_test.log"
|
#define FILE_NAME "logfile_test.log"
|
||||||
#define SUBDIR "log_subdir"
|
#define SUBDIR "log_subdir"
|
||||||
#define SUBDIR_FILE_NAME SUBDIR "/" FILE_NAME
|
#define SUBDIR_FILE_NAME SUBDIR "/" FILE_NAME
|
||||||
//Note that these tests are comewhat fragile as they depend on the
|
//Note that these tests are comewhat fragile as they depend on the
|
||||||
//file sizes that are created, which depends on the (relative)paths of this file.
|
//file sizes that are created, which depends on the (relative)paths of this file.
|
||||||
//for cleaning the created log files..
|
//for cleaning the created log files..
|
||||||
static void logging_rm_files(void)
|
static void logging_rm_files(void)
|
||||||
@@ -61,8 +61,7 @@ START_TEST (test_logfile_location)
|
|||||||
UC_LOGF(UC_LL_ERROR, 0, "Lorum ipson 5");
|
UC_LOGF(UC_LL_ERROR, 0, "Lorum ipson 5");
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
fail_if(rc != 0);
|
||||||
fail_if(st.st_size != 380, "was %ld", (long)st.st_size);
|
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -85,7 +84,7 @@ START_TEST (test_logfile_delete_destination)
|
|||||||
|
|
||||||
uc_log_init(&mods);
|
uc_log_init(&mods);
|
||||||
|
|
||||||
dest = uc_log_new_file(FILE_NAME, UC_LL_DEBUG, 1);
|
dest = uc_log_new_file(FILE_NAME, UC_LL_DEBUG, 0);
|
||||||
fail_if(dest == NULL);
|
fail_if(dest == NULL);
|
||||||
uc_log_add_destination(dest);
|
uc_log_add_destination(dest);
|
||||||
uc_log_add_destination(dest); //adding this twice should do nothing
|
uc_log_add_destination(dest); //adding this twice should do nothing
|
||||||
@@ -97,8 +96,8 @@ START_TEST (test_logfile_delete_destination)
|
|||||||
UC_LOGF(UC_LL_ERROR, 0, "Lorum ipson 5");
|
UC_LOGF(UC_LL_ERROR, 0, "Lorum ipson 5");
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
fail_if(rc != 0);
|
||||||
fail_if(st.st_size != 380, "was %ld", (long)st.st_size);
|
fail_if(st.st_size != 260);
|
||||||
|
|
||||||
uc_log_delete_destination(dest);
|
uc_log_delete_destination(dest);
|
||||||
|
|
||||||
@@ -110,8 +109,8 @@ START_TEST (test_logfile_delete_destination)
|
|||||||
|
|
||||||
//since we deleted destinatiion, no more logging should appear in the file
|
//since we deleted destinatiion, no more logging should appear in the file
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
fail_if(rc != 0);
|
||||||
fail_if(st.st_size != 380, "was %ld", (long)st.st_size);
|
fail_if(st.st_size != 260);
|
||||||
|
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
@@ -143,8 +142,8 @@ START_TEST (test_logfile_no_location)
|
|||||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
fail_if(rc != 0);
|
||||||
fail_if(st.st_size != 52*2, "was %ld", (long)st.st_size);
|
fail_if(st.st_size != 52*2);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -169,16 +168,16 @@ START_TEST (test_logfile_loglevel_surpressed_dest)
|
|||||||
|
|
||||||
|
|
||||||
//file destination have UC_LL_WARNING, so nothing should be logged
|
//file destination have UC_LL_WARNING, so nothing should be logged
|
||||||
dest = uc_log_new_file(FILE_NAME, UC_LL_WARNING, 10);
|
dest = uc_log_new_file(FILE_NAME, UC_LL_WARNING, 10);
|
||||||
fail_if(dest == NULL);
|
fail_if(dest == NULL);
|
||||||
uc_log_add_destination(dest);
|
uc_log_add_destination(dest);
|
||||||
|
|
||||||
UC_LOGF(UC_LL_INFO, 1, "Lorum ipson %d", 1);
|
UC_LOGF(UC_LL_INFO, 1, "Lorum ipson %d", 1);
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
fail_if(rc != 0);
|
||||||
|
|
||||||
fail_if(st.st_size != 0, "was %ld", (long)st.st_size);
|
fail_if(st.st_size != 0);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -203,16 +202,16 @@ START_TEST (test_logfile_loglevel_surpressed_module)
|
|||||||
uc_log_init(&mods);
|
uc_log_init(&mods);
|
||||||
|
|
||||||
|
|
||||||
dest = uc_log_new_file(FILE_NAME, UC_LL_DEBUG, 1);
|
dest = uc_log_new_file(FILE_NAME, UC_LL_DEBUG, 1);
|
||||||
fail_if(dest == NULL);
|
fail_if(dest == NULL);
|
||||||
uc_log_add_destination(dest);
|
uc_log_add_destination(dest);
|
||||||
|
|
||||||
UC_LOGF(UC_LL_INFO, 0, "Lorum ipson %d", 100);
|
UC_LOGF(UC_LL_INFO, 0, "Lorum ipson %d", 100);
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
fail_if(rc != 0);
|
||||||
|
|
||||||
fail_if(st.st_size != 0, "was %ld", (long)st.st_size);
|
fail_if(st.st_size != 0);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -235,7 +234,7 @@ START_TEST (test_logfile_reopen_files)
|
|||||||
|
|
||||||
uc_log_init(&mods);
|
uc_log_init(&mods);
|
||||||
|
|
||||||
dest = uc_log_new_file(FILE_NAME, UC_LL_DEBUG, 1);
|
dest = uc_log_new_file(FILE_NAME, UC_LL_DEBUG, 0);
|
||||||
fail_if(dest == NULL);
|
fail_if(dest == NULL);
|
||||||
uc_log_add_destination(dest);
|
uc_log_add_destination(dest);
|
||||||
|
|
||||||
@@ -243,20 +242,20 @@ START_TEST (test_logfile_reopen_files)
|
|||||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
fail_if(rc != 0);
|
||||||
fail_if(st.st_size != 77*2, "was %ld", (long)st.st_size);
|
fail_if(st.st_size != 104);
|
||||||
|
|
||||||
rc = remove(FILE_NAME);
|
rc = remove(FILE_NAME);
|
||||||
fail_if(rc != 0, "Remove failed %s", strerror(errno));
|
fail_if(rc != 0);
|
||||||
|
|
||||||
rc = uc_log_reopen_files();
|
rc = uc_log_reopen_files();
|
||||||
fail_if(rc != 0, "uc_log_reopen_files failed: %d", rc);
|
fail_if(rc != 0);
|
||||||
|
|
||||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "2. stat failed: %s", strerror(errno));
|
fail_if(rc != 0);
|
||||||
fail_if(st.st_size != 77, "was %ld", (long)st.st_size);//should only one line there now
|
fail_if(st.st_size != 52);//should only one line there now
|
||||||
|
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
@@ -281,10 +280,10 @@ START_TEST (test_logfile_remove_dest)
|
|||||||
uc_log_init(&mods);
|
uc_log_init(&mods);
|
||||||
|
|
||||||
|
|
||||||
dest1 = uc_log_new_file(FILE_NAME, UC_LL_DEBUG, 1);
|
dest1 = uc_log_new_file(FILE_NAME, UC_LL_DEBUG, 0);
|
||||||
fail_if(dest1 == NULL);
|
fail_if(dest1 == NULL);
|
||||||
|
|
||||||
dest2 = uc_log_new_stderr(UC_LL_WARNING, 1);
|
dest2 = uc_log_new_stderr(UC_LL_WARNING, 0);
|
||||||
fail_if(dest2 == NULL);
|
fail_if(dest2 == NULL);
|
||||||
|
|
||||||
uc_log_add_destination(dest1);
|
uc_log_add_destination(dest1);
|
||||||
@@ -294,25 +293,25 @@ START_TEST (test_logfile_remove_dest)
|
|||||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
fail_if(rc != 0);
|
||||||
fail_if(st.st_size != 77*2, "was %ld", (long)st.st_size);
|
fail_if(st.st_size != 104);
|
||||||
|
|
||||||
uc_log_remove_destination(dest1);
|
uc_log_remove_destination(dest1);
|
||||||
|
|
||||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); //should not be logged now
|
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); //should not be logged now
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "2. stat failed: %s", strerror(errno));
|
fail_if(rc != 0);
|
||||||
fail_if(st.st_size != 77*2, "was %ld", (long)st.st_size);//should be same size
|
fail_if(st.st_size != 104);//should be same size
|
||||||
|
|
||||||
//removing the last destination should be fine too
|
//removing the last destination should be fine too
|
||||||
uc_log_remove_destination(dest2);
|
uc_log_remove_destination(dest2);
|
||||||
|
|
||||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "2. stat failed: %s", strerror(errno));
|
fail_if(rc != 0);
|
||||||
fail_if(st.st_size != 77*2, "was %ld", (long)st.st_size);//should be same size
|
fail_if(st.st_size != 104);//should be same size
|
||||||
|
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
@@ -337,7 +336,7 @@ START_TEST (test_logfile_full_filesystem)
|
|||||||
uc_log_init(&mods);
|
uc_log_init(&mods);
|
||||||
|
|
||||||
dest = uc_log_new_file("/dev/full", UC_LL_DEBUG, 1);
|
dest = uc_log_new_file("/dev/full", UC_LL_DEBUG, 1);
|
||||||
fail_if(dest == NULL, "Cannot open /dev/full");
|
fail_if(dest == NULL);
|
||||||
uc_log_add_destination(dest);
|
uc_log_add_destination(dest);
|
||||||
|
|
||||||
for (i = 0; i < 1024; i++) {
|
for (i = 0; i < 1024; i++) {
|
||||||
@@ -397,7 +396,7 @@ START_TEST (test_logfile_invalid_file_after_reopen)
|
|||||||
logging_rm_subdir();
|
logging_rm_subdir();
|
||||||
|
|
||||||
rc = access(SUBDIR_FILE_NAME, W_OK);
|
rc = access(SUBDIR_FILE_NAME, W_OK);
|
||||||
fail_if(rc == 0, "Test setup is wrong. Can still access" SUBDIR_FILE_NAME "");
|
fail_if(rc == 0);
|
||||||
|
|
||||||
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||||
UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson %d", 1);
|
UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson %d", 1);
|
||||||
@@ -440,8 +439,8 @@ START_TEST (test_logfile_raw)
|
|||||||
UC_LOGFR(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
UC_LOGFR(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
fail_if(rc != 0);
|
||||||
fail_if(st.st_size != 14*2, "was %ld", (long)st.st_size);
|
fail_if(st.st_size != 14*2);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -480,16 +479,16 @@ START_TEST (test_logfile_dest_mask)
|
|||||||
UC_LOGFR(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
UC_LOGFR(UC_LL_DEBUG, 0, "Lorum ipson %d", 1);
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
fail_if(rc != 0);
|
||||||
fail_if(st.st_size != 0, "was %ld", (long)st.st_size);
|
fail_if(st.st_size != 0);
|
||||||
|
|
||||||
uc_log_destination_set_mask(dest, "MOD1=DEBUG:mod2=Debug");
|
uc_log_destination_set_mask(dest, "MOD1=DEBUG:mod2=Debug");
|
||||||
UC_LOGFR(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
UC_LOGFR(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1);
|
||||||
UC_LOGFR(UC_LL_DEBUG, 1, "Lorum ipson %d\n", 1);
|
UC_LOGFR(UC_LL_DEBUG, 1, "Lorum ipson %d\n", 1);
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
fail_if(rc != 0);
|
||||||
fail_if(st.st_size != 14*2, "was %ld", (long)st.st_size);
|
fail_if(st.st_size != 14*2);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -519,8 +518,8 @@ START_TEST (test_loglevel_module_none)
|
|||||||
UC_LOGFR(UC_LL_ERROR, 0, "Lorum ipson %d\n", 1);
|
UC_LOGFR(UC_LL_ERROR, 0, "Lorum ipson %d\n", 1);
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
fail_if(rc != 0);
|
||||||
fail_if(st.st_size != 0, "was %ld", (long)st.st_size);
|
fail_if(st.st_size != 0);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -550,8 +549,8 @@ START_TEST (test_loglevel_dest_none)
|
|||||||
UC_LOGFR(UC_LL_WARNING, 0, "Lorum ipson %d\n", 1);
|
UC_LOGFR(UC_LL_WARNING, 0, "Lorum ipson %d\n", 1);
|
||||||
|
|
||||||
rc = stat(FILE_NAME, &st);
|
rc = stat(FILE_NAME, &st);
|
||||||
fail_if(rc != 0, "stat failed: %s", strerror(errno));
|
fail_if(rc != 0);
|
||||||
fail_if(st.st_size != 0, "was %ld", (long)st.st_size);
|
fail_if(st.st_size != 0);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
|||||||
+84
-84
@@ -9,8 +9,8 @@ START_TEST (test_pack16_le_1)
|
|||||||
|
|
||||||
uc_pack_16_le(v,r);
|
uc_pack_16_le(v,r);
|
||||||
|
|
||||||
fail_if(r[0] != 0x34,"was 0x%x",r[0]);
|
fail_if(r[0] != 0x34);
|
||||||
fail_if(r[1] != 0x12,"was 0x%x",r[1]);
|
fail_if(r[1] != 0x12);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -21,8 +21,8 @@ START_TEST (test_pack16_le_2)
|
|||||||
|
|
||||||
uc_pack_16_le(v,r);
|
uc_pack_16_le(v,r);
|
||||||
|
|
||||||
fail_if(r[0] != 0xEF,"was 0x%x",r[0]);
|
fail_if(r[0] != 0xEF);
|
||||||
fail_if(r[1] != 0xFE,"was 0x%x",r[1]);
|
fail_if(r[1] != 0xFE);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -33,8 +33,8 @@ START_TEST (test_pack16_be_1)
|
|||||||
|
|
||||||
uc_pack_16_be(v,r);
|
uc_pack_16_be(v,r);
|
||||||
|
|
||||||
fail_if(r[0] != 0x12,"was 0x%x",r[0]);
|
fail_if(r[0] != 0x12);
|
||||||
fail_if(r[1] != 0x34,"was 0x%x",r[1]);
|
fail_if(r[1] != 0x34);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -45,8 +45,8 @@ START_TEST (test_pack16_be_2)
|
|||||||
|
|
||||||
uc_pack_16_be(v, r);
|
uc_pack_16_be(v, r);
|
||||||
|
|
||||||
fail_if(r[0] != 0xFE,"was 0x%x",r[0]);
|
fail_if(r[0] != 0xFE);
|
||||||
fail_if(r[1] != 0xEF,"was 0x%x",r[1]);
|
fail_if(r[1] != 0xEF);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ START_TEST (test_unpack16_le_1)
|
|||||||
|
|
||||||
v = uc_unpack_16_le(r);
|
v = uc_unpack_16_le(r);
|
||||||
|
|
||||||
fail_if(v != 0x3412,"was 0x%x",v);
|
fail_if(v != 0x3412);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ START_TEST (test_unpack16_le_2)
|
|||||||
|
|
||||||
v = uc_unpack_16_le(r);
|
v = uc_unpack_16_le(r);
|
||||||
|
|
||||||
fail_if(v != 0xEFFE,"was 0x%x",v);
|
fail_if(v != 0xEFFE);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ START_TEST (test_unpack16_be_1)
|
|||||||
|
|
||||||
v = uc_unpack_16_be(r);
|
v = uc_unpack_16_be(r);
|
||||||
|
|
||||||
fail_if(v != 0x1234,"was 0x%x",v);
|
fail_if(v != 0x1234);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ START_TEST (test_unpack16_be_2)
|
|||||||
|
|
||||||
v = uc_unpack_16_be(r);
|
v = uc_unpack_16_be(r);
|
||||||
|
|
||||||
fail_if(v != 0xFEEF,"was 0x%x",v);
|
fail_if(v != 0xFEEF);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -101,9 +101,9 @@ START_TEST (test_pack24_le_1)
|
|||||||
|
|
||||||
uc_pack_24_le(v,r);
|
uc_pack_24_le(v,r);
|
||||||
|
|
||||||
fail_if(r[0] != 0x56,"was 0x%x",r[0]);
|
fail_if(r[0] != 0x56);
|
||||||
fail_if(r[1] != 0x34,"was 0x%x",r[1]);
|
fail_if(r[1] != 0x34);
|
||||||
fail_if(r[2] != 0x12,"was 0x%x",r[2]);
|
fail_if(r[2] != 0x12);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -114,9 +114,9 @@ START_TEST (test_pack24_le_2)
|
|||||||
|
|
||||||
uc_pack_24_le(v,r);
|
uc_pack_24_le(v,r);
|
||||||
|
|
||||||
fail_if(r[0] != 0xF6,"was 0x%x",r[0]);
|
fail_if(r[0] != 0xF6);
|
||||||
fail_if(r[1] != 0xF7,"was 0x%x",r[1]);
|
fail_if(r[1] != 0xF7);
|
||||||
fail_if(r[2] != 0xF8,"was 0x%x",r[2]);
|
fail_if(r[2] != 0xF8);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -127,9 +127,9 @@ START_TEST (test_pack24_be_1)
|
|||||||
|
|
||||||
uc_pack_24_be(v,r);
|
uc_pack_24_be(v,r);
|
||||||
|
|
||||||
fail_if(r[0] != 0x12,"was 0x%x",r[0]);
|
fail_if(r[0] != 0x12);
|
||||||
fail_if(r[1] != 0x34,"was 0x%x",r[1]);
|
fail_if(r[1] != 0x34);
|
||||||
fail_if(r[2] != 0x56,"was 0x%x",r[2]);
|
fail_if(r[2] != 0x56);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -140,9 +140,9 @@ START_TEST (test_pack24_be_2)
|
|||||||
|
|
||||||
uc_pack_24_be(v,r);
|
uc_pack_24_be(v,r);
|
||||||
|
|
||||||
fail_if(r[0] != 0xF8,"was 0x%x",r[0]);
|
fail_if(r[0] != 0xF8);
|
||||||
fail_if(r[1] != 0xF7,"was 0x%x",r[1]);
|
fail_if(r[1] != 0xF7);
|
||||||
fail_if(r[2] != 0xF6,"was 0x%x",r[2]);
|
fail_if(r[2] != 0xF6);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -153,10 +153,10 @@ START_TEST (test_pack32_le_1)
|
|||||||
|
|
||||||
uc_pack_32_le(v,r);
|
uc_pack_32_le(v,r);
|
||||||
|
|
||||||
fail_if(r[0] != 0x78,"was 0x%x",r[0]);
|
fail_if(r[0] != 0x78);
|
||||||
fail_if(r[1] != 0x56,"was 0x%x",r[1]);
|
fail_if(r[1] != 0x56);
|
||||||
fail_if(r[2] != 0x34,"was 0x%x",r[2]);
|
fail_if(r[2] != 0x34);
|
||||||
fail_if(r[3] != 0x12,"was 0x%x",r[3]);
|
fail_if(r[3] != 0x12);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -167,10 +167,10 @@ START_TEST (test_pack32_le_2)
|
|||||||
|
|
||||||
uc_pack_32_le(v,r);
|
uc_pack_32_le(v,r);
|
||||||
|
|
||||||
fail_if(r[0] != 0xF4,"was 0x%x",r[0]);
|
fail_if(r[0] != 0xF4);
|
||||||
fail_if(r[1] != 0xF6,"was 0x%x",r[1]);
|
fail_if(r[1] != 0xF6);
|
||||||
fail_if(r[2] != 0xF7,"was 0x%x",r[2]);
|
fail_if(r[2] != 0xF7);
|
||||||
fail_if(r[3] != 0xF8,"was 0x%x",r[3]);
|
fail_if(r[3] != 0xF8);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -181,10 +181,10 @@ START_TEST (test_pack32_be_1)
|
|||||||
|
|
||||||
uc_pack_32_be(v,r);
|
uc_pack_32_be(v,r);
|
||||||
|
|
||||||
fail_if(r[3] != 0x78,"was 0x%x",r[3]);
|
fail_if(r[3] != 0x78);
|
||||||
fail_if(r[2] != 0x56,"was 0x%x",r[2]);
|
fail_if(r[2] != 0x56);
|
||||||
fail_if(r[1] != 0x34,"was 0x%x",r[1]);
|
fail_if(r[1] != 0x34);
|
||||||
fail_if(r[0] != 0x12,"was 0x%x",r[0]);
|
fail_if(r[0] != 0x12);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -195,10 +195,10 @@ START_TEST (test_pack32_be_2)
|
|||||||
|
|
||||||
uc_pack_32_be(v,r);
|
uc_pack_32_be(v,r);
|
||||||
|
|
||||||
fail_if(r[3] != 0xF4,"was 0x%x",r[3]);
|
fail_if(r[3] != 0xF4);
|
||||||
fail_if(r[2] != 0xF6,"was 0x%x",r[2]);
|
fail_if(r[2] != 0xF6);
|
||||||
fail_if(r[1] != 0xF7,"was 0x%x",r[1]);
|
fail_if(r[1] != 0xF7);
|
||||||
fail_if(r[0] != 0xF8,"was 0x%x",r[0]);
|
fail_if(r[0] != 0xF8);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -209,7 +209,7 @@ START_TEST (test_unpack24_le_1)
|
|||||||
|
|
||||||
v = uc_unpack_24_le(r);
|
v = uc_unpack_24_le(r);
|
||||||
|
|
||||||
fail_if(v != 0x563412,"was 0x%x",v);
|
fail_if(v != 0x563412);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -220,7 +220,7 @@ START_TEST (test_unpack24_le_2)
|
|||||||
|
|
||||||
v = uc_unpack_24_le(r);
|
v = uc_unpack_24_le(r);
|
||||||
|
|
||||||
fail_if(v != 0xF6F7F8,"was 0x%x",v);
|
fail_if(v != 0xF6F7F8);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -231,7 +231,7 @@ START_TEST (test_unpack24_be_1)
|
|||||||
|
|
||||||
v = uc_unpack_24_be(r);
|
v = uc_unpack_24_be(r);
|
||||||
|
|
||||||
fail_if(v != 0x123456,"was 0x%x",v);
|
fail_if(v != 0x123456);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -242,7 +242,7 @@ START_TEST (test_unpack24_be_2)
|
|||||||
|
|
||||||
v = uc_unpack_24_be(r);
|
v = uc_unpack_24_be(r);
|
||||||
|
|
||||||
fail_if(v != 0xF8F7F6,"was 0x%x",v);
|
fail_if(v != 0xF8F7F6);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -253,7 +253,7 @@ START_TEST (test_unpack32_le_1)
|
|||||||
|
|
||||||
v = uc_unpack_32_le(r);
|
v = uc_unpack_32_le(r);
|
||||||
|
|
||||||
fail_if(v != 0x78563412,"was 0x%x",v);
|
fail_if(v != 0x78563412);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -264,7 +264,7 @@ START_TEST (test_unpack32_le_2)
|
|||||||
|
|
||||||
v = uc_unpack_32_le(r);
|
v = uc_unpack_32_le(r);
|
||||||
|
|
||||||
fail_if(v != 0xF4F6F7F8,"was 0x%x",v);
|
fail_if(v != 0xF4F6F7F8);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -275,7 +275,7 @@ START_TEST (test_unpack32_be_1)
|
|||||||
|
|
||||||
v = uc_unpack_32_be(r);
|
v = uc_unpack_32_be(r);
|
||||||
|
|
||||||
fail_if(v != 0x12345678,"was 0x%x",v);
|
fail_if(v != 0x12345678);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -286,7 +286,7 @@ START_TEST (test_unpack32_be_2)
|
|||||||
|
|
||||||
v = uc_unpack_32_be(r);
|
v = uc_unpack_32_be(r);
|
||||||
|
|
||||||
fail_if(v != 0xF8F7F6F4,"was 0x%x",v);
|
fail_if(v != 0xF8F7F6F4);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -297,14 +297,14 @@ START_TEST (test_pack64_le_1)
|
|||||||
|
|
||||||
uc_pack_64_le(v, r);
|
uc_pack_64_le(v, r);
|
||||||
|
|
||||||
fail_if(r[0] != 0x88,"was 0x%x",r[0]);
|
fail_if(r[0] != 0x88);
|
||||||
fail_if(r[1] != 0x77,"was 0x%x",r[1]);
|
fail_if(r[1] != 0x77);
|
||||||
fail_if(r[2] != 0x66,"was 0x%x",r[2]);
|
fail_if(r[2] != 0x66);
|
||||||
fail_if(r[3] != 0x55,"was 0x%x",r[3]);
|
fail_if(r[3] != 0x55);
|
||||||
fail_if(r[4] != 0x44,"was 0x%x",r[4]);
|
fail_if(r[4] != 0x44);
|
||||||
fail_if(r[5] != 0x33,"was 0x%x",r[5]);
|
fail_if(r[5] != 0x33);
|
||||||
fail_if(r[6] != 0x22,"was 0x%x",r[6]);
|
fail_if(r[6] != 0x22);
|
||||||
fail_if(r[7] != 0x11,"was 0x%x",r[7]);
|
fail_if(r[7] != 0x11);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -315,14 +315,14 @@ START_TEST (test_pack64_le_2)
|
|||||||
|
|
||||||
uc_pack_64_le(v, r);
|
uc_pack_64_le(v, r);
|
||||||
|
|
||||||
fail_if(r[0] != 0xF8,"was 0x%x",r[0]);
|
fail_if(r[0] != 0xF8);
|
||||||
fail_if(r[1] != 0xF9,"was 0x%x",r[1]);
|
fail_if(r[1] != 0xF9);
|
||||||
fail_if(r[2] != 0xFA,"was 0x%x",r[2]);
|
fail_if(r[2] != 0xFA);
|
||||||
fail_if(r[3] != 0xFB,"was 0x%x",r[3]);
|
fail_if(r[3] != 0xFB);
|
||||||
fail_if(r[4] != 0xFC,"was 0x%x",r[4]);
|
fail_if(r[4] != 0xFC);
|
||||||
fail_if(r[5] != 0xFD,"was 0x%x",r[5]);
|
fail_if(r[5] != 0xFD);
|
||||||
fail_if(r[6] != 0xFE,"was 0x%x",r[6]);
|
fail_if(r[6] != 0xFE);
|
||||||
fail_if(r[7] != 0xFF,"was 0x%x",r[7]);
|
fail_if(r[7] != 0xFF);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -333,7 +333,7 @@ START_TEST (test_unpack64_le_1)
|
|||||||
|
|
||||||
v = uc_unpack_64_le(r);
|
v = uc_unpack_64_le(r);
|
||||||
|
|
||||||
fail_if(v != 0x8877665544332211ULL,"was 0x%llx",v);
|
fail_if(v != 0x8877665544332211ULL);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -345,7 +345,7 @@ START_TEST (test_unpack64_le_2)
|
|||||||
|
|
||||||
v = uc_unpack_64_le(r);
|
v = uc_unpack_64_le(r);
|
||||||
|
|
||||||
fail_if(v != 0xF8F9FAFBFCFDFEFFULL,"was 0x%llx",v);
|
fail_if(v != 0xF8F9FAFBFCFDFEFFULL);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -356,14 +356,14 @@ START_TEST (test_pack64_be_1)
|
|||||||
|
|
||||||
uc_pack_64_be(v, r);
|
uc_pack_64_be(v, r);
|
||||||
|
|
||||||
fail_if(r[0] != 0x11,"was 0x%x",r[0]);
|
fail_if(r[0] != 0x11);
|
||||||
fail_if(r[1] != 0x22,"was 0x%x",r[1]);
|
fail_if(r[1] != 0x22);
|
||||||
fail_if(r[2] != 0x33,"was 0x%x",r[2]);
|
fail_if(r[2] != 0x33);
|
||||||
fail_if(r[3] != 0x44,"was 0x%x",r[3]);
|
fail_if(r[3] != 0x44);
|
||||||
fail_if(r[4] != 0x55,"was 0x%x",r[4]);
|
fail_if(r[4] != 0x55);
|
||||||
fail_if(r[5] != 0x66,"was 0x%x",r[5]);
|
fail_if(r[5] != 0x66);
|
||||||
fail_if(r[6] != 0x77,"was 0x%x",r[6]);
|
fail_if(r[6] != 0x77);
|
||||||
fail_if(r[7] != 0x88,"was 0x%x",r[7]);
|
fail_if(r[7] != 0x88);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -374,14 +374,14 @@ START_TEST (test_pack64_be_2)
|
|||||||
|
|
||||||
uc_pack_64_be(v, r);
|
uc_pack_64_be(v, r);
|
||||||
|
|
||||||
fail_if(r[0] != 0xFF,"was 0x%x",r[0]);
|
fail_if(r[0] != 0xFF);
|
||||||
fail_if(r[1] != 0xFE,"was 0x%x",r[1]);
|
fail_if(r[1] != 0xFE);
|
||||||
fail_if(r[2] != 0xFD,"was 0x%x",r[2]);
|
fail_if(r[2] != 0xFD);
|
||||||
fail_if(r[3] != 0xFC,"was 0x%x",r[3]);
|
fail_if(r[3] != 0xFC);
|
||||||
fail_if(r[4] != 0xFB,"was 0x%x",r[4]);
|
fail_if(r[4] != 0xFB);
|
||||||
fail_if(r[5] != 0xFA,"was 0x%x",r[5]);
|
fail_if(r[5] != 0xFA);
|
||||||
fail_if(r[6] != 0xF9,"was 0x%x",r[6]);
|
fail_if(r[6] != 0xF9);
|
||||||
fail_if(r[7] != 0xF8,"was 0x%x",r[7]);
|
fail_if(r[7] != 0xF8);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -392,7 +392,7 @@ START_TEST (test_unpack64_be_1)
|
|||||||
|
|
||||||
v = uc_unpack_64_be(r);
|
v = uc_unpack_64_be(r);
|
||||||
|
|
||||||
fail_if(v != 0x1122334455667788ULL,"was 0x%llx",v);
|
fail_if(v != 0x1122334455667788ULL);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -403,7 +403,7 @@ START_TEST (test_unpack64_be_2)
|
|||||||
|
|
||||||
v = uc_unpack_64_be(r);
|
v = uc_unpack_64_be(r);
|
||||||
|
|
||||||
fail_if(v != 0xFFFEFDFCFBFAF9F8ULL,"was 0x%llx",v);
|
fail_if(v != 0xFFFEFDFCFBFAF9F8ULL);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ START_TEST (test_ratelimit_1)
|
|||||||
|
|
||||||
uc_ratelimit_init(&r, 30, 2);
|
uc_ratelimit_init(&r, 30, 2);
|
||||||
for (i = 0; i < 30; i++) {
|
for (i = 0; i < 30; i++) {
|
||||||
fail_if(!uc_ratelimit_allow(&r, now), "i = %d", i);
|
fail_if(!uc_ratelimit_allow(&r, now));
|
||||||
}
|
}
|
||||||
fail_if(uc_ratelimit_allow(&r, now));
|
fail_if(uc_ratelimit_allow(&r, now));
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-25
@@ -18,8 +18,8 @@ START_TEST (test_read_file_non_existing_file)
|
|||||||
content = uc_read_file("non existing file 123765", &len, 1000000000);
|
content = uc_read_file("non existing file 123765", &len, 1000000000);
|
||||||
saved_errno = errno;
|
saved_errno = errno;
|
||||||
|
|
||||||
fail_if(content != NULL);
|
ck_assert_ptr_null(content);
|
||||||
fail_if(saved_errno == 0);
|
ck_assert_int_ne(saved_errno, 0);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -31,20 +31,20 @@ START_TEST (test_read_file_simple)
|
|||||||
ssize_t rc;
|
ssize_t rc;
|
||||||
|
|
||||||
int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0664);
|
int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0664);
|
||||||
fail_if(fd == -1);
|
ck_assert_int_ne(fd, -1);
|
||||||
|
|
||||||
rc = write(fd, "hello", 5);
|
rc = write(fd, "hello", 5);
|
||||||
fail_if(rc != 5, "rc was %ld", (long)rc);
|
ck_assert_int_eq(rc, 5);
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
content = uc_read_file(filename, &len, 1000000000);
|
content = uc_read_file(filename, &len, 1000000000);
|
||||||
unlink(filename);
|
unlink(filename);
|
||||||
|
|
||||||
fail_if(content == NULL);
|
ck_assert_ptr_nonnull(content);
|
||||||
fail_if(len != 5);
|
ck_assert_uint_eq(len, 5);
|
||||||
fail_if(strlen(content) != 5);
|
ck_assert_uint_eq(strlen(content), 5);
|
||||||
fail_if(strcmp("hello", content) != 0);
|
ck_assert_str_eq("hello", content);
|
||||||
free(content);
|
free(content);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
@@ -61,7 +61,7 @@ START_TEST (test_read_file_greater_than_max)
|
|||||||
fail_if(fd == -1);
|
fail_if(fd == -1);
|
||||||
|
|
||||||
rc = write(fd, "hello", 5);
|
rc = write(fd, "hello", 5);
|
||||||
fail_if(rc != 5, "rc was %ld", (long)rc);
|
fail_if(rc != 5);
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
@@ -69,8 +69,8 @@ START_TEST (test_read_file_greater_than_max)
|
|||||||
saved_errno = errno;
|
saved_errno = errno;
|
||||||
unlink(filename);
|
unlink(filename);
|
||||||
|
|
||||||
fail_if(content != NULL);
|
ck_assert_ptr_null(content);
|
||||||
fail_if(saved_errno != EMSGSIZE, "was %d", saved_errno);
|
ck_assert_int_eq(saved_errno, EMSGSIZE);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -87,16 +87,16 @@ START_TEST (test_read_file_boundary)
|
|||||||
fail_if(fd == -1);
|
fail_if(fd == -1);
|
||||||
|
|
||||||
rc = write(fd, buf, sizeof buf);
|
rc = write(fd, buf, sizeof buf);
|
||||||
fail_if(rc != sizeof buf, "rc was %ld", (long)rc);
|
ck_assert_uint_eq(rc, sizeof buf);
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
content = uc_read_file(filename, &len, 1000000000);
|
content = uc_read_file(filename, &len, 1000000000);
|
||||||
unlink(filename);
|
unlink(filename);
|
||||||
|
|
||||||
fail_if(content == NULL);
|
ck_assert_ptr_nonnull(content);
|
||||||
fail_if(len != sizeof buf);
|
ck_assert_uint_eq(len, sizeof buf);
|
||||||
fail_if(strcmp("foobar", &content[1022]) != 0);
|
ck_assert_str_eq("foobar", &content[1022]);
|
||||||
free(content);
|
free(content);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
@@ -107,10 +107,10 @@ START_TEST (test_read_file_devnull)
|
|||||||
size_t len = 123;
|
size_t len = 123;
|
||||||
|
|
||||||
content = uc_read_file("/dev/null", &len, 1024);
|
content = uc_read_file("/dev/null", &len, 1024);
|
||||||
fail_if(content == NULL);
|
ck_assert_ptr_nonnull(content);
|
||||||
fail_if(len != 0);
|
ck_assert_uint_eq(len, 0);
|
||||||
free(content);
|
free(content);
|
||||||
|
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
@@ -125,14 +125,14 @@ START_TEST (test_read_file_too_big)
|
|||||||
fail_if(fd == -1);
|
fail_if(fd == -1);
|
||||||
|
|
||||||
rc = write(fd, "hello", 5);
|
rc = write(fd, "hello", 5);
|
||||||
fail_if(rc != 5, "rc was %ld", (long)rc);
|
fail_if(rc != 5);
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
content = uc_read_file(filename, &len, 4);
|
content = uc_read_file(filename, &len, 4);
|
||||||
|
|
||||||
fail_if(errno != EMSGSIZE);
|
ck_assert_int_eq(errno, EMSGSIZE);
|
||||||
fail_if(content != NULL);
|
ck_assert_ptr_null(content);
|
||||||
|
|
||||||
unlink(filename);
|
unlink(filename);
|
||||||
}
|
}
|
||||||
@@ -147,18 +147,18 @@ START_TEST (test_read_file_big)
|
|||||||
ssize_t rc;
|
ssize_t rc;
|
||||||
|
|
||||||
int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0664);
|
int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0664);
|
||||||
fail_if(fd == -1);
|
ck_assert_int_ne(fd, -1);
|
||||||
memset(buf, 'a', sizeof buf);
|
memset(buf, 'a', sizeof buf);
|
||||||
|
|
||||||
rc = write(fd, buf, sizeof buf);
|
rc = write(fd, buf, sizeof buf);
|
||||||
fail_if(rc != sizeof buf, "rc was %ld", (long)rc);
|
ck_assert_uint_eq(rc, sizeof buf);
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
content = uc_read_file(filename, &len, 4096*16);
|
content = uc_read_file(filename, &len, 4096*16);
|
||||||
fail_if(content == NULL);
|
fail_if(content == NULL);
|
||||||
fail_if(len != sizeof buf);
|
ck_assert_uint_eq(len, sizeof buf);
|
||||||
fail_if(memcmp(content, buf, sizeof buf) != 0);
|
ck_assert_int_eq(memcmp(content, buf, sizeof buf), 0);
|
||||||
|
|
||||||
free(content);
|
free(content);
|
||||||
|
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ START_TEST (test_restart_counter_garble)
|
|||||||
ck_assert_int_eq(0, uc_restart_counter_get(&cnt));
|
ck_assert_int_eq(0, uc_restart_counter_get(&cnt));
|
||||||
|
|
||||||
rc = uc_restart_counter_init(&cnt, FILE_NAME, 0);
|
rc = uc_restart_counter_init(&cnt, FILE_NAME, 0);
|
||||||
fail_if(rc != UC_RC_OK, "%d", rc);
|
fail_if(rc != UC_RC_OK);
|
||||||
ck_assert_int_eq(1, uc_restart_counter_get(&cnt));
|
ck_assert_int_eq(1, uc_restart_counter_get(&cnt));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ extern Suite *ticket_lock_suite(void);
|
|||||||
extern Suite *restart_counter_suite(void);
|
extern Suite *restart_counter_suite(void);
|
||||||
extern Suite *iomux_suite(void);
|
extern Suite *iomux_suite(void);
|
||||||
extern Suite *iomux_signal_suite(void);
|
extern Suite *iomux_signal_suite(void);
|
||||||
|
extern Suite *string_suite(void);
|
||||||
extern Suite *ringbuf_suite(void);
|
extern Suite *ringbuf_suite(void);
|
||||||
|
|
||||||
static suite_func suites[] = {
|
static suite_func suites[] = {
|
||||||
@@ -64,7 +65,10 @@ static suite_func suites[] = {
|
|||||||
restart_counter_suite,
|
restart_counter_suite,
|
||||||
iomux_suite,
|
iomux_suite,
|
||||||
iomux_signal_suite,
|
iomux_signal_suite,
|
||||||
|
string_suite,
|
||||||
|
#ifndef __APPLE__
|
||||||
ringbuf_suite
|
ringbuf_suite
|
||||||
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,213 @@
|
|||||||
|
#include <check.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "ucore/string.h"
|
||||||
|
#include "ucore/utils.h"
|
||||||
|
|
||||||
|
|
||||||
|
START_TEST (test_getfields)
|
||||||
|
{
|
||||||
|
char str[] = "a;b;c";
|
||||||
|
char *letters[5] = {NULL};
|
||||||
|
|
||||||
|
int rc = uc_getfields(str, letters, 5, 0, ";");
|
||||||
|
ck_assert_int_eq(rc, 3);
|
||||||
|
|
||||||
|
|
||||||
|
ck_assert_str_eq("a", letters[0]);
|
||||||
|
ck_assert_str_eq("b", letters[1]);
|
||||||
|
ck_assert_str_eq("c", letters[2]);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST (test_getfields_consecutive)
|
||||||
|
{
|
||||||
|
char str[] = "a;;b;c;;;";
|
||||||
|
char *letters[7] = {NULL};
|
||||||
|
|
||||||
|
int rc = uc_getfields(str, letters, 5, 0, ";");
|
||||||
|
ck_assert_int_eq(rc, 5);
|
||||||
|
|
||||||
|
|
||||||
|
// This result is rather silly, but it's
|
||||||
|
// how getfields works with mflag=0
|
||||||
|
ck_assert_str_eq("a", letters[0]);
|
||||||
|
ck_assert_str_eq("", letters[1]);
|
||||||
|
ck_assert_str_eq("b", letters[2]);
|
||||||
|
ck_assert_str_eq("c", letters[3]);
|
||||||
|
ck_assert_str_eq(";;", letters[4]);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST (test_getfields_mflag)
|
||||||
|
{
|
||||||
|
char str[] = "a;b;c";
|
||||||
|
char *letters[5] = {NULL};
|
||||||
|
|
||||||
|
int rc = uc_getfields(str, letters, 5, 1, ";");
|
||||||
|
ck_assert_int_eq(rc, 3);
|
||||||
|
|
||||||
|
|
||||||
|
ck_assert_str_eq("a", letters[0]);
|
||||||
|
ck_assert_str_eq("b", letters[1]);
|
||||||
|
ck_assert_str_eq("c", letters[2]);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST (test_getfields_consecutive_mflag)
|
||||||
|
{
|
||||||
|
char str[] = "a;;b;c;;;";
|
||||||
|
char *letters[7] = {NULL};
|
||||||
|
|
||||||
|
int rc = uc_getfields(str, letters, 7, 1, ";");
|
||||||
|
ck_assert_int_eq(rc, 3);
|
||||||
|
|
||||||
|
|
||||||
|
// This result is rather silly, but it's
|
||||||
|
// how getfields works with mflag=0
|
||||||
|
ck_assert_str_eq("a", letters[0]);
|
||||||
|
ck_assert_str_eq("b", letters[1]);
|
||||||
|
ck_assert_str_eq("c", letters[2]);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST (test_getfields_too_many)
|
||||||
|
{
|
||||||
|
char str[] = "a\r\nb\r\nc\r\nd\r\ne";
|
||||||
|
char *letters[4] = {NULL};
|
||||||
|
|
||||||
|
int rc = uc_getfields(str, letters, 4, 0, "\r\n");
|
||||||
|
ck_assert_int_eq(rc, 4);
|
||||||
|
|
||||||
|
// This result is rather silly, but it's
|
||||||
|
// how getfields works with mflag=0
|
||||||
|
ck_assert_str_eq("a", letters[0]);
|
||||||
|
ck_assert_str_eq("", letters[1]);
|
||||||
|
ck_assert_str_eq("b", letters[2]);
|
||||||
|
ck_assert_str_eq("\nc\r\nd\r\ne", letters[3]);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST (test_getfields_too_many_mflag)
|
||||||
|
{
|
||||||
|
char str[] = "a\r\nb\r\nc\r\nd\r\ne";
|
||||||
|
char *letters[4] = {NULL};
|
||||||
|
|
||||||
|
int rc = uc_getfields(str, letters, 4, 1, "\r\n");
|
||||||
|
ck_assert_int_eq(rc, 4);
|
||||||
|
|
||||||
|
ck_assert_str_eq("a", letters[0]);
|
||||||
|
ck_assert_str_eq("b", letters[1]);
|
||||||
|
ck_assert_str_eq("c", letters[2]);
|
||||||
|
ck_assert_str_eq("d\r\ne", letters[3]);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST (test_getfields_empty)
|
||||||
|
{
|
||||||
|
char str[] = "";
|
||||||
|
char *letters[4] = {NULL};
|
||||||
|
|
||||||
|
int rc = uc_getfields(str, letters, 4, 0, ";\r\n");
|
||||||
|
ck_assert_int_eq(rc, 1);
|
||||||
|
ck_assert_str_eq("", letters[0]);
|
||||||
|
|
||||||
|
rc = uc_getfields(str, letters, 4, 1, ";\r\n");
|
||||||
|
ck_assert_int_eq(rc, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST (test_gettokens)
|
||||||
|
{
|
||||||
|
char str[] = "a;b;c";
|
||||||
|
char *letters[5] = {NULL};
|
||||||
|
|
||||||
|
int rc = uc_gettokens(str, letters, 5,";");
|
||||||
|
ck_assert_int_eq(rc, 3);
|
||||||
|
|
||||||
|
|
||||||
|
ck_assert_str_eq("a", letters[0]);
|
||||||
|
ck_assert_str_eq("b", letters[1]);
|
||||||
|
ck_assert_str_eq("c", letters[2]);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST (test_gettokens_consecutive)
|
||||||
|
{
|
||||||
|
char str[] = "a;;;b;;c;";
|
||||||
|
char *letters[5] = {NULL};
|
||||||
|
|
||||||
|
int rc = uc_gettokens(str, letters, 5,";");
|
||||||
|
ck_assert_int_eq(rc, 3);
|
||||||
|
|
||||||
|
|
||||||
|
ck_assert_str_eq("a", letters[0]);
|
||||||
|
ck_assert_str_eq("b", letters[1]);
|
||||||
|
ck_assert_str_eq("c", letters[2]);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST (test_gettokens_empty)
|
||||||
|
{
|
||||||
|
char str[] = "";
|
||||||
|
char *letters[5] = {NULL};
|
||||||
|
|
||||||
|
int rc = uc_gettokens(str, letters, 5,";");
|
||||||
|
ck_assert_int_eq(rc, 0);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST (test_gettokens_quotes)
|
||||||
|
{
|
||||||
|
char str[] = "\"abc\";d;\"e \"";
|
||||||
|
char *letters[5] = {NULL};
|
||||||
|
|
||||||
|
int rc = uc_gettokens(str, letters, 5,";");
|
||||||
|
ck_assert_int_eq(rc, 3);
|
||||||
|
|
||||||
|
ck_assert_str_eq("abc", letters[0]);
|
||||||
|
ck_assert_str_eq("d", letters[1]);
|
||||||
|
ck_assert_str_eq("e ", letters[2]);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST (test_gettokens_double_quotes)
|
||||||
|
{
|
||||||
|
char str[] = "\"\"abc\"\";d;\"e\"\"f\"\"\"";
|
||||||
|
char *letters[5] = {NULL};
|
||||||
|
|
||||||
|
int rc = uc_gettokens(str, letters, 5,";");
|
||||||
|
ck_assert_int_eq(rc, 3);
|
||||||
|
|
||||||
|
ck_assert_str_eq("abc", letters[0]);
|
||||||
|
ck_assert_str_eq("d", letters[1]);
|
||||||
|
ck_assert_str_eq("e\"f\"", letters[2]);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
Suite *string_suite(void)
|
||||||
|
{
|
||||||
|
Suite *s = suite_create("string");
|
||||||
|
TCase *tc = tcase_create("string");
|
||||||
|
|
||||||
|
tcase_add_test(tc, test_getfields);
|
||||||
|
tcase_add_test(tc, test_getfields_consecutive);
|
||||||
|
tcase_add_test(tc, test_getfields_mflag);
|
||||||
|
tcase_add_test(tc, test_getfields_consecutive_mflag);
|
||||||
|
tcase_add_test(tc, test_getfields_too_many);
|
||||||
|
tcase_add_test(tc, test_getfields_too_many_mflag);
|
||||||
|
tcase_add_test(tc, test_getfields_empty);
|
||||||
|
|
||||||
|
tcase_add_test(tc, test_gettokens);
|
||||||
|
tcase_add_test(tc, test_gettokens_consecutive);
|
||||||
|
tcase_add_test(tc, test_gettokens_empty);
|
||||||
|
tcase_add_test(tc, test_gettokens_quotes);
|
||||||
|
tcase_add_test(tc, test_gettokens_double_quotes);
|
||||||
|
|
||||||
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -135,6 +135,44 @@ START_TEST (test_strv_append_all_nocopy)
|
|||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST (test_strv_reverse)
|
||||||
|
{
|
||||||
|
struct UCStrv strv;
|
||||||
|
|
||||||
|
uc_strv_init(&strv);
|
||||||
|
|
||||||
|
uc_strv_append(&strv, "string1");
|
||||||
|
|
||||||
|
uc_strv_reverse(&strv);
|
||||||
|
ck_assert_str_eq("string1", strv.strings[0]);
|
||||||
|
|
||||||
|
uc_strv_destroy(&strv);
|
||||||
|
|
||||||
|
uc_strv_init(&strv);
|
||||||
|
|
||||||
|
uc_strv_append(&strv, "string1");
|
||||||
|
uc_strv_append(&strv, "string2");
|
||||||
|
|
||||||
|
uc_strv_reverse(&strv);
|
||||||
|
ck_assert_str_eq("string2", strv.strings[0]);
|
||||||
|
ck_assert_str_eq("string1", strv.strings[1]);
|
||||||
|
|
||||||
|
uc_strv_destroy(&strv);
|
||||||
|
|
||||||
|
uc_strv_init(&strv);
|
||||||
|
|
||||||
|
uc_strv_append(&strv, "string1");
|
||||||
|
uc_strv_append(&strv, "string2");
|
||||||
|
uc_strv_append(&strv, "string3");
|
||||||
|
|
||||||
|
uc_strv_reverse(&strv);
|
||||||
|
ck_assert_str_eq("string3", strv.strings[0]);
|
||||||
|
ck_assert_str_eq("string2", strv.strings[1]);
|
||||||
|
ck_assert_str_eq("string1", strv.strings[2]);
|
||||||
|
|
||||||
|
uc_strv_destroy(&strv);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
Suite *strv_suite(void)
|
Suite *strv_suite(void)
|
||||||
{
|
{
|
||||||
@@ -147,6 +185,7 @@ Suite *strv_suite(void)
|
|||||||
tcase_add_test(tc, test_strv_null_terminate);
|
tcase_add_test(tc, test_strv_null_terminate);
|
||||||
tcase_add_test(tc, test_strv_append_all_copy);
|
tcase_add_test(tc, test_strv_append_all_copy);
|
||||||
tcase_add_test(tc, test_strv_append_all_nocopy);
|
tcase_add_test(tc, test_strv_append_all_nocopy);
|
||||||
|
tcase_add_test(tc, test_strv_reverse);
|
||||||
|
|
||||||
suite_add_tcase(s, tc);
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user