Commits (2)
[submodule "cshared"]
path = cshared
url = https://github.com/fillabs/cshared.git
export LANG=en_US
ALL_CONFIGURATIONS := POSIX WIN32
.PHONY: all clean tests docs cleandocs distr DUMMY
BUILDROOT ?= $(PROJECTROOT)/build
CSHAREDDIR ?= $(PROJECTROOT)/cshared
CXMLDIR ?= $(PROJECTROOT)/cxml
ifeq ($(ARCH),)
ARCH = $(shell gcc -dumpmachine)
GCC := gcc
STRIP := strip
AR := ar
else
GCC := $(addprefix $(addsuffix -,$(ARCH)), gcc)
STRIP := $(addprefix $(addsuffix -,$(ARCH)), strip)
AR := $(addprefix $(addsuffix -,$(ARCH)), ar)
endif
-include $(BUILDROOT)/$(ARCH).mk
ifneq ($(findstring w32,$(ARCH)),)
packages := $(filter-out readline threads, $(packages))
CFG += WIN32
else
CFG += POSIX
endif
ifneq ($(findstring cygwin,$(ARCH)),)
CFG += CYGWIN
endif
ifneq ($(findstring openwrt,$(ARCH)),)
CFG += OPENWRT
endif
cflags += -fPIC -Wall
ifeq ($(DEBUG),)
DEBUG=no
endif
ifeq ($(DEBUG),yes)
cflags += -g -O0
defines += DEBUG
dsuffix = -d
else
defines += NDEBUG
cflags += -O2
endif
ifneq ($(filter readline, $(packages)),)
defines += USE_READLINE
libs += -lreadline
endif
ifneq ($(filter dmalloc, $(packages)),)
defines += DMALLOC DMALLOC_FUNC_CHECK
libs += -ldmalloc
dsuffix = -dmalloc
endif
ifneq ($(filter profile, $(packages)),)
cflags += -pg
endif
ifneq ($(filter openssl, $(packages)),)
ifneq ($(findstring mingw32,$(ARCH)),)
ifeq ($(OPENSSL_DIR),)
OPENSSL_DIR := C:/OpenSSL/Win32
endif
libs += $(OPENSSL_DIR)/lib/MinGW/libcrypto.a $(OPENSSL_DIR)/lib/MinGW/libssl.a
else
libs += -lssl -lcrypto
endif
ifneq ($(OPENSSL_DIR),)
includes += $(OPENSSL_DIR)/include
libs += -L $(OPENSSL_DIR)/lib
endif
endif
ifneq ($(filter cxml, $(packages)),)
predirs += $(CXMLDIR)
includes += $(CXMLDIR)
endif
ifneq ($(filter cshared, $(packages)),)
predirs += $(CSHAREDDIR)
includes += $(CSHAREDDIR)
endif
ifneq ($(filter pcap, $(packages)),)
ifneq ($(findstring cygwin,$(ARCH)),)
ifneq ($(NPCAP_SDK),)
includes += "$(NPCAP_SDK)/Include"
libs += "/cygdrive/c/Windows/System32/Npcap/wpcap.dll"
endif
else
libs += -lpcap
endif
endif
ifneq ($(filter thread, $(packages)),)
defines += USE_THREADS
libs += -lpthread
endif
ifeq ($(testdir), )
testdir := tests
endif
includes += $(foreach cfg,$(CFG),$(includes-$(cfg)))
defines += $(foreach cfg,$(CFG),$(defines-$(cfg)))
libs += $(foreach cfg,$(CFG),$(libs-$(cfg)))
sources += $(foreach cfg,$(CFG),$(sources-$(cfg)))
headers += $(foreach cfg,$(CFG),$(headers-$(cfg)))
tests += $(foreach cfg,$(CFG),$(tests-$(cfg)))
distfiles += $(foreach cfg,$(CFG),$(distfiles-$(cfg)))
predirs += $(foreach cfg,$(CFG),$(predirs-$(cfg)))
postdirs += $(foreach cfg,$(CFG),$(postdirs-$(cfg)))
tests := $(addprefix $(addsuffix /,$(testdir)),$(tests))
sources := $(addprefix $(addsuffix /,$(srcdir)),$(sources))
headers := $(addprefix $(addsuffix /,$(incdir)),$(headers))
cflags += $(addprefix -I, $(includes)) $(addprefix -D, $(defines))
ifeq ($(BUILDROOT),)
BUILDROOT = .
endif
outdir := $(BUILDROOT)/$(ARCH)$(dsuffix)
objdir := $(outdir)/o-$(PROJECT)
objects := $(patsubst %.c, $(objdir)/%.o, $(sources))
$(foreach b,$(bins),$(eval objects-$(b)=$$(patsubst %.c,$$(objdir)/%.o,$$(sources-$(b)))))
$(info objects-certgen=$(objects-certgen))
$(info objects-keygen=$(objects-keygen))
binobjects:= $(patsubst %.c, $(objdir)/%.o, $(foreach b,$(bins),$(sources-$(b))))
testbins := $(patsubst %.c, $(outdir)/%, $(tests))
dirs := $(objdir) $(outdir)/tests
alibnames := $(patsubst %, $(outdir)/lib%.a, $(alibs))
solibnames := $(patsubst %, $(outdir)/lib%.so, $(solibs))
binnames := $(patsubst %, $(outdir)/%, $(bins))
ldflags += $(patsubst %, -L%, $(outdir) $(libdirs))
ifneq ($(filter cxml, $(packages)),)
deplibs += $(outdir)/libcxml.a
endif
ifneq ($(filter cshared, $(packages)),)
deplibs += $(outdir)/libcshared.a
endif
all: $(dirs) $(pre) $(predirs) $(alibnames) $(solibnames) $(binnames) $(postdirs) $(post)
tests: all $(testbins)
$(predirs) $(postdirs): DUMMY
$(MAKE) -C $@ ARCH=$(ARCH) PROJECTROOT=$(realpath $(PROJECTROOT)) BUILDROOT=$(realpath $(BUILDROOT)) DEBUG=$(DEBUG)
define ALibRule
$$(outdir)/lib$(l).a: $$(outdir)/lib%.a : $$(objects-$(l)) $$(objects)
$$(AR) rcs $$@ $$^
endef
$(foreach l, $(alibs), $(eval $(ALibRule)))
define SoLibRule
$$(outdir)/lib$(l).so: $$(outdir)/lib%.so : $$(objects-$(l)) $$(objects) $$(deplibs)
$$(GCC) $$(cflags) -shared $$(ldflags) -o $$@ $$^ $$(csharedlib) $$(deplibs) $$(libs) $$(libs_$$*)
ifeq (no,$$(DEBUG))
$$(STRIP) $@
endif
endef
$(foreach l, $(solibs), $(eval $(SoLibRule)))
define BinRule
$$(outdir)/$(b): $$(outdir)/%: $$(objects-$(b)) $$(objects) $$(deplibs)
$$(GCC) $$(cflags) $$(ldflags) -o $$@ $$^ $$(csharedlib) $$(deplibs) $$(libs) $$(libs_$$*)
ifeq (no,$$(DEBUG))
$$(STRIP) $$@
endif
endef
$(foreach b, $(bins), $(eval $(BinRule)))
#$(eval $(call BinRule, certgen))
#$(eval $(call BinRule, keygen))
#$(binnames): $(outdir)/% : $(eval $$(objects-%)) $(objects) $(deplibs)
# $(GCC) $(cflags) $(ldflags) -o $@ $^ $(csharedlib) $(deplibs) $(libs) $(libs_$*)
#ifeq (no,$(DEBUG))
# $(STRIP) $@
#endif
$(testbins): $(alibnames)
$(testbins): $(outdir)/tests/% : tests/%.c
$(GCC) $(cflags) $(cflags_$*) -o $@ $< $(alibnames) $(libs) $(libs_$*)
ifeq (no,$(DEBUG))
$(STRIP) $@
endif
$(dirs):
mkdir -p $@
$(objects) $(binobjects): $(objdir)/%.o: %.c
@mkdir -p $(dir $@)
$(GCC) $(cflags) -o $@ -MMD -MF $(objdir)/$*.d -c $(abspath $<)
clean:
rm -rf $(alibnames) $(solibnames) $(binnames) $(testbins) $(objects)
distfiles += $(wildcard Makefile $(DOXYFILE))
dist:
-rm -rf $(PROJECT) $(PROJECT)-$(shell date -u '+%Y%m%d').tar.gz
mkdir $(PROJECT)
cp --parents $(sources) $(headers) $(distfiles) $(addprefix tests/, $(tests)) $(PROJECT)
tar -zcvf $(PROJECT)-$(shell date -u '+%Y%m%d').tar.gz $(PROJECT)
rm -rf $(PROJECT)
# tar -zcvf $(PROJECT)-$(shell date -u '+%Y%m%d').tar.gz $(sources) $(headers) $(distfiles) $(addprefix tests/, $(tests))
ifneq (,$(DOXYFILE))
docs: $(DOXYFILE)
doxygen $(DOXYFILE)
cleandocs:
rm -rf doc/html
endif
include $(wildcard $(addsuffix /*.d, $(objdir)))
......@@ -3,10 +3,11 @@
## Created by: Denis Filatov
##
## Copyleft (c) 2015
## This code is provided under the CeCill-C license agreement.
## This code is provided under the MIT license agreement.
######################################################################
PROJECTROOT = ..
BUILDROOT = $(PROJECTROOT)/build
#BUILDROOT = $(PROJECTROOT)/build
CSHAREDDIR = $(PROJECTROOT)/cshared
PROJECT = certgen
DEBUG = yes
bins = certgen keygen
......@@ -20,4 +21,4 @@ packages += cshared openssl
predirs := asncodec
includes += asncodec
libs += $(outdir)/libItsCertAsn.a
include $(BUILDROOT)/common.mk
include $(CSHAREDDIR)/common.mk
......@@ -11,7 +11,7 @@
xmlns:date="http://exslt.org/dates-and-times"
extension-element-prefixes="date"
>
<xsl:variable name="base-time" select="'2021-01-01'"/>
<xsl:variable name="base-time" select="'2022-01-01'"/>
<xsl:variable name="local-region" select="250"/>
<xsl:variable name="base-latitude" select="436169490.0"/>
<xsl:variable name="base-longitude" select="70533080.0"/>
......
......@@ -3,13 +3,14 @@
## Created by: Denis Filatov
##
## Copyleft (c) 2015
## This code is provided under the CeCill-C license agreement.
## This code is provided under the MIT license agreement.
######################################################################
PROJECTROOT = ../..
BUILDROOT = $(PROJECTROOT)/build
CSHAREDDIR = $(PROJECTROOT)/cshared
PROJECT = ItsCertAsn
DEBUG = yes
alibs = ItsCertAsn
sources := $(wildcard *.c)
includes += .
include $(BUILDROOT)/common.mk
include $(CSHAREDDIR)/common.mk
Subproject commit a4f1cc6b7f364c42c29e06190256534a6a11fbba
PROJECTROOT = ..
BUILDROOT = $(PROJECTROOT)/build/
PROJECT = cshared
DEBUG = yes
testdir = tests
alibs = $(PROJECT)
solibs = $(PROJECT)
sources := copts.c cserialize.c cstr.c cring.c e4c_lite.c
sources-WIN32 := cdir_win.c
headers := copts.h cserialize.h cstr.h cdir.h cring.h cmem.h e4c_lite.h
tests := test_copts.c
include $(BUILDROOT)/common.mk
#ifndef cdir_h
#define cdir_h
#include "cstr.h"
#include "cserialize.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct cdir_t cdir_t;
enum {
e_cdir_recursive = 1,
e_cdir_nofiles = 4,
e_cdir_nodirs = 8,
};
typedef struct {
const char * path;
const char * fname;
int flags;
uint64_t size;
}cdir_stat_t;
cdir_t * cdir_open(const pchar_t * path, const char * mask, int flags);
void cdir_close(cdir_t * dir);
cdir_t * cdir_rewind(cdir_t * dir);
const cdir_stat_t * cdir_next(cdir_t * dir);
int cdir_glob(const char * mask, const char * fname);
#ifdef __cplusplus
}
#endif
#endif
#define _CRT_SECURE_NO_WARNINGS
#include "cdir.h"
#include "cmem.h"
#include "cstr.h"
#include <windows.h>
struct cdir_t {
WIN32_FIND_DATA fd;
HANDLE h;
int flags;
char * path;
char * fname;
cdir_stat_t st;
};
static void _cdir_apply_filter(cdir_t * dir)
{
do {
if (dir->fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if (strcmp(".", dir->fd.cFileName) && strcmp("..", dir->fd.cFileName)){
if (0 == (dir->flags & e_cdir_nodirs)) return;
}
}
else {
if (0 == (dir->flags & e_cdir_nofiles)) return;
}
//skip this file
} while (FindNextFile(dir->h, &dir->fd));
FindClose(dir->h);
dir->h = INVALID_HANDLE_VALUE;
}
cdir_t * cdir_open(const pchar_t * path, const char * mask, int flags)
{
cdir_t * dir;
size_t plen = path ? pchar_len(path) : 0;
dir = cnew(cdir_t);
dir->path = pchar_alloc(plen + MAX_PATH + 1);
pchar_cpy(dir->path, path);
while (plen > 0 && (dir->path[plen - 1] == '/' || dir->path[plen - 1] == '\\'))plen--;
if (plen > 0) {
dir->path[plen] = '\\';
dir->fname = dir->path + plen + 1;
}
else{
dir->fname = dir->path;
}
dir->flags = flags;
if (mask == NULL) mask = "*";
strcpy(dir->fname, mask);
dir->h = FindFirstFile(dir->path, &dir->fd);
if (INVALID_HANDLE_VALUE == dir->h){
cfree(dir);
return NULL;
}
_cdir_apply_filter(dir);
dir->st.path = dir->path;
dir->st.fname = dir->fname;
return dir;
}
void cdir_close(cdir_t * dir)
{
if(dir){
if(dir->h != INVALID_HANDLE_VALUE){
FindClose(dir->h);
}
cfree(dir);
}
}
cdir_t * cdir_rewind(cdir_t * dir)
{
if(dir){
if(dir->h != INVALID_HANDLE_VALUE){
FindClose(dir->h);
}
*dir->fname = 0;
dir->h = FindFirstFile(dir->path, &dir->fd);
if(INVALID_HANDLE_VALUE == dir->h){
cfree(dir);
dir = NULL;
}
}
return dir;
}
const cdir_stat_t* cdir_next(cdir_t * dir)
{
if (dir && dir->h != INVALID_HANDLE_VALUE){
pchar_cpy(dir->fname, dir->fd.cFileName);
dir->st.size = dir->fd.nFileSizeHigh;
dir->st.size = (dir->st.size << 32) | dir->fd.nFileSizeLow;
if (FindNextFile(dir->h, &dir->fd)){
_cdir_apply_filter(dir);
}else {
FindClose(dir->h);
dir->h = INVALID_HANDLE_VALUE;
}
return &dir->st;
}
return NULL;
}
/*********************************************************************
######################################################################
##
## Created by: Denis Filatov
## Date : 10.11.2005
##
## Copyleft (c) 2003 - 2015
## This code is provided under the CeCill-C license agreement.
######################################################################
*********************************************************************/
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include "clog.h"
static int _clog_level = CLOG_INFO;
static FILE * _clog_out[CLOG_LASTLEVEL];
static const char * _clog_lnames[CLOG_LASTLEVEL] = {
"FATAL",
"ERROR",
"WARNING",
"INFO",
"DEBUG",
};
static int _clog_out_initialized = 0;
static void _clog_out_initialize(void)
{
int i;
_clog_out[CLOG_FATAL] = stderr;
_clog_out[CLOG_ERROR] = stderr;
_clog_out[CLOG_WARNING] = stderr;
for(i=CLOG_INFO; i<CLOG_LASTLEVEL; i++){
_clog_out[i] = stdout;
}
_clog_out_initialized = 1;
}
int clog_level(void)
{
return _clog_level;
}
void clog_set_level(int const level)
{
if(level >= 0 && level <= CLOG_DEBUG){
_clog_level = level;
}
}
const char * clog_level_name(int const level)
{
const char * ret = NULL;
if(level < CLOG_LASTLEVEL)
ret = _clog_lnames[level];
return ret ? ret : CLOG_DEFAULT_LEVEL_NAME;
}
void clog_set_level_name(int const level, const char * const name)
{
if(level < CLOG_LASTLEVEL)
_clog_lnames[level] = name;
}
void clog_set_output(int const level, void * const out)
{
if(0 == _clog_out_initialized){
_clog_out_initialize();
}
if(level < 0){
int i;
for(i=0; i<sizeof(_clog_out)/sizeof(_clog_out[0]); i++){
_clog_out[i] = (FILE*)out;
}
}else if(level < sizeof(_clog_out)/sizeof(_clog_out[0])){
_clog_out[level] = (FILE*)out;
}
}
void clog_fprintf(void * const f, int const level, const char * format, ...)
{
if(level <= _clog_level){
FILE * out;
va_list ap;
if(f){
out = (FILE*)f;
}else{
if(0 == _clog_out_initialized){
_clog_out_initialize();
}
if(level >= sizeof(_clog_out)/sizeof(_clog_out[0])){
out = _clog_out[sizeof(_clog_out)/sizeof(_clog_out[0]) - 1];
}else{
out = _clog_out[level];
}
}
if(out){
va_start(ap, format);
vfprintf(out, format, ap);
va_end(ap);
{
size_t l = strlen(format);
if(l == 0 || format[l-1]!= '\n'){
fprintf(out, "\n");
}
}
}
}
}
/*********************************************************************
######################################################################
##
## Created by: Denis Filatov
## Date : 10.11.2005
##
## Copyleft (c) 2003 - 2015
## This code is provided under the CeCill-C license agreement.
######################################################################
*********************************************************************/
#ifndef clog_h
#define clog_h
enum{
CLOG_FATAL=0,
CLOG_ERROR,
CLOG_WARNING,
CLOG_INFO,
CLOG_DEBUG,
CLOG_LASTLEVEL
};
int clog_level(void);
void clog_set_level(int const level);
const char * clog_level_name(int const level);
void clog_set_level_name(int const level, const char * const name);
void clog_set_output(int const level, void * const out);
#define CLOG_DEFAULT_LEVEL_NAME ""
#define STRMODULE(M) #M
#define XSTRMODULE(M) STRMODULE(M)
#define clog_flm(F, SMODULE, LEVEL, FORMAT, ...) clog_fprintf(F, LEVEL, "%10.10s: %7.7s: " FORMAT, SMODULE, clog_level_name(LEVEL), ##__VA_ARGS__)
#define clog_lm(SMODULE,LEVEL,FORMAT, ...) clog_flm((void*)0, SMODULE, LEVEL, FORMAT, ##__VA_ARGS__)
#define clog_fl(F,LEVEL,FORMAT, ...) clog_flm(F, XSTRMODULE(__MODULE__), LEVEL, FORMAT, ##__VA_ARGS__)
#define clog_l(LEVEL,FORMAT, ...) clog_flm((void*)0, XSTRMODULE(__MODULE__), LEVEL, FORMAT, ##__VA_ARGS__)
#define clog_fatal(FORMAT, ...) clog_l(CLOG_FATAL, FORMAT, ##__VA_ARGS__)
#define clog_error(FORMAT, ...) clog_l(CLOG_ERROR, FORMAT, ##__VA_ARGS__)
#define clog_warning(FORMAT, ...) clog_l(CLOG_WARNING, FORMAT, ##__VA_ARGS__)
#define clog_info(FORMAT, ...) clog_l(CLOG_INFO, FORMAT, ##__VA_ARGS__)
#define clog_debug(FORMAT, ...) clog_l(CLOG_DEBUG, FORMAT, ##__VA_ARGS__)
#define fclog_fatal(F,FORMAT, ...) clog_fl(F, CLOG_FATAL, FORMAT, ##__VA_ARGS__)
#define fclog_error(F,FORMAT, ...) clog_fl(F, CLOG_ERROR, FORMAT, ##__VA_ARGS__)
#define fclog_warning(F,FORMAT, ...) clog_fl(F, CLOG_WARNING, FORMAT, ##__VA_ARGS__)
#define fclog_info(F,FORMAT, ...) clog_fl(F, CLOG_INFO, FORMAT, ##__VA_ARGS__)
#define fclog_debug(F,FORMAT, ...) clog_fl(F, CLOG_DEBUG, FORMAT, ##__VA_ARGS__)
#define mclog_fatal(MODULE, FORMAT, ...) clog_lm(#MODULE, CLOG_FATAL, FORMAT, ##__VA_ARGS__)
#define mclog_error(MODULE, FORMAT, ...) clog_lm(#MODULE, CLOG_ERROR, FORMAT, ##__VA_ARGS__)
#define mclog_warning(MODULE, FORMAT, ...) clog_lm(#MODULE, CLOG_WARNING, FORMAT, ##__VA_ARGS__)
#define mclog_info(MODULE, FORMAT, ...) clog_lm(#MODULE, CLOG_INFO, FORMAT, ##__VA_ARGS__)
#define mclog_debug(MODULE, FORMAT, ...) clog_lm(#MODULE, CLOG_DEBUG, FORMAT, ##__VA_ARGS__)
#define fmclog_fatal(F, MODULE, FORMAT, ...) clog_flm(F, #MODULE, CLOG_FATAL, FORMAT, ##__VA_ARGS__)
#define fmclog_error(F, MODULE, FORMAT, ...) clog_flm(F, #MODULE, CLOG_ERROR, FORMAT, ##__VA_ARGS__)
#define fmclog_warning(F, MODULE, FORMAT, ...) clog_flm(F, #MODULE, CLOG_WARNING, FORMAT, ##__VA_ARGS__)
#define fmclog_info(F, MODULE, FORMAT, ...) clog_flm(F, #MODULE, CLOG_INFO, FORMAT, ##__VA_ARGS__)
#define fmclog_debug(F, MODULE, FORMAT, ...) clog_flm(F, #MODULE, CLOG_DEBUG, FORMAT, ##__VA_ARGS__)
void clog_fprintf(void * const f, int const level, const char * format, ...);
#undef __CLOG_MODULE
#endif
/*********************************************************************
######################################################################
##
## Created by: Denis Filatov
## Date : 10.11.2005
##
## Copyleft (c) 2003 - 2015
## This code is provided under the CeCill-C license agreement.
######################################################################
*********************************************************************/
#ifndef cmem_h
#define cmem_h
#include <stdlib.h>
#include <string.h>
#define callocate(N) malloc(N)
#define callocate0(N) calloc(1,N)
#define cfree(P) free(P)
#define cnew(T) (T*)callocate(sizeof(T))
#define cnew0(T) (T*)callocate0(sizeof(T))
typedef void(cdestructor_fn)(void*);
#if defined(__GNUC__)
#define cfetch_and_add(P,X) __sync_fetch_and_add(P, X)
#define cfetch_and_sub(P,X) __sync_fetch_and_sub(P, X)
#define cadd_and_fetch(P,X) __sync_add_and_fetch(P, X)
#define csub_and_fetch(P,X) __sync_sub_and_fetch(P, X)
#define cfetch_and_inc(P) cfetch_and_add(P,1)
#define cfetch_and_dec(P) cfetch_and_sub(P,1)
#define cinc_and_fetch(P) cadd_and_fetch(P,1)
#define cdec_and_fetch(P) csub_and_fetch(P,1)
#elif defined (_MSC_VER)
#include <windows.h>
#define cfetch_and_add(P,X) (InterlockedAddNoFence(P,X)-X)
#define cfetch_and_sub(P,X) (InterlockedAddNoFence(P,-X)+X)
#define cadd_and_fetch(P,X) InterlockedAddNoFence(P,X)
#define csub_and_fetch(P,X) InterlockedAddNoFence(P,-X)
#define cfetch_and_inc(P) (InterlockedIncrementNoFence(P)-1)
#define cfetch_and_dec(P) (InterlockedDecrementNoFence(P)+1)
#define cinc_and_fetch(P) InterlockedIncrementNoFence(P)
#define cdec_and_fetch(P) InterlockedDecrementNoFence(P)
#ifndef __cplusplus
#define inline _inline
#endif
#endif
__inline static void * cmemdup(const void * const ptr, int size) {
void * p;
if (size > 0){
p = callocate(size);
if (p && ptr) {
memcpy(p, ptr, size);
}
}
else{
p = NULL;
}
return p;
}
__inline static void * _cretain(void*p, int*prcntr) {
if (*prcntr != 0){
cinc_and_fetch(prcntr);
}
return p;
}
__inline static void _crelease(void*p, int*prcntr, void * destr) {
if (*prcntr != 0){
if(0 == cdec_and_fetch(prcntr)){
if (destr) ((cdestructor_fn *)destr)(p);
else free(p);
}
}
}
#if defined(__GNUC__)
#define cretain(S) (__typeof__(S)*)_cretain(S, &(S)->_rcntr)
#elif defined (_MSC_VER)
#define cretain(S) _cretain(S, &(S)->_rcntr)
#endif
#define crelease(S,D) _crelease(S, &(S)->_rcntr, D)
#endif
This diff is collapsed.
/*********************************************************************
######################################################################
##
## Created by: Denis Filatov
## Date : 10.11.2005
##
## C command line arguments and simple config file parser
##
## Copyleft (c) 2003 - 2007
## This code is provided under the CeCill-C license agreement.
######################################################################
*********************************************************************/
#ifndef copts_h
#define copts_h
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup COPTS copts - Programm line option processing.
* @{ */
#ifndef DOXYGEN
typedef struct copt_t copt_t;
typedef enum coptflag_t coptflag_t;
typedef enum coptype_t coptype_t;
typedef enum copterr_t copterr_t;
#endif
/** @enum coptype_t
* Option types definitions.
*/
enum coptype_t{
COPT_BOOL , /**< Boolean option. Doesn't require arguments.*/
COPT_BOOLI, /**< Inverted Boolean option. Doesn't require arguments. */
COPT_LONG , /**< Requires for long argument */
COPT_ULONG, /**< Requires for unsigned long argument */
COPT_SHORT, /**< Requires for short (16 bit) argument */
COPT_USHORT, /**< Requires for unsigned short argument */
COPT_CHAR , /**< Requires for char or unsigned char argument */
COPT_STR , /**< Requires for string (const char *) arguments */
COPT_HOST, /**< Requires for string (const char *) arguments. Checks url syntax. */
COPT_PATH, /**< Requires for string (const pchar_t *) arguments. */
COPT_STRLIST, /**< Requires for string list argument (const char *[])
* Every time when this opion will be occuren in argv
* the value will be assigned to given pointer and
* this pointer will be incremented. */
COPT_STRENUM, /**< Requires for one of the string in the array given by vptr)
* Array of strings must be terminated by NULL pointer.
* After option found the vptr pointer will point
* to the element corresponding to the argument */
COPT_CFGFILE, /**< Requires for string (const pchar_t *) arguments.
* Treat it as config file name and load if found.
* If one or more config file options are exists in copt_t list
* this options will be executed before any other options parsing */
COPT_HELP, /**< Does't require argument.
* If this option is occured in command line parsing will be
* terminated imediate and COPT_EHELP will be returned */
COPT_TYPE_MASK = 0x00FF, /**< Option type mask. For internal usage. */
COPT_CALLBACK = 0x4000, /**< Mask. Can be or-ed with any other option.
* That's mean treat vptr as a callback addres to call
* when option is occured */
COPT_CONFIG = 0x8000, /**< Mask. Can be or-ed with any other option.
* That's mean this option can be reached from config file
* and have to be writen to.*/
COPT_END = 0xFFFF, /**< End of options.
* If vptr is not NULL, treat it as callback to call for unknown
* options and non-option values */
};
#define COPT_INT COPT_LONG
#define COPT_UINT COPT_ULONG
#define COPT_IBOOL COPT_BOOLI
/** Main options item.
* Have to be used to define options items.
* Short and long options can be defined.
* Possible options notations:
* - Boolean options:
* - -o
* - --option
* - Other types except of boolean:
* - -o value
* - -o=value
* - --option=value
*/
struct copt_t
{
const char* sopts; /**< Short options. */
const char* lopt; /**< Long option. */
const coptype_t type; /**< Option type ( see @ref coptype_t ). */
void* vptr; /**< Option variable pointer. */
const char* helpstr; /**< Option help string. */
};
/**
* Execute option parser.
* @param argc Command line parameters count (from arguments of main() for example).
* @param argv Array of command line parameters.
* @param flags Configuration flags ( @ref coptflag_t ).
* @param opts Array of possible options. Must be finished by item with COPT_END type.
* @return <ul><li>On success returns the index of the first option argument in the arguments array.<li>On error returns negative index of the invalid option in the arguments array.</ul>
*/
int coptions(int argc, char* argv[], int flags, copt_t* opts);
/** Get enum index from the option variable.
* @param opts @ref copt_t array.
* @param idx Index of the enum option in the array.
* @param ptr The initial value of the @a vptr field of the opion array item.
* @return the integer enum value of the selected item.
*/
#define copts_enum_value(opts,idx,ptr) \
((const char **)((opts)[idx]).vptr) - ((const char **)(ptr))
/**
* Load options config file.
* @param filename File path to load.
* @param section If not NULL then try to find the last occurance of the
* given section or load the file complet.
* @param flags Configuration flags ( see @ref coptflag_t ).
* @param opts The Array of possible option records. Must be finished
* by the item with COPT_END type.
* @return
<ul><li>On success returns 0.<li>On error returns negative line number of the invalid expression.</ul>
*/
int coptions_load(const char* filename, const char * section, int flags, copt_t* const opts);
/**
* Save current options to the file
*/
int coptions_save(const char* filename, const copt_t* const opts);
/**
* Save current options to already opened file
*/
int coptions_fsave(FILE * fd, const copt_t* const opts);
/**
* Generate and print the help page.
* @param fd File descriptor to print the resulting help page.
* @param prgname Application name. Can be taken from argv[0].
* @param opt Options array.
* @param usagestr The string to print before option list.
* @param header Help page header.
* @param footer Help page footer.
*/
void coptions_help_ex(FILE * fd, const char * prgname, int flags, copt_t* opt, const char* usagestr,
const char* header, const char* footer);
/** The lite version of the @ref coptions_help_ex.
* @param fd File descriptor to print the resulting help page.
* @param prgname Application name. Can be taken from argv[0].
* @param opt Options array.
* @param usagestr The string to print before option list.
*/
#define coptions_help(fd,prgname,flags,opt,usagestr) \
coptions_help_ex(fd,prgname,flags,opt,usagestr,NULL,NULL)
/** Wild value definition */
typedef union{
int v_boolean;
signed short v_short;
unsigned short v_ushort;
signed long v_long;
unsigned long v_ulong;
char v_char;
char * v_str;
}copt_value_t;
/** The type of callback function to be called for the option having
@ref COPT_CALLBACK bit set in the @e type field of the @ref copt_t structure.
These functions must return zero if option was successfully processed,
@ref COPT_EHELP to generate option help string or negative value when
some error was occured.
@param opt The current item of the options array.
@param option String option given.
@param value Pointer to the option value.
*/
typedef int copt_callback(const copt_t * opt, const char * option, const copt_value_t * value);
/** Inverted Boolean True. */
#define IBOOL_YES ((void*)-1)
/** @enum coptflag_t
Option flag mask values.
*/
enum coptflag_t
{
COPT_DEFAULT = 0x0000, /**< No special flags given. */
COPT_NOAUTOHELP = 0x0001, /**< Does not provide automatic help messages. */
COPT_NOCONFIG = 0x0002, /**< Does not search for config files. */
COPT_NOREORDER = 0x0004, /**< Does not reorder command line array. */
COPT_NOERR_MSG = 0x0010, /**< Be silent. */
COPT_NOERR_UNKNOWN = 0x0020, /**< Treat unknown options as non-option args.*/
COPT_NOERR_ARG = 0x0040, /**< Does not produce an error if the required
option's argument is omited or have
incompatible type. */
COPT_NOERR = 0x0070, /**< Does not produce any errors. */
COPT_ERR_CONFIG = 0x0080, /**< Does not produce config errors. */
COPT_NOHELP_MSG = 0x0100, /**< Does not print help messages. */
COPT_HELP_NOVALUES = 0x0200, /**< Does not print default values. */
};
/** @{
@ref coptions return codes.
*/
/** Help option (-h or --help) vaw invoked. Need to print help page.*/
#define COPT_EHELP ((int)(0x80000001))
/** Some error was occured.*/
#define COPT_ERROR ((int)(0x80000002))
#define COPT_ERC(rc) (rc < 0 && 0==(rc & 0x8000000))
/**@}*/
/** @} */
/**
* @example test_copts.c
*/
#ifdef __cplusplus
}
#endif
#endif
/*********************************************************************
######################################################################
##
## Created by: Denis Filatov
## Date : 10.11.2005
##
## Copyleft (c) 2003 - 2015
## This code is provided under the CeCill-C license agreement.
######################################################################
*********************************************************************/
#include "cring.h"
#include "cmem.h"
#include <stdlib.h>
void _cring_init( cring_t * const r )
{
r->next = r;
r->prev = r;
}
cring_t * _cring_erase( cring_t * const x )
{
cring_t * n = x->next;
cring_t * p = x->prev;
n->prev = p;
p->next = n;
x->next = x;
x->prev = x;
return n;
}
cring_t * _cring_insert_after( cring_t * const r, cring_t * const i)
{
cring_t * n = r->next;
i->prev = r;
r->next = i;
i->next = n;
n->prev = i;
return n;
}
cring_t * _cring_insert_before( cring_t * const r, cring_t * const i)
{
cring_t * p = r->prev;
i->next = r;
r->prev = i;
i->prev = p;
p->next = i;
return p;
}
cring_t * _cring_insert_ring_after( cring_t * const p, cring_t * const b)
{
cring_t *n, *e;
if(b->next == b){
return _cring_insert_after(p, b);
}
n = p->next;
e = b->prev;
p->next = b;
b->prev = p;
n->prev = e;
e->next = n;
return n;
}
cring_t * _cring_insert_ring_before( cring_t * const n, cring_t * const b)
{
cring_t *p, *e;
if(b->next == b){
return _cring_insert_before(n, b);
}
p = n->prev;
e = b->prev;
p->next = b;
b->prev = p;
n->prev = e;
e->next = n;
return p;
}
cring_t * _cring_erase_ring( cring_t * const f, cring_t * const l)
{
cring_t *p, *n;
if(f == l){
return _cring_erase(f);
}
p = f->prev;
n = l->next;
f->prev = l;
l->next = f;
p->next = n;
n->prev = p;
return n;
}
int cring_is_empty( cring_t * const r )
{
return r->next == r;
}
void cring_cleanup(cring_t * const r, void * const fn_destructor)
{
while(r->next != r){
cring_t * x = r->next;
_cring_erase(x);
if(fn_destructor){
((void(*)(void*))fn_destructor)(x);
}
}
}
cring_t * _cring_insert_sorted(cring_t * const r, cring_t * const n, cring_compare_fn * const fn_compare)
{
cring_t * i = r->next;
for (; i != r; i = i->next){
int x = fn_compare(i, n);
if (x == 0)
return i;
if (x > 0) /* i > n */
break;
}
_cring_insert_before(i, n);
return n;
}
cring_t * _cring_find_sorted(cring_t * const r, cring_t * const n, cring_compare_fn * const fn_compare)
{
cring_t * i = r->next;
for (; i != r; i = i->next){
int x = fn_compare(i, n);
if (x == 0)
return i;
if (x > 0) /* i > n */
break;
}
return NULL;
}
cring_t * cring_zerase( cring_t * * const root, cring_t * const r )
{
if(r->next == r){
*root = NULL;
return r;
}
if(*root == r){
*root = r->next;
}
return _cring_erase(r);
}
cring_t * cring_zinsert_after (cring_t * * const root, cring_t * const i)
{
if(*root == NULL) {
*root = i;
return i;
}
return _cring_insert_ring_after(*root, i);
}
cring_t * cring_zinsert_before(cring_t * * const root, cring_t * const i)
{
if(*root == NULL) {
*root = i;
return i;
}
return _cring_insert_ring_before(*root, i);
}
cring_t * cring_zerase_ring( cring_t * * const root, cring_t * const f, cring_t * const l)
{
cring_t *i, *ret;
if(f->prev == l){
/* remove full ring */
*root = NULL;
return NULL;
}
ret = _cring_erase_ring( f, l);
/* need to check if *root occurs in erased space */
i = f;
do{
if(i == *root){
*root = ret->prev;
break;
}
if(i == l){
break;
}
i=i->next;
}while(1);
return ret;
}
void cring_zcleunup( cring_t * * const root, void * const fn_destructor)
{
cring_t * r = *root;
if(r){
*root = NULL;
do{
cring_t * n = r->next;
_cring_erase(r);
if(fn_destructor){
((void(*)(void*))fn_destructor)(r);
}
if(r == n){
break;
}
r=n;
}while(1);
}
}
static cring_t __xcring_pool = {&__xcring_pool, &__xcring_pool};
xcring_t * xcring_new (void * const data)
{
xcring_t * r;
if(__xcring_pool.next == &__xcring_pool){
int i;
/* preallocate PREALLOC_D items */
r = callocate(sizeof(xcring_t)*XRING_PREALLOC);
if(NULL == r) return NULL;
for(i = 0; i<XRING_PREALLOC-1; i++, r++){
r->next = r;
r->prev = r;
r->data = NULL;
_cring_insert_after( &__xcring_pool, (cring_t *) r);
}
/* use last allocated item */
r->next = r;
r->prev = r;
}else{
r = (xcring_t *)__xcring_pool.next;
_cring_erase( __xcring_pool.next );
}
r->data = data;
return r;
}
void xcring_free(xcring_t * const r, void * const fn_destructor)
{
if(r->data){
if(fn_destructor){
((void(*)(void*))fn_destructor)(r->data);
}
r->data = NULL;
}
_cring_insert_after( &__xcring_pool, (cring_t *) r);
}
void xcring_cleanup(cring_t * const root, void * const fn_destructor)
{
while(!cring_is_empty(root)){
xcring_t * r = (xcring_t *)root->next;
_cring_erase(root->next);
xcring_free(r, fn_destructor);
}
}
xcring_t * xcring_enqueue(cring_t * const root, void * const data)
{
xcring_t * r = xcring_new (data);
_cring_insert_before(root, (cring_t*)r);
return r;
}
void * xcring_dequeue(cring_t * const root)
{
void * data;
xcring_t * r;
if(root->next == root){
return NULL;
}
r = (xcring_t*)root->next;
_cring_erase((cring_t*)r);
data=r->data;
r->data = NULL;
_cring_insert_after( &__xcring_pool, (cring_t *) r);
return data;
}
void * xcring_find (cring_t * const root, void * const pattern,
int(*comparator)(const void * const pattern,
const void * const data))
{
xcring_t * r = (xcring_t *)root->next;
for(;r!=(xcring_t *)root; r=r->next){
if(0==comparator(pattern, r->data)){
return r->data;
}
}
return NULL;
}
/*********************************************************************
######################################################################
##
## Created by: Denis Filatov
## Date : 10.11.2005
##
## Copyleft (c) 2003 - 2015
## This code is provided under the CeCill-C license agreement.
######################################################################
*********************************************************************/
#ifndef cring_h
#define cring_h
/** @defgroup CRING Double-Linked Rings.
* @{
The @ref cring_t structure it is the easiest way to organize rounded
double-linked lists of any data items. Insertion and removing of items
are very lightweight operations. Rings are usefull for any types of
queues, stacks and other types of data storage does not need the index-based
access to the items.
Every ring item have two pointers to the next and previous ones. This
structure can be embedded to the data item structure at the begining or
in any position (see @ref cring_cast).
Here we have 3 data items inserted to the ring, headed by @c items member of
Container structure.
@code
+==============+ +----->+===========+<--------+
I Container I | I Data item I |
I structure I | I cring_t I |
I I | I {next}--I-----+ |
I . . . I | +---I---{prev} I | |
I I | | I . . . I | |
Icring_t items I<-|--+ +===========+ +----->+===========+
I {next}-I--+ | | | I Data item I
I {prev}-I---+ | | | I cring_t I
I I | | | +--I---{prev} I
I . . . I | | +===========+<-----------I---{next} I
I I +---->I Data item I | I . . . I
I I | I cring_t I | +===========+
I I | I {prev}--I-----+
I I +---I---{next} I
I I I . . . I
+==============+ +===========+
@endcode
The next and prev pointer of an empty @ref cring_t item points to itself.
*/
#ifdef _MSC_VER
#define __typeof__ __typeof
#endif
typedef struct cring_t cring_t;
/** Base ring structure. */
struct cring_t
{
cring_t * next; /**< pointer to the next ring element. */
cring_t * prev; /**< pointer to the next ring element. */
};
#ifndef offsetof
/** @def offsetof(TYPE, MEMBER)
Return the offset of given member from the begining of the given
structure type.
@param TYPE Structure type.
@param MEMBER Structure member name.
Example:
@code
struct Base {
int n1;
int n2;
. . .
};
int ofs =
@endcode
In this example offsetof(Base,n2) is equal to 4 (sizeof(int))
*/
#define offsetof(TYPE, MEMBER) (unsigned int) &((TYPE *) 0)->MEMBER
#endif
/** Cast the pointer to the member of structure to the pointer
to the base structure.
* @param TYPE Base structure type.
* @param MEMBER Member of the base structure.
* @param PTR Pointer to this member.
* @return Pointer to the base structure.
*
* Example:
* The base structure looks like:
* @code
* struct Base {
* cring_t ring1;
* cring_t ring2;
* . . .
* };
* @endcode
* We need to organize this type objects to two independent rings.
* @code
* static cring_t r1;
* static cring_t r2;
* @endcode
* We will use @a ring1 member for work with the first ring and @a ring2
* for the second one.
* To take the first item in @c r1 we need just cast @c r1.next to the
* <c>(Base *)</c> type or use the special macro.
* @code
* struct Base * ptr = cring_next_cast(&r1, struct Base);
* @endcode
* But we will make the same operations for the second ring, we will got
* a pointer to the @a ring2 member of Base of the first ring item.
* To cast it to the @a Base type we need for @a cring_cast.
* @code
* struct cring_t * r = cring_next(&r2);
* struct Base * ptr = cring_cast(struct Base, ring2, r);
* @endcode
*/
#define cring_cast(TYPE,MEMBER,PTR) ( (TYPE*) ((char*)(PTR) - offsetof(TYPE,MEMBER)))
/** Return next ring item.
* @param x Pointer could been converted to the @ref cring_t structure.
* @return Next ring item automaticaly converted to the type of x. */
#define cring_next(x) ((__typeof__(x))(((cring_t*)(x))->next))
/** Return previous ring item.
* @param x Pointer could been converted to the @ref cring_t structure.
* @return Previous ring item automaticaly converted to the type of x. */
#define cring_prev(x) ((__typeof__(x))(((cring_t*)(x))->prev))
/** Return next ring item with cast conversion.
* @param x Pointer could been converted to the @ref cring_t structure.
* @param t Type to cast to.
* @return Next ring item converted to the given type. */
#define cring_next_cast(x,t) ((t*)((cring_t*)(x))->next)
/** Return next ring item with cast conversion.
* @param x Pointer could been converted to the @ref cring_t structure.
* @param t Type to cast to.
* @return Previous ring item converted to the given type. */
#define cring_prev_cast(x,t) ((t*)((cring_t*)(x))->prev)
/** Return first ring item with cast conversion
* @param x Root ring item.
* @param t Type to cast to.
* @return The first item of the ring converted to the given type. */
#define cring_first_cast(x,t) cring_next_cast(&x,t)
/** Return last ring item with cast conversion
* @param x Root ring item.
* @param t Type to cast to.
* @return The last item of the ring converted to the given type. */
#define cring_last_cast(x,t) cring_prev_cast(&x,t)
void _cring_init ( cring_t * const r );
#define cring_init(R) _cring_init((cring_t*)(R))
cring_t * _cring_erase ( cring_t * const r );
#define cring_erase(R) _cring_erase((cring_t*)(R))
cring_t * _cring_insert_after(cring_t * const r, cring_t * const i);
#define cring_insert_after(R,I) _cring_insert_after((cring_t*)(R), (cring_t*)(I))
cring_t * _cring_insert_before(cring_t * const r, cring_t * const i);
#define cring_insert_before(R,I) _cring_insert_before((cring_t*)(R), (cring_t*)(I))
#define cring_enqueue(R,I) cring_insert_before(R,I)
cring_t * _cring_insert_ring_after(cring_t * const r, cring_t * const i);
#define cring_insert_ring_after(R,I) _cring_insert_ring_after((cring_t*)(R), (cring_t*)(I))
cring_t * _cring_insert_ring_before(cring_t * const r, cring_t * const i);
#define cring_insert_ring_before(R,I) _cring_insert_ring_before((cring_t*)(R), (cring_t*)(I))
cring_t * _cring_erase_ring(cring_t * const from, cring_t * const to);
#define cring_erase_ring(F,T) _cring_erase_ring((cring_t*)(F), (cring_t*)(T))
int cring_is_empty(cring_t * const r);
void cring_cleanup(cring_t * const r, void * const fn_destructor);
typedef int cring_compare_fn(void * const p1, void * const p2);
cring_t * _cring_insert_sorted(cring_t * const r, cring_t * const i, cring_compare_fn * const fn_compare);
cring_t * _cring_find_sorted(cring_t * const r, cring_t * const n, cring_compare_fn * const fn_compare);
#define cring_insert_sorted(R,I,C) _cring_insert_sorted((cring_t*)(R), (cring_t*)(I), (cring_compare_fn *)(C))
#define cring_find_sorted(R,I,C) _cring_find_sorted((cring_t*)(R), (cring_t*)(I), (cring_compare_fn *)(C))
cring_t * cring_zerase( cring_t * * const root, cring_t * const r );
cring_t * cring_zerase_ring( cring_t * * const root, cring_t * const from, cring_t * const to);
cring_t * cring_zinsert_after (cring_t * * const root, cring_t * const i);
cring_t * cring_zinsert_before(cring_t * * const root, cring_t * const i);
void cring_zcleunup( cring_t * * const root, void * const fn_destructor);
#define XRING_PREALLOC 16
typedef struct xcring_t
{
struct xcring_t * next;
struct xcring_t * prev;
void * data;
} xcring_t;
xcring_t * xcring_new (void * const data);
void xcring_free(xcring_t * const r, void * const fn_destructor);
void xcring_cleanup(cring_t * const root, void * const fn_destructor);
#define xcring_data(TYPE,R) ( (TYPE*) ((xcring_t*)R)->data )
xcring_t * xcring_enqueue(cring_t * const root, void * const data);
void * xcring_dequeue(cring_t * const root);
void * xcring_find (cring_t * const root, void * const pattern,
int(*comparator)(const void * const pattern,
const void * const data));
/** @} */
#endif
/*********************************************************************
######################################################################
##
## Created by: Denis Filatov
##
## Copyleft (c) 2003 - 2015
## This code is provided under the CeCill-C license agreement.
######################################################################
*********************************************************************/
#include "cserialize.h"
#include "cstr.h"
#include "e4c_lite.h"
#include <errno.h>
#include <string.h>
#ifdef __GNUC__
#define cint_cpy(D,N,S) __builtin_memcpy((char*)(D),N,S)
#else
#define cint_cpy(D,N,S) memcpy((char*)(D),N,S)
static const uint64_t __one64 = 1;
#if !defined (_MSC_VER)
uint64_t cint64_swap(uint64_t);
uint32_t cint32_swap(uint32_t);
uint16_t cint16_swap(uint16_t);
#endif
#endif
#define C_ERROR(E) \
if (perror) *perror = E; \
throw(RuntimeException, E, NULL)
int _cint64_write(const uint64_t value, char** const ptr, const char* const end, int * const perror)
{
register unsigned char* p = (unsigned char*)*ptr;
if (p + 8 > (unsigned char*)end){
C_ERROR(ENOSPC);
return -1;
}
if (0 == (((intptr_t)p) & 0x7)){
*((uint64_t*)p) = cint64_hton(value);
p+=8;
}else{
int i;
for(i=7; i>=0; i--){
*p++ = (value>>(8*i))&0xFF;
}
}
*ptr = (char*)p;
if (perror) *perror = 0;
return 0;
}
int _cint32_write(const uint32_t value, char** const ptr, const char* const end, int * const perror)
{
register unsigned char* p = (unsigned char*)*ptr;
if(p + 4 > (unsigned char*)end){
C_ERROR(ENOSPC);
return -1;
}
if (0 == (((intptr_t)p) & 0x3)){
*((uint32_t*)p) = cint32_hton(value);
p+=4;
}else{
int i;
for(i=3; i>=0; i--){
*p++ = (value>>(8*i))&0xFF;
}
}
*ptr = (char*)p;
if (perror) *perror = 0;
return 0;
}
int _cint16_write(const uint16_t value, char** const ptr, const char* const end, int * const perror)
{
register unsigned char* p = (unsigned char*)*ptr;
if (p + 2 > (unsigned char*)end){
C_ERROR(ENOSPC);
return -1;
}
*p++ = (value >> 8) & 0xFF;
*p++ = value&0xFF;
*ptr = (char*)p;
if (perror) *perror = 0;
return 0;
}
int _cint8_write(const uint8_t value, char** const ptr, const char* const end, int * const perror)
{
if (*ptr >= end) {
C_ERROR(ENOSPC);
return -1;
}
if (perror) *perror = 0;
*((uint8_t*)*ptr) = value;
(*ptr) ++;
return 0;
}
uint64_t cint64_read(const char** const ptr, const char* const end, int * const perror)
{
uint64_t value;
register const uint8_t * p = (const uint8_t *)*ptr;
if (p + 8 > (const uint8_t *)end) {
C_ERROR(EFAULT);
return (unsigned)-1;
}
if (0 == (((intptr_t)p) & 0x7)){
value = *(uint64_t*)p;
value = cint64_hton(value);
*ptr = (char*)(p+8);
}else{
int i;
value=0;
for(i=0; i<8; i++){
value = (value<<8) | *(p++);
}
*ptr = (char*)p;
}
if (perror) *perror = 0;
return value;
}
uint32_t cint32_read(const char** const ptr, const char* const end, int * const perror)
{
uint32_t value;
register const uint8_t * p = (const uint8_t*)*ptr;
if(p + 4 > (const uint8_t *)end) {
C_ERROR(EFAULT);
return (unsigned)-1;
}
if (perror) *perror = 0;
value = ((uint32_t)p[0]) << 24 | ((uint32_t)p[1]) << 16 | ((uint32_t)p[2]) << 8 | p[3];
*ptr = (char*)(p+4);
return value;
}
uint16_t cint16_read(const char** const ptr, const char* const end, int * const perror)
{
uint32_t value;
register const uint8_t * p = (const uint8_t*)*ptr;
if (p + 2 > (const uint8_t *)end) {
C_ERROR(EFAULT);
return (uint16_t)-1;
}
if (perror) *perror = 0;
value = ((uint16_t)p[0]) << 8 | p[1];
*ptr = (const char*)(p+2);
return value;
}
uint8_t cint8_read(const char** const ptr, const char* const end, int * const perror)
{
if (*ptr >= end) {
C_ERROR(EFAULT);
return (uint8_t)-1;
}
if (perror) *perror = 0;
return *(const uint8_t*)((*ptr)++);
}
int cintx_bytecount(uint64_t value)
{
int num_bytes = 0;
#ifdef __GNUC__
if(value){
num_bytes = (64 + 6 - __builtin_clzll(value))/7;
}else{
num_bytes = 1;
}
#else
uint64_t overflow = 0;
while(value >= overflow){
num_bytes++;
overflow = __one64 << (7*num_bytes);
}
#endif
return num_bytes;
}
int _cintx_write (const uint64_t value, char ** const ptr, const char * const end, int * const perror)
{
int num_bytes = 0;
uint8_t c;
uint8_t *out = (uint8_t*)(*ptr);
num_bytes = cintx_bytecount(value);
if(num_bytes > 8 || out+num_bytes > ((const uint8_t*)end)){
C_ERROR(ENOSPC);
return (unsigned)-1;
}
num_bytes--;
c = ~((1<<(8-num_bytes))-1);
c |= (value >> (num_bytes*8)) & 0xFF;
*out++ = c;
while(num_bytes){
num_bytes--;
c = (value >> (num_bytes*8)) & 0xFF;
*out++ = c;
}
*ptr = (char*)out;
if (perror) *perror = 0;
return 0;
}
static int countof1(int c)
{
int r = 0;
while(c & 0x80){
#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 407) && !defined(__INTEL_COMPILER)
return 1 + __builtin_clrsb(c<<24);
#else
r++;
c<<=1;
#endif
}
return r;
}
uint64_t cintx_read(const char** const ptr, const char* const end, int * const perror)
{
uint8_t c;
const uint8_t* in;
int i, lead_ones;
in = (const uint8_t*)*ptr;
if(in <= (const uint8_t*)end){
c = *in;
lead_ones = countof1(c);
if(in + 1 + lead_ones <= (const uint8_t*)end) {
uint64_t value;
value = c & ((1<<(7-lead_ones))-1);
for(i=1; i<=lead_ones; i++){
value = (value<<8) | in[i];
}
*ptr = (const char*)(in + 1 + lead_ones);
if (perror) *perror = 0;
return value;
}
}
C_ERROR(EFAULT);
return (unsigned)-1;
}
uint32_t cxsize_read(const char ** const ptr, const char * const end, int * const perror)
{
uint32_t len = (uint32_t)cintx_read(ptr, end, perror);
if (perror == 0){
if (*ptr + len > end){
C_ERROR(EFAULT);
return (unsigned)-1;
}
}
if (perror) *perror = 0;
return len;
}
int cbuf_write(const void * const p, size_t length, char ** const ptr, const char * const end, int * const perror)
{
if((*ptr) + length > end) {
C_ERROR(ENOSPC);
return (unsigned)-1;
}
cint_cpy(*ptr, p, length);
*ptr = (*ptr) + length;
if (perror) *perror = 0;
return 0;
}
int cbuf_read(void * const p, size_t length, const char ** const ptr, const char * const end, int * const perror)
{
if((*ptr) + length > end) {
C_ERROR(EFAULT);
return -1;
}
if (p){
cint_cpy(p, *ptr, length);
}
*ptr = (*ptr) + length;
if (perror) *perror = 0;
return 0;
}
int cstr_write(const char * const p, char ** const ptr, const char * const end, int * const perror)
{
int ret;
size_t len = cstrlen(p);
// write size
ret = cintx_write(len, ptr, end, perror);
if (ret == 0 && len > 0 ) {
ret = cbuf_write(p, len, ptr, end, perror);
}
return ret;
}
int cstrn_write(const char * const p, size_t length, char ** const ptr, const char * const end, int * const perror)
{
int ret;
size_t len = cstrnlen(p, length);
// write size
ret = cintx_write(len, ptr, end, perror);
if (ret == 0 && len > 0) {
ret = cbuf_write(p, len, ptr, end, perror);
}
return ret;
}
int cstr_read(char * const p, const char ** const ptr, const char * const end, int * const perror)
{
// read size
int len = (int)cintx_read(ptr, end, perror);
if (*perror == 0){
return cbuf_read(p, len, ptr, end, perror);
}
return -1;
}
int cstrn_read(char * const p, size_t length, const char ** const ptr, const char * const end, int * const perror)
{
// read size
size_t len = (size_t)cintx_read(ptr, end, perror);
if (len <= length){
// read buf
return cbuf_read(p, len, ptr, end, perror);
}
C_ERROR(EFAULT);
return -1;
}
int cbookmark_store(cbookmark * bm, char ** const ptr, const char * const end, int * const perror)
{
char * p = *ptr;
if (bm->idx >= sizeof(bm->ptrs) / sizeof(bm->ptrs[0])){
C_ERROR(E2BIG);
return -1;
}
if (p >= end){
C_ERROR(ENOSPC);
return -1;
}
bm->ptrs[bm->idx] = p;
bm->idx++;
*ptr = p + 1;
if (perror) *perror = 0;
return 0;
}
int cbookmark_apply(cbookmark * bm, char ** const ptr, const char * const end, int * const perror)
{
size_t size;
int bcount;
char *p, * psize;
p = *ptr;
if (bm->idx == 0){
C_ERROR(E2BIG);
return -1;
}
psize = bm->ptrs[--bm->idx];
size = p - psize - 1;
bcount = cintx_bytecount(size);
if (bcount == 1){
*(unsigned char*)psize = (unsigned char)size;
size = 0; // return value;
}
else{
if (p + bcount - 1 > end){
C_ERROR(ENOSPC);
return (unsigned)-1;
}
memmove(psize + bcount, psize + 1, p - psize - 1);
*ptr = p + bcount - 1;
size = cintx_write(size, &psize, psize + bcount, perror);
}
if (perror) *perror = 0;
return (int)size; // size is overridden to be 0 or -1
}
/*********************************************************************
######################################################################
##
## Created by: Denis Filatov
##
## Copyleft (c) 2003 - 2015
## This code is provided under the CeCill-C license agreement.
######################################################################
*********************************************************************/
#ifndef cint_h
#define cint_h
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "e4c_lite.h"
#if defined(__GNUC__)
# define cint64_swap(X) __builtin_bswap64(X)
# define cint32_swap(X) __builtin_bswap32(X)
# define cint16_swap(X) __builtin_bswap16(X)
#elif defined (_MSC_VER)
# define cint64_swap(X) _byteswap_uint64(X)
# define cint32_swap(X) _byteswap_ulong (X)
# define cint16_swap(X) _byteswap_ushort(X)
#define __ORDER_LITTLE_ENDIAN__ 1
#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
#else
uint64_t cint64_swap(const uint64_t);
uint32_t cint32_swap(const uint32_t);
uint16_t cint16_swap(const uint16_t);
#endif
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define cint64_hton(X) cint64_swap(X)
# define cint32_hton(X) cint32_swap(X)
# define cint16_hton(X) cint16_swap(X)
# define cint64_lsb(X) ((uint8_t)(((uint64_t)(X))>>56))
# define cint32_lsb(X) ((uint8_t)(((uint32_t)(X))>24))
# define cint24_lsb(X) ((uint8_t)(((uint32_t)(X))>16))
# define cint64_lsb3(X) ((uint32_t)(((uint64_t)(X))>>40))
# define cint32_lsb3(X) ((uint32_t)(((uint64_t)(X))>>8))
#else
# define cint64_hton(X) (X)
# define cint32_hton(X) (X)
# define cint16_hton(X) (X)
# define cint64_lsb(X) ((uint8_t)((X)&0xFF))
# define cint32_lsb(X) ((uint8_t)((X)&0xFF))
# define cint24_lsb(X) ((uint8_t)((X)&0xFF))
# define cint64_lsb3(X) ((uint32_t)((X)&0xFFFFFF))
# define cint32_lsb3(X) ((uint32_t)((X)&0xFFFFFF))
#endif /* __BYTE_ORDER__ */
/* serialisation */
int _cint64_write(const uint64_t n, char ** const ptr, const char * const end, int * const error);
int _cint32_write(const uint32_t n, char ** const ptr, const char * const end, int * const error);
int _cint16_write(const uint16_t n, char ** const ptr, const char * const end, int * const error);
int _cint8_write (const uint8_t n, char ** const ptr, const char * const end, int * const error);
int _cintx_write (const uint64_t n, char ** const ptr, const char * const end, int * const error);
#define cint64_write(N,P,S,E) _cint64_write((uint64_t)(N), P, S, E)
#define cint32_write(N,P,S,E) _cint32_write((uint32_t)(N), P, S, E)
#define cint16_write(N,P,S,E) _cint16_write((uint16_t)(N), P, S, E)
#define cint8_write(N,P,S,E) _cint8_write ((uint8_t)(N), P, S, E)
#define cintx_write(N,P,S,E) _cintx_write ((uint32_t)(N), P, S, E)
uint64_t cint64_read (const char ** const ptr, const char * const end, int * const error);
uint32_t cint32_read (const char ** const ptr, const char * const end, int * const error);
uint16_t cint16_read (const char ** const ptr, const char * const end, int * const error);
uint8_t cint8_read (const char ** const ptr, const char * const end, int * const error);
uint64_t cintx_read (const char ** const ptr, const char * const end, int * const error);
uint32_t cxsize_read(const char ** const ptr, const char * const end, int * const error);
int cintx_bytecount(uint64_t);
int cbuf_write(const void * const p, size_t length, char ** const ptr, const char * const end, int * const error);
int cbuf_read(void * const p, size_t length, const char ** const ptr, const char * const end, int * const error);
typedef struct {
int idx;
void * ptrs[6];
}cbookmark;
int cbookmark_store(cbookmark * bm, char ** const ptr, const char * const end, int * const error);
int cbookmark_apply(cbookmark * bm, char ** const ptr, const char * const end, int * const error);
E4C_DECLARE_EXCEPTION(cexc_readbuf);
E4C_DECLARE_EXCEPTION(RuntimeException);
#ifdef __cplusplus
}
#endif
#endif
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="cdir_win.c" />
<ClCompile Include="clog.c" />
<ClCompile Include="copts.c" />
<ClCompile Include="cring.c" />
<ClCompile Include="cserialize.c" />
<ClCompile Include="cstr.c" />
<ClCompile Include="e4c_lite.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="cdir.h" />
<ClInclude Include="clog.h" />
<ClInclude Include="cmem.h" />
<ClInclude Include="copts.h" />
<ClInclude Include="cring.h" />
<ClInclude Include="cserialize.h" />
<ClInclude Include="cstr.h" />
<ClInclude Include="e4c_lite.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{D5918B85-FA45-4F75-9B50-C2D3E34ABA17}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>cshared</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(ProjectDir)..\build\msvc\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)..\build\msvc\$(Platform)\$(Configuration)\$(ProjectName)</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(ProjectDir)..\build\msvc\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)..\build\msvc\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(ProjectDir)..\build\msvc\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)..\build\msvc\$(Platform)\$(Configuration)\$(ProjectName)</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(ProjectDir)..\build\msvc\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)..\build\msvc\$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
\ No newline at end of file
/*********************************************************************
######################################################################
##
## Created by: Denis Filatov
##
## Copyleft (c) 2003 - 2015
## This code is provided under the CeCill-C license agreement.
######################################################################
*********************************************************************/
#define _CRT_SECURE_NO_WARNINGS
#include "cstr.h"
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <ctype.h>
size_t cstrlen(const char * str)
{
return str ? strlen(str) : 0;
}
size_t cstrnlen(const char * str, size_t maxsize)
{
size_t len = str ? strlen(str) : 0;
return len > maxsize ? maxsize : len;
}
char* cstrend(const char * str)
{
return (char*)(str ? str + strlen(str) : NULL);
}
int cstrequal(const char * s1, const char * s2)
{
return (s1 == s2) || (s1 && s2 && 0 == strcmp(s1, s2));
}
char* cstrisprefix(const char * str, const char * prefix)
{
size_t len;
if (str == prefix){
return (char*)(str ? str + strlen(str) : NULL);
}
if (str == NULL || prefix == NULL || 0 == *prefix){
return (char*)str;
}
len = strlen(prefix);
if (0 == memcmp(str, prefix, len)){
return ((char*)str) + len;
}
return NULL;
}
char * cstrcpy(char * dst, const char * src)
{
if(!dst) return (char*)0;
size_t len = 0;
if(src){
len = strlen(src);
if(len){
memcpy(dst, src, len);
}
}
dst[len]=0;
return dst + len;
}
char * cstrchr(const char * str, int c)
{
char * ret = (char*)0;
if (str) {
if (c == 0) ret = cstrend(str);
else{
ret = strchr(str, c);
if (!ret) ret = cstrend(str);
}
}
return ret;
}
char * cstrrchr(const char * str, int c)
{
char * ret = (char*)0;
if (str) {
if (c == 0) ret = cstrend(str);
else{
ret = strrchr(str, c);
if (!ret) ret = cstrend(str);
}
}
return ret;
}
/* copy up to maxsize characters from src to dst and return pointer to the next byte after the end */
char * cstrncpy(char * dst, size_t maxsize, const char * src)
{
if (!dst) return (char*)0;
size_t ms = maxsize;
size_t len = 0;
if (src && ms > 0){
len = strlen(src);
if (len > ms){
len = ms;
}
if (len){
memcpy(dst, src, len);
}
}
dst[len] = 0;
return dst + len;
}
char * cmemcpy(char * dst, const char * src, size_t length)
{
if (!dst) return (char*)0;
if (length){
if (src){
memcpy(dst, src, length);
}
else{
memset(dst, 0, length);
}
}
dst[length] = 0;
return dst + length;
}
/* copy up to maxsize characters from src to dst and return pointer to the next byte after the end */
char * cvstrncpy(char * dst, size_t maxsize, const char * ptr, ...)
{
va_list ap;
char * p = dst;
const char * r = ptr;
size_t ms = maxsize;
if(ms > 0){
va_start(ap, ptr);
while(r){
size_t len = strlen(r);
if(len > ms) len = ms;
memcpy(p, r, len);
p += len;
ms -= len;
r = va_arg(ap, const char*);
}
va_end(ap);
*p = 0;
}
return p;
}
char * cstralloc(size_t size)
{
return (char*)malloc((size+0xF)&(~0xF));
}
char * cstrdup(const char * str)
{
char * ret = NULL;
if(str){
size_t len = strlen(str);
if(len){
ret = cstralloc(len);
memcpy(ret, str, len+1);
}
}
return ret;
}
char * cstrndup(const char * str, size_t max_size)
{
char * ret = NULL;
size_t ms = max_size;
if(str){
size_t len = strlen(str);
if(len>ms) len=ms;
if(len){
ret = cstralloc(len);
memcpy(ret, str, len);
ret[len] = 0;
}
}
return ret;
}
char * cvstrdup(const char * ptr, ...)
{
va_list ap;
size_t len = 0;
char *dst, *p;
const char * r;
if(!ptr) return (char*)ptr;
// calculate size
r = ptr;
va_start(ap, ptr);
while(r){
len += strlen(r);
r = va_arg(ap, const char*);
}
va_end(ap);
p = dst = cstralloc(len+1);
if(dst){
r = ptr;
va_start(ap, ptr);
while(r){
len = strlen(r);
memcpy(p, r, len);
p += len;
r = va_arg(ap, const char*);
}
va_end(ap);
*p = 0;
}
return dst;
}
char * cstrnload(char * dst, size_t max_size, const pchar_t * path)
{
FILE * f = pchar_fopen(path, _PCH("rb"));
size_t len, rl;
size_t ms = max_size;
if (!f) return NULL;
fseek(f, 0, SEEK_END);
len = ftell(f);
fseek(f, 0, SEEK_SET);
if (len > ms) len = ms;
rl = fread(dst, 1, len, f);
fclose(f);
if ((int)rl < 0){
return NULL;
}
if (len < ms)dst[len] = 0;
return dst + len;
}
char * cstraload(char ** p, const pchar_t * path)
{
char * ret = NULL;
FILE * f = pchar_fopen(path, _PCH("rb"));
size_t len;
if (f){
fseek(f, 0, SEEK_END);
len = ftell(f);
fseek(f, 0, SEEK_SET);
if (len > 0){
ret = malloc(len);
if (ret){
size_t ms = fread(ret, 1, len, f);
if (ms < len){
free(ret);
*p = ret = NULL;
}
else{
*p = ret;
ret += len;
}
}
}
fclose(f);
}
return ret;
}
const pchar_t * cstrlastpathelement(const pchar_t * str)
{
const pchar_t * p = pchar_rchr(str, '/');
#ifdef WIN32
const pchar_t * p2 = pchar_rchr(str, '\\');
if(p<p2)p=p2;
#endif
if(p == NULL) p = str;
else p++;
return p;
}
pchar_t * cstrpathextension(const pchar_t * str)
{
const pchar_t * p;
if (str){
p = pchar_rchr(str, '.');
if (!p) p = str + pchar_len(str);
}
else{
p = str;
}
return (pchar_t*)p;
}
char * cstr_hex2bin(char * bin, size_t blen, const char * hex, size_t hlen)
{
// check
const char * h = hex;
const char * e = hex+hlen;
char * b = bin;
int n = 0;
while (h<e){
char ch = *h++;
if (isspace((int)(ch))) continue;
if (ch >= '0' && ch <= '9') continue;
if (ch >= 'A' && ch <= 'F') continue;
if (ch >= 'a' && ch <= 'f') continue;
return NULL;
}
h = hex;
while (h < e){
char ch = *h++;
if (ch >= '0' && ch <= '9') ch -= '0';
else if (ch >= 'A' && ch <= 'F') ch -= 'A' - 0x0A;
else if (ch >= 'a' && ch <= 'f') ch -= 'a' - 0x0A;
else continue;
if (!n){
*b = ch;
}
else{
char ch1 = *b;
*b++ = (ch1 << 4) | ch;
}
n = !n;
}
if (n){
char ch1 = *b;
*b++ = (ch1 << 4);
n = 0;
}
return b;
}
static const char* _hexDigits = "0123456789ABCDEF";
char * cstr_bin2hex(char * hex, size_t hlen, const char * bin, size_t blen)
{
const unsigned char *b, *e;
char * s;
// sanity check
if(hlen >=0 && hlen < blen * 2) return NULL;
b = (const unsigned char *)bin;
e = b + blen - 1;
s = hex + blen * 2;
if(s < hex + hlen) *s = 0;
for (; b <= e; e--){
*(--s) = _hexDigits[(*e) & 0xF];
*(--s) = _hexDigits[(*e) >> 4];
}
return hex + blen * 2;
}
void *cmemmem(const void *haystack, size_t n, const void *needle, size_t m)
{
const unsigned char *y = (const unsigned char *)haystack;
const unsigned char *x = (const unsigned char *)needle;
size_t j, k, l;
if (m > n || !m || !n)
return NULL;
if (1 != m) {
if (x[0] == x[1]) {
k = 2;
l = 1;
} else {
k = 1;
l = 2;
}
j = 0;
while (j <= n - m) {
if (x[1] != y[j + 1]) {
j += k;
} else {
if (!memcmp(x + 2, y + j + 2, m - 2)
&& x[0] == y[j])
return (void *)&y[j];
j += l;
}
}
} else
do {
if (*y == *x)
return (void *)y;
y++;
} while (--n);
return NULL;
}
char * cstrnstr(const char *str, size_t size, const char* s)
{
if(!str || !s || *s == 0) return (char*)str;
return cmemmem(str, size, s, strlen(s));
}
int cstr_write(const char * const p, char ** const ptr, const char * const end, int * const error);
int cstr_read(char * const p, const char ** const ptr, const char * const end, int * const error);
int cstrn_write(const char * const p, size_t length, char ** const ptr, const char * const end, int * const error);
int cstrn_read(char * const p, size_t length, const char ** const ptr, const char * const end, int * const error);