编译通过,原有功能正常。

This commit is contained in:
zhengchao
2017-07-04 20:13:36 +08:00
parent e739b2d961
commit f3999170db
9 changed files with 661 additions and 511 deletions

View File

@@ -1,5 +1,5 @@
#ifndef H_MAAT_RULE_H_INCLUDE
#define H_MAAT_RULE_H_INCLUDE
#ifndef H_MAAT_COMMAND_H_INCLUDE
#define H_MAAT_COMMAND_H_INCLUDE
#ifndef __cplusplus
#error("This file should be compiled with C++ compiler")
#endif
@@ -59,10 +59,10 @@ struct Maat_rgn_str_t
struct Maat_rgn_addr_t
{
enum MAAT_ADDR_TYPE addr_type;
char* src_ip;
char* mask_src_ip;
char* dst_ip;
char* mask_dst_ip;
const char* src_ip;
const char* mask_src_ip;
const char* dst_ip;
const char* mask_dst_ip;
unsigned short src_port;
unsigned short mask_src_port;
unsigned short dst_port;
@@ -78,7 +78,7 @@ struct Maat_rgn_intv_t
struct Maat_rgn_digest_t
{
unsigned long long orgin_len;
char* digest_string;
const char* digest_string;
short confidence_degree;
};
struct Maat_rgn_sim_t
@@ -88,7 +88,7 @@ struct Maat_rgn_sim_t
};
struct Maat_region_t
{
char* table_name;
const char* table_name;
int region_id; //Any, maat will assigned one.
enum MAAT_REGION_TYPE region_type;
union
@@ -113,9 +113,8 @@ struct Maat_command_t
int group_num; // for MAAT_OP_DEL, Any.
struct Maat_group_t* groups;// for MAAT_OP_DEL, SET to NULL.
};
struct Maat_command_t* Maat_create_comand(const struct Maat_rule_t* rule, const char*table_name, int group_num);
int Maat_set_command(struct Maat_command_t* cmd,int which_group,const struct Maat_region_t* region);
struct Maat_command_t* Maat_create_comand(const struct Maat_rule_t* rule, int group_num);
void Maat_cmd_add_region(struct Maat_command_t* cmd,int which_group,const struct Maat_region_t* region);
void Maat_free_command(struct Maat_command_t* cmd);
int Maat_format_command(struct Maat_command_t* cmd, char* buffer, int size);

View File

