RT-Thread finsh源码分析: finsh_var.c

/*
 *  Variable implementation in finsh shell.
 *
 * COPYRIGHT (C) 2006 - 2013, RT-Thread Development Team
 *
 *  This file is part of RT-Thread (http://www.rt-thread.org)
 *  Maintainer: bernard.xiong <bernard.xiong at gmail.com>
 *
 *  All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Change Logs:
 * Date           Author       Notes
 * 2010-03-22     Bernard      first version
 * 2012-04-27     Bernard      fixed finsh_var_delete issue which
 *                             is found by Grissiom.
 */
#include <finsh.h>
#include "finsh_var.h"

//结构体数组,全局变量,全局变量加前缀global,增加代码可读性
struct finsh_var global_variable[FINSH_VARIABLE_MAX];
//在finsh.h中定义
struct finsh_sysvar_item* global_sysvar_list;

//数组global_variable初始化
int finsh_var_init()
{
        //此处使用sizeof(global_variable),
        //而不是FINSH_VARIABLE_MAX * sizeof(finsh_var)
        //增加代码可读性
    memset(global_variable, 0, sizeof(global_variable));

    //一般情况,正常返回0值,错误返回负值,如-1,但最后使用宏定义错误码
    //不推荐使用魔数
    return 0;
}

//变量var插入函数,注意name前面const修饰符,用于防止误操作,因为这一系列操作都是
//根据唯一的name值进行
int finsh_var_insert(const char* name, int type)
{
    int i, empty;  //empty用于存储找到的索引值i

    empty = -1;
    for (i = 0; i < FINSH_VARIABLE_MAX; i ++)
    {
        /* there is a same name variable exist. */
        //strncmp返回0值表示双方字符串相同
        if (strncmp(global_variable[i].name, name, FINSH_NAME_MAX) == 0)
            return -1;
                //finsh_type_unknown是枚举值,在finsh.h文件中定义
                //&&empty的目的是找到第一个未使用的索引值即可
                //此处为什么不用break?break会影响代码优化,特别是在for,while循环中
                //具体优化知识可以查阅科学巨著《深入理解计算机系统》
        if (global_variable[i].type == finsh_type_unknown && empty == -1)
        {
            empty = i;
        }
    }

    //如果 global_variable[i].type != finsh_type_unknown
    //即数组已满,返回-1
    /* there is no empty entry */
    if (empty == -1) return -1;

    //插入var到数组global_variable
    /* insert entry */
    //使用strncpy而不是strcpy,减少数组越界风险
    strncpy(global_variable[empty].name, name, FINSH_NAME_MAX);
    //类型定义
    global_variable[empty].type = type;

    //返回数组下标
    /* return the offset */
    return empty;
}

//变量var删除函数
int finsh_var_delete(const char* name)
{
    int i;

    for (i = 0; i < FINSH_VARIABLE_MAX; i ++)
    {
            //strncmp == 0,表示双方name匹配,故跳出循环
        if (strncmp(global_variable[i].name, name, FINSH_NAME_MAX) == 0)
            break;
    }

    //如果i == FINSH_VARIABLE_MAX,证明遍历数组都找不到同名var,返回-1
    /* can't find variable */
    if (i == FINSH_VARIABLE_MAX) return -1;

    //清空该var值,全部初始化为0
    memset(&global_variable[i], 0, sizeof(struct finsh_var));

    //返回0值,表示OK
    return 0;
}

//查找var函数
struct finsh_var* finsh_var_lookup(const char* name)
{
    int i;

    //遍历数组
    for (i = 0; i < FINSH_VARIABLE_MAX; i ++)
    {
        if (strncmp(global_variable[i].name, name, FINSH_NAME_MAX) == 0)
            break;
    }

    /* can't find variable */
    if (i == FINSH_VARIABLE_MAX) return NULL;

    //返回索引值对应的结构体指针
    return &global_variable[i];
}

#ifdef RT_USING_HEAP  //如果定义RT_USING_HEAP
//sysvar附属函数
void finsh_sysvar_append(const char* name, u_char type, void* var_addr)
{
    /* create a sysvar */
    //在finsh.h中定义
    struct finsh_sysvar_item* item;

    //在内存池中申请大小sizeof(struct finsh_sysvar_item)的内存
    item = (struct finsh_sysvar_item*) rt_malloc (sizeof(struct finsh_sysvar_item));
    //非空判断,防止指针错误
    if (item != NULL)
    {
            //结构体初始化
        item->next = NULL;  
        item->sysvar.name = rt_strdup(name);
        item->sysvar.type = type;
        item->sysvar.var = var_addr;

        //如果global_sysvar_list == NULL,说明是头指针
        if (global_sysvar_list == NULL)
        {
            global_sysvar_list = item;
        }
        else  //如果非空,插入global_sysvar_list,注意该链表是首尾相连的
        {
            item->next = global_sysvar_list;
            global_sysvar_list = item;
        }
    }
}
#endif

//sysvar查找函数
struct finsh_sysvar* finsh_sysvar_lookup(const char* name)
{
    struct finsh_sysvar* index;
    struct finsh_sysvar_item* item;

    //此处_sysvar_table_begin等在finsh.h中定义
    for (index = _sysvar_table_begin;
         index < _sysvar_table_end;
         FINSH_NEXT_SYSVAR(index))
    {
            //同名,则返回下标
        if (strcmp(index->name, name) == 0)
            return index;
    }

    /* find in sysvar list */
    //对局部变量item进行操作,而不是对全局变量global_sysvar_list直接操作
    item = global_sysvar_list;
    //遍历查找同名变量,找到则返回
    while (item != NULL)
    {
        if (strncmp(item->sysvar.name, name, strlen(name)) == 0)
        {
            return &(item->sysvar);
        }

        /* move to next item */
        item = item->next;
    }

    /* can't find variable */
    return NULL;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值