自定义打印日志及红黑树应用

文章仅供个人记录使用

c语言个人打印函数及红黑树的增删改查实例记录,红黑树的移植在上一章已经描述过了,主要记录一下函数可变参的处理

/********************************************************************************************************
/                                                Vicon OS-I
/                                          The Linux-app Wireless manager
/
/
/                         (c) Copyright 2019-2023; Micrium, Inc.; ShenZhen, FL
/                    All rights reserved.  You may obtain a copy of the License at:.
/
/                                           huguidong@me.com
/
/ File      : MacDr.c
/ Version   : V1.0.0
/ (c)       : Doon < huguidong@me.com >
/ Date		: 2020-January 15 Wednesday
/
/ Platform  : Mipsel-Openwrt
/ Mode      : Thread mode
/ Toolchain : Source Insight 4.0
/ Desc		: Machine Driver .
********************************************************************************************************/
#include "MacDr.h"
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
/*
************************************************************************************************************************
*                                            System driver entrance
*
* Description : System driver's interface .
*
* Entrance : 
             
			 mytree                   the red-black tree root.
			 -------------
			 
			 dev_rb_insert            add some node to the device tree
             -------------
			 
             dev_rb_find              find some node from the device tree
             -------------
			 
             dev_rb_delete            delete some node from the device tree
             -------------

             dev_rb_destory           destory the whole tree.
             -------------

************************************************************************************************************************
*/

/* 
 *
 * x point
 * 
 *          px                                  px
 *         /                                    /
 *        x                                    y                
 *       /  \      --(left rotate)-->         / \                     #
 *      lx   y                               x  ry     
 *         /   \                             /  \
 *        ly   ry                           lx  ly  
 *
 *
 */
 
/*
 *
 * y point
 *
 *            py                                    py
 *           /                                      /
 *          y                                      x                  
 *         /  \      --(right rotate)-->          /  \                #
 *        x   ry                                 lx   y  
 *       / \                                    / \                   #
 *      lx  rx                                rx  ry
 *
 */
 
struct rb_root mytree;
/**
*@des: create a user node of rbtrees
*/
dev_rb_t *
create_dev_node( struct dev_info *dev_info )
{
	dev_rb_t *node;
	
	node = ( dev_rb_t* )malloc( sizeof( dev_rb_t ) );
	if( node )
	{
		memset( node , 0 ,sizeof(dev_rb_t) );
		memcpy( (char *)&node->info, dev_info , sizeof( struct dev_info ) );
		return node;
	}
	else	return NULL;
}

/**
*@des: find the user node.
*/
struct dev_info *
dev_rb_find( struct rb_root *root , char *mac )
{
	struct rb_node *node = root->rb_node;
	dev_rb_t *goal_node = NULL;
	int res = 0;
	
	while( node )
	{
		goal_node = rb_entry( node , dev_rb_t , node );
		res = strcmp( goal_node->info.mac_addr , mac );
		if( res < 0 ){
			node = node->rb_left;
		}else if( res > 0 ){
			node = node->rb_right;
		}else{
			return &goal_node->info;
		}
	}
	return NULL;
}

/**
*@des: insert a user node.
*/
int
dev_rb_insert( struct rb_root *root , struct dev_info *dev_info )
{
	struct rb_node **new = &(root->rb_node);
	struct rb_node *parent = NULL;
	dev_rb_t *goal_node = NULL;
	int res = 0;
	
	while( *new )
	{
		parent = *new;
		goal_node = rb_entry( *new , dev_rb_t , node );
		res = strcmp( goal_node->info.mac_addr , dev_info->mac_addr );
		if( res < 0 ){
			new = &(( *new )->rb_left );
		}else if( res > 0 ){
			new = &(( *new )->rb_right );
		}else{
			return 0;
		}
	}
	
	/* create red-black tree node */
	goal_node = create_dev_node( dev_info );
	if( goal_node )
	{
		// add new node
		rb_link_node( &goal_node->node ,parent , new );
		// rebalence red-black tree
		rb_insert_color( &goal_node->node , root );
		
		return 0;		/* < success > */
	}else return -1;	/* < failed > */
}


/**
*@des: delete single node
*/
int
dev_rb_delete( struct rb_root *root , char *mac )
{
	dev_rb_t *goal_node;
	// Here changed the return of rb find . so we should offset the struct
	goal_node = rb_entry( dev_rb_find( root , mac ) , dev_rb_t , info );
	if( goal_node )
	{
		rb_erase( &goal_node->node , root );
		free( goal_node );
		return 0;		/* < success > */
	}else return -1;	/* < failed > */
}

/**
*@des: destory whole tree
*/
void 
dev_rb_destory( struct rb_root *root )
{
	struct rb_node *node = NULL, *tmp_node = NULL;
	dev_rb_t *goal_node = NULL;
	
	for( node = rb_first(root) ; node ; )
	{
		tmp_node = rb_next( node );
		goal_node = rb_entry( node , dev_rb_t , node );
		rb_erase( node , root );
		free( goal_node );
		node = tmp_node;
	}
}

/*
************************************************************************************************************************
*                                            System debug entrance
*
* Description : System debug logo print .
*
* Entrance : 
             
			 logo_output               the system output root.
			 -------------

************************************************************************************************************************
*/
static char *lvl_names[] = {
    "non", "crt", "err", "wrn", "inf", "dbg", "flw"
};
const char *lvl_color[] = {
    "[0m", "[1;31m", "[1;31m", "[1;35m", "[1;33m", "[1;36m", "[1;34m"
};