@@ -185,7 +185,7 @@ int region_compile(_Maat_feather_t*feather,struct _INNER_scan_status_t *_mid,int
int exprid2region_id(struct _Maat_group_inner_t* group_rule,int expr_id,int* district_id)
{
int i=0,j=0,region_id=-1;
int i=0,region_id=-1;
struct _Maat_region_inner_t* region_rule=NULL;
assert(group_rule->group_id>=0);
pthread_mutex_lock(&(group_rule->mutex));
@@ -442,11 +442,11 @@ Maat_feather_t Maat_feather(int max_thread_num,const char* table_info_path,void*
if(feather->p_table_info[i]->table_type==TABLE_TYPE_GROUP)
{
feather->GROUP_MODE_ON=1;
memcpy(feather->group_tn,feather->p_table_info[i].table_name[0],sizeof(feather->group_tn));
strncpy(feather->group_tn,feather->p_table_info[i]->table_name[0],sizeof(feather->group_tn));
}
if(feather->p_table_info[i]->table_type==TABLE_TYPE_COMPILE)
{
memcpy(feather->compile_tn,feather->p_table_info[i].table_name[0],sizeof(feather->compile_tn));
strncpy(feather->compile_tn,feather->p_table_info[i]->table_name[0],sizeof(feather->compile_tn));
}
for(j=0;j<feather->p_table_info[i]->conj_cnt;j++)
{
@@ -526,8 +526,9 @@ int Maat_set_feather_opt(Maat_feather_t feather,enum MAAT_INIT_OPT type,const vo
memcpy(_feather->inc_dir,(const char*)value,size);
break;
case MAAT_OPT_JSON_FILE_PATH:
ret=json2iris((const char*)value, _feather->full_dir
ret=json2iris((const char*)value
,_feather->compile_tn,_feather->group_tn
,_feather->full_dir
,sizeof(_feather->full_dir),_feather->logger);
if(ret<0)
{
@@ -568,21 +569,21 @@ int Maat_set_feather_opt(Maat_feather_t feather,enum MAAT_INIT_OPT type,const vo
(const char*)value);
break;
case MAAT_OPT_DECRYPT_KEY:
if(size>sizeof(_feather->decrypt_key))
if((size_t)size>sizeof(_feather->decrypt_key))
{
return -1;
}
memcpy(_feather->decrypt_key,value,size);
break;
case MAAT_OPT_REDIS_IP:
if(size>sizeof(_feather->redis_ip))
if((size_t)size>sizeof(_feather->redis_ip))
{
return -1;
}
memcpy(_feather->redis_ip,value,size);
break;
case MAAT_OPT_REDIS_PORT:
if(size!=sizeof(unsigned short))
if((size_t)size!=sizeof(unsigned short))
{
return -1;
}

File diff suppressed because it is too large Load Diff

View File

@@ -17,7 +17,6 @@
#include "Maat_rule.h"
#include "Maat_rule_internal.h"
#include "Maat_redis.h"
#include "json2iris.h"
#include "dynamic_array.h"
#include "aligment_int64.h"
@@ -71,7 +70,7 @@ char* _maat_strdup(const char* s)
return NULL;
}
d=(char*)malloc(strlen(s)+1);
memcpy(d,s,strlen(s)+1));
memcpy(d,s,strlen(s)+1);
return d;
}
int is_valid_expr_type(enum MAAT_EXPR_TYPE expr_type)
@@ -475,17 +474,77 @@ void destroy_table_info(struct _Maat_table_info_t*p)
aligment_int64_array_free(p->input_bytes);
aligment_int64_array_free(p->stream_num);
aligment_int64_array_free(p->hit_cnt);
if(p->cb_info!=NULL)
{
dynamic_array_destroy(p->cb_info->cache_lines, free);
p->cb_info->cache_lines=NULL;
free(p->cb_info);
p->cb_info=NULL;
}
free(p);
return;
}
int read_expr_table_info(const char* line,int line_num,struct _Maat_table_info_t* p,MESA_htable_handle string2int_map)
{
int j=0,ret[4]={0};
char table_type[16],src_charset[256],dst_charset[256],merge[4],quick_str_scan[32]={0};
char *token=NULL,*sub_token=NULL,*saveptr;
sscanf(line,"%hu\t%s\t%s\t%s\t%s\t%s\t%d\t%s",&(p->table_id)
,p->table_name[0]
,table_type
,src_charset
,dst_charset
,merge
,&(p->cross_cache_size)
,quick_str_scan);
memset(ret,0,sizeof(ret));
ret[0]=map_str2int(string2int_map,strlwr(table_type),(int*)&(p->table_type));
ret[1]=map_str2int(string2int_map,strlwr(src_charset),(int*)&(p->src_charset));
ret[2]=map_str2int(string2int_map,strlwr(merge),&(p->do_charset_merge));
if(strlen(quick_str_scan)>0)
{
ret[3]=map_str2int(string2int_map,strlwr(quick_str_scan),&(p->quick_expr_switch));
}
memset(quick_str_scan,0,sizeof(quick_str_scan));
for(j=0;j<4;j++)
{
if(ret[j]<0)
{
return -1;
}
}
j=0;
for (token = dst_charset; ; token= NULL)
{
sub_token= strtok_r(token,"/", &saveptr);
if (sub_token == NULL)
break;
ret[3]=map_str2int(string2int_map,strlwr(sub_token),(int*)&(p->dst_charset[j]));
if(ret[3]>0)
{
if(p->dst_charset[j]==p->src_charset)
{
p->src_charset_in_dst=TRUE;
}
j++;
}
else
{
return -1;
}
}
return 0;
}
int read_table_info(struct _Maat_table_info_t** p_table_info,int num,const char* table_info_path,int max_thread_num,void* logger)
{
FILE*fp=NULL;
char line[MAX_TABLE_LINE_SIZE];
int i=0,j=0,ret[4]={0},table_cnt=0;
char table_type[16],src_charset[256],dst_charset[256],merge[4],quick_str_scan[32]={0};
int i=0,ret=0,table_cnt=0;
char table_type_str[16],not_care[256];
MESA_htable_handle string2int_map=map_create();
char *token=NULL,*sub_token=NULL,*saveptr;
struct _Maat_table_info_t*p=NULL;
struct _Maat_table_info_t*conj_table=NULL;
@@ -511,14 +570,6 @@ int read_table_info(struct _Maat_table_info_t** p_table_info,int num,const char*
}
}
/*
map_register(string2int_map,"gbk", CHARSET_GBK);
map_register(string2int_map,"big5", CHARSET_BIG5);
map_register(string2int_map,"unicode", CHARSET_UNICODE);
map_register(string2int_map,"utf8", CHARSET_UTF8);
map_register(string2int_map,"unicode_hex", CHARSET_UNICODE_ASCII_ESC);
map_register(string2int_map,"unicode_hex", CHARSET_UNICODE_ASCII_ESC);
*/
map_register(string2int_map,"yes", 1);
map_register(string2int_map,"no", 0);
@@ -540,57 +591,43 @@ int read_table_info(struct _Maat_table_info_t** p_table_info,int num,const char*
}
p=create_table_info(max_thread_num);
sscanf(line,"%hu\t%s\t%s\t%s\t%s\t%s\t%d\t%s",&(p->table_id)
sscanf(line,"%hu\t%s\t%s\t%s",&(p->table_id)
,p->table_name[0]
,table_type
,src_charset
,dst_charset
,merge
,&(p->cross_cache_size)
,quick_str_scan);
ret[0]=map_str2int(string2int_map,strlwr(table_type),(int*)&(p->table_type));
ret[1]=map_str2int(string2int_map,strlwr(src_charset),(int*)&(p->src_charset));
ret[2]=map_str2int(string2int_map,strlwr(merge),&(p->do_charset_merge));
if(strlen(quick_str_scan)>0)
,table_type_str
,not_care);
ret=map_str2int(string2int_map,strlwr(table_type_str),(int*)&(p->table_type));
if(ret<0)
{
ret[3]=map_str2int(string2int_map,strlwr(quick_str_scan),&(p->quick_expr_switch));
MESA_handle_runtime_log(logger, RLOG_LV_FATAL,maat_module,
"Maat read table info %s line %d error:invalid table type.",table_info_path,i);
goto error_jump;
}
memset(quick_str_scan,0,sizeof(quick_str_scan));
for(j=0;j<4;j++)
switch(p->table_type)
{
if(ret[j]<0)
case TABLE_TYPE_EXPR:
case TABLE_TYPE_EXPR_PLUS:
ret=read_expr_table_info(line, i, p, string2int_map);
if(ret<0)
{
fprintf(stderr,"Maat read table info %s line %d error:unknown column.\n",table_info_path,i);
MESA_handle_runtime_log(logger, RLOG_LV_FATAL,maat_module,
"Maat read table info %s line %d error:unknown column.",table_info_path,i);
goto error_jump;
}
}
j=0;
for (token = dst_charset; ; token= NULL)
{
sub_token= strtok_r(token,"/", &saveptr);
if (sub_token == NULL)
break;
ret[3]=map_str2int(string2int_map,strlwr(sub_token),(int*)&(p->dst_charset[j]));
if(ret[3]>0)
case TABLE_TYPE_PLUGIN:
p->cb_info=(struct _plugin_table_info*)calloc(sizeof(struct _plugin_table_info),1);
p->cb_info->cache_lines=dynamic_array_create(1024,1024);
ret=sscanf(not_care,"%d",&(p->valid_flag_column));
if(ret==0||ret==EOF)
{
if(p->dst_charset[j]==p->src_charset)
{
p->src_charset_in_dst=TRUE;
p->valid_flag_column=-1;
}
j++;
}
else
{
fprintf(stderr,"Maat read table info %s line %d error:unknown dest charset %s.\n",table_info_path,i,sub_token);
MESA_handle_runtime_log(logger, RLOG_LV_FATAL,maat_module,
"Maat read table info %s line %d error: unknown dest charset %s.",table_info_path,i,sub_token);
goto error_jump;
break;
default:
break;
}
}
if(p->table_id>=num)
{
fprintf(stderr,"Maat read table info %s:%d error: table id %uh > %d.\n",table_info_path,i,p->table_id,num);
@@ -618,11 +655,7 @@ int read_table_info(struct _Maat_table_info_t** p_table_info,int num,const char*
//use goto to free the conjunctioned table_info
goto error_jump;
}
if(p->table_type==TABLE_TYPE_PLUGIN)
{
p->cb_info=(struct _plugin_table_info*)calloc(sizeof(struct _plugin_table_info),1);
p->cb_info->cache_lines=dynamic_array_create(1024,1024);
}
p_table_info[p->table_id]=p;
table_cnt++;
continue;
@@ -1357,7 +1390,7 @@ void cancel_last_region_from_group(struct _Maat_group_inner_t* group,int region_
{
struct _Maat_region_inner_t* region_rule=NULL;
pthread_mutex_lock(&(group->mutex));
region_rule=(struct _Maat_region_inner_t*)dynamic_array_read(group->regions,group->region_boundary);
region_rule=(struct _Maat_region_inner_t*)dynamic_array_read(group->regions,group->region_boundary-1);
assert(region_rule->expr_id_ub==expr_id&&region_rule->region_id==region_id);
if(region_rule->expr_id_cnt==1)
{
@@ -1369,7 +1402,7 @@ void cancel_last_region_from_group(struct _Maat_group_inner_t* group,int region_
else
{
region_rule->expr_id_ub--;
region_rule->region_cnt--;
region_rule->expr_id_cnt--;
}
pthread_mutex_unlock(&(group->mutex));
return;
@@ -1771,6 +1804,8 @@ int add_expr_rule(struct _Maat_table_info_t* table,struct db_str_rule_t* db_rule
scanner->dedup_expr_num++;
cancel_last_region_from_group(group_rule,db_rule->region_id,op_expr->p_expr->expr_id);
destroy_op_expr(op_expr);
//redeem expr_id
scanner->exprid_generator--;
op_expr=NULL;
}
else
@@ -3077,7 +3112,7 @@ void *thread_rule_monitor(void *arg)
,maat_finish_cb
,feather
,feather->decrypt_key //Not used.
,feather->logger);
,feather);
}
else
{
@@ -3094,7 +3129,7 @@ void *thread_rule_monitor(void *arg)
if(feather->update_tmp_scanner!=NULL)
{
old_scanner=feather->scanner;
//__sync_lock_test_and_set not work in some OS.
//Some OS doesn't have __sync_lock_test_and_set.
//feather->scanner=__sync_lock_test_and_set(&(feather->scanner),feather->update_tmp_scanner);
feather->scanner=feather->update_tmp_scanner;
if(old_scanner!=NULL)

View File

@@ -165,19 +165,22 @@ struct op_expr_t
struct _Maat_region_inner_t
{
int region_id;
int expr_id_cnt;
int district_id;
int table_id;
int expr_id_cnt;
int expr_id_lb;
int expr_id_ub;
enum MAAT_TABLE_TYPE region_type;
enum MAAT_TABLE_TYPE table_type;
};
struct _Maat_group_inner_t
{
int group_id;
int table_id;
int region_boundary;
int region_cnt;
int ref_cnt;
dynamic_array_t *region_rules;
char* group_name;
dynamic_array_t *regions;
void* compile_shortcut;
pthread_mutex_t mutex;
};
@@ -185,9 +188,10 @@ struct _Maat_compile_inner_t
{
struct db_compile_rule_t *db_c_rule;
dynamic_array_t *groups;
int compile_id;//equal to db_c_rule->m_rule.config_id
int table_id;
int group_boundary;
int group_cnt;
int compile_id;//equal to db_c_rule->m_rule.config_id
pthread_rwlock_t rwlock;//reading compile rule is safe in update thread, rwlock lock called when delete or scan thread read
};
struct _compile_result_t
@@ -252,6 +256,7 @@ struct _Maat_table_info_t
int ipv6_rule_cnt;
};
struct _plugin_table_info *cb_info;
int valid_flag_column;
//for stat>>>>>>>>
unsigned long long udpate_err_cnt;
unsigned long long iconv_err_cnt;
@@ -369,14 +374,14 @@ struct _Maat_feather_t
pthread_mutex_t plugin_table_reg_mutex;
unsigned char decrypt_key[MAX_TABLE_NAME_LEN];
unsigned char redis_ip[MAX_TABLE_NAME_LEN];
char redis_ip[MAX_TABLE_NAME_LEN];
int redis_port;
struct timeval connect_timeout;
redisContext *redis_read_ctx;
redisContext *redis_write_ctx; // not thread safe.
int on_redis_writing;
int cmd_q_cnt;
struct _Maat_cmd_t* cmd_qhead, *cmd_qtail;
struct _Maat_cmd_inner_t* cmd_qhead, *cmd_qtail;
pthread_mutex_t redis_write_lock; //protect redis_write_ctx
long long base_rgn_seq,base_grp_seq;
//for stat>>>>
@@ -408,8 +413,8 @@ struct _maat_garbage_t
union
{
struct _Maat_scanner_t* scanner;
struct _Maat_group_rule_t* group_rule;
struct _Maat_compile_rule_t* compile_rule;
struct _Maat_group_inner_t* group_rule;
struct _Maat_compile_inner_t* compile_rule;
void* bool_matcher;
void * raw;
MESA_htable_handle str2int_map;
@@ -417,7 +422,7 @@ struct _maat_garbage_t
};
void garbage_bagging(enum maat_garbage_type type,void *p,MESA_lqueue_head garbage_q);
void garbage_bury(MESA_lqueue_head garbage_q,void *logger);
void make_group_set(const struct _Maat_compile_rule_t* compile_rule,universal_bool_expr_t* a_set);
void make_group_set(const struct _Maat_compile_inner_t* compile_rule,universal_bool_expr_t* a_set);
int read_table_info(struct _Maat_table_info_t** p_table_info,int num,const char* table_info_path,int max_thread_num,void* logger);
void maat_start_cb(unsigned int new_version,int update_type,void*u_para);
void maat_update_cb(const char* table_name,const char* line,void *u_para);
@@ -433,10 +438,13 @@ inline void ipv6_ntoh(unsigned int *v6_addr)
}
return;
}
void * HASH_fetch_by_id(MESA_htable_handle hash,int id);
int HASH_add_by_id(MESA_htable_handle hash,int id,void*data);
int HASH_delete_by_id(MESA_htable_handle hash,int id);
void maat_stat_init(struct _Maat_feather_t* feather);
void maat_stat_table(struct _Maat_table_info_t* p_table,int scan_len,struct timespec* start, struct timespec* end,int thread_num);
void maat_stat_output(struct _Maat_feather_t* feather);
char* _maat_strdup(const char* s);
void redis_monitor_traverse(unsigned int version,redisContext *c,
void (*start)(unsigned int ,int ,void*),//vesion,CM_UPDATE_TYPE_*,u_para
void (*update)(const char* ,const char*,void* ),//table name ,line ,u_para

View File

@@ -4,11 +4,11 @@
CC = gcc
CCC = g++
CFLAGS = -Wall -g -fPIC
GCOV_FLAGS = -fprofile-arcs -ftest-coverage
#GCOV_FLAGS = -fprofile-arcs -ftest-coverage
CFLAGS += $(OPTFLAGS)
#CFLAGS += $(GCOV_FLAGS)
LDDICTATOR = -Wl,-wrap,malloc -Wl,-wrap,calloc -Wl,-wrap,free -Wl,-wrap,realloc
LDFLAGS = -lMESA_handle_logger -lMESA_htable -lpthread -lrt -lm -lrulescan -lpcre -lMESA_field_stat2 -lcrypto
LDFLAGS = -lMESA_handle_logger -lMESA_htable -lpthread -lrt -lm -lrulescan -lpcre -lMESA_field_stat2 -lcrypto -lhiredis_vip
#LDFLAGS += $(LDDICTATOR)
LDFLAGS += $(GCOV_FLAGS)
MAILLIB = ../lib
@@ -18,8 +18,8 @@ H_DIR =-I$(G_H_DIR) -I../../inc
LIBMAAT = libmaatframe.a
LIBMAAT_SO = libmaatframe.so
OBJS=config_monitor.o Maat_rule.o Maat_api.o Maat_stat.o UniversalBoolMatch.o dynamic_array.o cJSON.o\
json2iris.o map_str2int.o interval_index.o great_index_engine.o mesa_fuzzy.o rbtree.o
OBJS=config_monitor.o Maat_rule.o Maat_api.o Maat_command.o Maat_stat.o UniversalBoolMatch.o dynamic_array.o\
cJSON.o json2iris.o map_str2int.o interval_index.o great_index_engine.o mesa_fuzzy.o rbtree.o
.c.o:
$(CC) -c $(CFLAGS) -I. $(H_DIR) $<

View File

@@ -52,7 +52,7 @@ int decrypt_open(FILE* in,const unsigned char* key, const char* algorithm,unsign
cipher=EVP_get_cipherbyname(algorithm);
if(cipher==NULL)
{
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,module_config_monitor,"Not cipher:%s not supported.");
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,module_config_monitor,"Not cipher:%s not supported.",algorithm);
return 0;
}
dgst=EVP_get_digestbyname("md5");

View File

@@ -55,8 +55,6 @@ struct traslate_command_t
};
int set_iris_descriptor(const char* json_file,cJSON *json,const char*compile_tn,const char* group_tn,struct iris_description_t *iris_cfg,void * logger)
{
cJSON* j=NULL;
char* table_name=NULL;
memset(iris_cfg,0,sizeof(struct iris_description_t));
snprintf(iris_cfg->tmp_iris_dir,sizeof(iris_cfg->tmp_iris_dir),"%s_iris_tmp",json_file);
snprintf(iris_cfg->tmp_iris_index_dir,sizeof(iris_cfg->tmp_iris_index_dir),"%s_iris_tmp/index",json_file);

105
src/inc_internal/sds.h Normal file
View File

@@ -0,0 +1,105 @@
/* SDS (Simple Dynamic Strings), A C dynamic strings library.
*
* Copyright (c) 2006-2014, Salvatore Sanfilippo <antirez at gmail dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Redis nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __SDS_H
#define __SDS_H
#define SDS_MAX_PREALLOC (1024*1024)
#include <sys/types.h>
#include <stdarg.h>
#ifdef _MSC_VER
#include "win32.h"
#endif
typedef char *sds;
struct sdshdr {
int len;
int free;
char buf[];
};
static inline size_t sdslen(const sds s) {
struct sdshdr *sh = (struct sdshdr *)(s-sizeof *sh);
return sh->len;
}
static inline size_t sdsavail(const sds s) {
struct sdshdr *sh = (struct sdshdr *)(s-sizeof *sh);
return sh->free;
}
sds sdsnewlen(const void *init, size_t initlen);
sds sdsnew(const char *init);
sds sdsempty(void);
size_t sdslen(const sds s);
sds sdsdup(const sds s);
void sdsfree(sds s);
size_t sdsavail(const sds s);
sds sdsgrowzero(sds s, size_t len);
sds sdscatlen(sds s, const void *t, size_t len);
sds sdscat(sds s, const char *t);
sds sdscatsds(sds s, const sds t);
sds sdscpylen(sds s, const char *t, size_t len);
sds sdscpy(sds s, const char *t);
sds sdscatvprintf(sds s, const char *fmt, va_list ap);
#ifdef __GNUC__
sds sdscatprintf(sds s, const char *fmt, ...)
__attribute__((format(printf, 2, 3)));
#else
sds sdscatprintf(sds s, const char *fmt, ...);
#endif
sds sdscatfmt(sds s, char const *fmt, ...);
void sdstrim(sds s, const char *cset);
void sdsrange(sds s, int start, int end);
void sdsupdatelen(sds s);
void sdsclear(sds s);
int sdscmp(const sds s1, const sds s2);
sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count);
void sdsfreesplitres(sds *tokens, int count);
void sdstolower(sds s);
void sdstoupper(sds s);
sds sdsfromlonglong(long long value);
sds sdscatrepr(sds s, const char *p, size_t len);
sds *sdssplitargs(const char *line, int *argc);
sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen);
sds sdsjoin(char **argv, int argc, char *sep, size_t seplen);
sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen);
/* Low level functions exposed to the user API */
sds sdsMakeRoomFor(sds s, size_t addlen);
void sdsIncrLen(sds s, int incr);
sds sdsRemoveFreeSpace(sds s);
size_t sdsAllocSize(sds s);
#endif