RT-Thread finsh源码分析: finsh_var.c
2015-08-18 22:03
337 查看
/* * 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; }
相关文章推荐
- 花生壳映射svn
- BZOJ 1703 [Usaco2007 Mar]Ranking the Cows 奶牛排名 bitset优化
- Github搭建属于自己的开源项目-androd学习之旅(72)
- [UVA10533]Digit Primes
- linux-grep/cut/wc/sort
- R语言之描述性统计量
- Android TextView
- 原码, 反码, 补码 详解
- C++ Primer 5e chapter 2
- RT-Thread finsh源码分析: finsh_var.h
- QT串口工具(1)
- 海外短租,亟待巨头定规矩?
- Linux基本权限与ACL权限
- Android ToggleButton和Switch
- UIP协议一
- SPOJ 题目694 Distinct Substrings(后缀数组,求不同的子串个数)
- Poj 1321 棋盘问题
- iOS 任意圆角button,左圆右直,左直右圆,上圆下直,上直下圆
- 回文判断
- light oj 1248 第六周E题(期望)