void 
my_printf(const char *fmt, ... )
{
    va_list args;

    va_start( args , fmt );
    vprintf( fmt , args );
    va_end( args );

    fflush( stdout );
}

void
logo_output( unsigned char level , const char *fmt , ... )
{
	va_list args;
	va_start( args , fmt );
		
	my_printf( "%s%s", "\033" , lvl_color[level] );
    my_printf( "[%s] %s(%d): " , lvl_names[level] , __FILE__ , __LINE__ );
	vprintf( fmt , args );
	my_printf( "%s\r\n", "\033[0m");
	
	va_end( args );
	
	fflush( stdout );
}


struct SysBox Sysbox = {
	.drv_api = {
		.root = &mytree,
		.find = dev_rb_find,
		.insert = dev_rb_insert,
		.delete = dev_rb_delete,
		.destory = dev_rb_destory
	},
	
	.output = {
		.print = logo_output,
	},
	
};

/******************* (C) COPYRIGHT 2020 Doon****************END OF FILE****/

系统盒子接口如下:

struct SysBox{
		
		struct{
			/* Device's root node */
			struct rb_root *root;
			/* look for someone */
			struct dev_info *(*find)( struct rb_root *root , char *mac );
			/* Insert node */
			int (*insert)( struct rb_root *root , struct dev_info *dev_info );
			/* Delete node */
			int (*delete)( struct rb_root *root , char *mac );
			/* Destory whole tree */
			void (*destory)( struct rb_root *root );
		}drv_api;
		
		struct{
			void (*print)( unsigned char level , const char *fmt , ... )__attribute__ ((format (printf, 2, 3)));
		}output;
};

测试代码如下:

struct dev_info test,*test1;
	int rest,i;

	Sysbox.output.print( LOG_NONE_LEVEL , "%s" , "LOG_NONE_LEVEL" );
	Sysbox.output.print( LOG_CRIT_LEVEL , "%s" , "LOG_CRIT_LEVEL" );
	Sysbox.output.print( LOG_ERR_LEVEL , "%s" , "LOG_ERR_LEVEL" );
	Sysbox.output.print( LOG_WARNING_LEVEL , "%s" , "LOG_WARNING_LEVEL" );
	Sysbox.output.print( LOG_INFO_LEVEL , "%s" , "LOG_INFO_LEVEL" );
	Sysbox.output.print( LOG_DEBUG_LEVEL , "%s" , "LOG_DEBUG_LEVEL" );
	Sysbox.output.print( LOG_FLOW_LEVEL , "%s" , "LOG_FLOW_LEVEL" );
	

	for( i = 0 ; i < 10 ; i++ )
	{
			sprintf( test.mac_addr , "0123456789-%d" , i + 1 );
			rest = Sysbox.drv_api.insert( Sysbox.drv_api.root , &test );
			if( rest )			Sysbox.output.print( LOG_WARNING_LEVEL , "insert %s failed" , test.mac_addr );
			else				Sysbox.output.print( LOG_DEBUG_LEVEL , "insert %s success" , test.mac_addr );
	}

	/* find the first one */
	test1 = Sysbox.drv_api.find( Sysbox.drv_api.root , "0123456789-1" );
	if( test1 != NULL )	Sysbox.output.print( LOG_DEBUG_LEVEL , "find [%s]" , test1->mac_addr );
	else					Sysbox.output.print( LOG_WARNING_LEVEL , "can't find-1" );

	/* delete the first one */
	rest = Sysbox.drv_api.delete( Sysbox.drv_api.root , "0123456789-1" );
	if( rest )			Sysbox.output.print( LOG_WARNING_LEVEL , "delete 0123456789-1 failed" );
	else					Sysbox.output.print( LOG_DEBUG_LEVEL , "delete 0123456789-1 success" );

	/* find the first one again */
	test1 = Sysbox.drv_api.find( Sysbox.drv_api.root , "0123456789-1" );
	if( test1 != NULL )	Sysbox.output.print( LOG_DEBUG_LEVEL , "find [%s]" , test1->mac_addr );
	else					Sysbox.output.print( LOG_WARNING_LEVEL , "can't find-1" );

以及通过mqtt的触发发送

int
MQ_Test( const char *buff )
{
	cJSON *root,*devlist,*dev;
	struct rb_node *node;
	char *endpoint , *l_poJson;

	root = cJSON_CreateObject();
	if( root )
	{
		cJSON_AddStringToObject( root , "Code" , "200" );
		cJSON_AddStringToObject( root , "Cmd" , "Test" );
		devlist = cJSON_CreateArray();
		cJSON_AddItemToObject( root , "RbTree" , devlist );
		for( node = rb_first( Sysbox.drv_api.root ) ; node  ; node = rb_next( node ) )
		{
			//Sysbox.output.print( LOG_INFO_LEVEL , "Mac[%s]" , rb_entry( node , dev_rb_t , node )->info.mac_addr );
			dev = cJSON_CreateObject();
			cJSON_AddItemToArray( devlist , dev );
			cJSON_AddStringToObject( dev , "mac_addr" , rb_entry( node , dev_rb_t , node )->info.mac_addr );
		}
		l_poJson = cJSON_PrintUnformatted( root );
		KS_MQTT_Publish( l_poJson );
		cJSON_Delete( root );
		free( l_poJson );
		return 0;
	}
}

好的,接下来看看效果:
在这里插入图片描述
整体来说也还行~~不过目前仅仅是个demo,后续会把打印等级开关,重定向到文件等等补齐。json的打印未贴出~有兴趣的可以去阿里给的MQTT源码里找。

收工!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值