PC-lint安装及使用总结_第1页
PC-lint安装及使用总结_第2页
PC-lint安装及使用总结_第3页
PC-lint安装及使用总结_第4页
PC-lint安装及使用总结_第5页
已阅读5页,还剩30页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

精选优质文档倾情为你奉上精选优质文档倾情为你奉上专心专注专业专心专注专业精选优质文档倾情为你奉上专心专注专业PC-lint研究总结TOC1. PC-lint总体介绍 图在ProjectManager中的源文件上点击鼠标右键,选择Lint就开始检查选中的文件了,输出信息在Build窗口。图3.2.2.5集成到SI中SourceInsight的集成方法参见C:\Lint8\lnt\env-si.lnt中的注释。从Options菜单中选择“Custom

Commands”命令项。点击Add…。在Name栏中输入“PC-lint

unitcheck”,原则上这个名称可以随便起,只要你能搞清楚它的含义就可以了。在Run栏中输入“C:\Lint8\lint-nt

-u

-iC:\Lint8\

std

env-si

%f”其中C:\Lint8是你PC-LINT的安装目录。在Output栏中选择“Iconic

Window”、“Capture

Output”。在Control栏中选择“Save

Files

First”。在Source

Links

in

Output栏中选择“Parse

Links

in

Output”、“File,then

Line”。在Pattern栏中输入“^\([^

]*\)

\([0-9]+\)”。点Close键加入该命令。如下图:图3.2.3.1使用时,在Source

Insight下打开要LINT的文件,打开Options菜单中的“Custom

Commands”命令项,在“Command”栏中选择“PC-lint

unit

check”命令运行即可。请注意,不论你怎样配置参数一定不要忘记了将env-si.lnt包含在你的配置文件里,否则就无法进行错误信息和程序的自动对应了。用Menu命令把PC_Lint添加到菜单中。图3.2.3.2至此,你可以运行sourceinsight下集成的PC-Lint功能完成对代码的走查,并且很方便的找到错误信息的位置。图3.2.3.3在错误信息处点击旁边的红色图标,就会自己跳转至错误出现处。上图就是一个不安全变量转换的警告信息。以上是对在sourceinsight3.5中使用集成PC-lint的一个总结。我们可以看到该方式使用PC-lint简单易用,容易查找到错误,但考虑只能做当前文件的单元检查,需要自己指定Include目录和需要自己定义相关的宏等,设置过程比较麻烦,并且不够通用。此方式适合个人维护自己的代码用,对于整个部门的代码的走查,还是采取makefile的方式比较好。集成到UE中图3.2.4.1(1)从UltraEdit的<高级>菜单中进入<工具配置>(2)<菜单项目名>栏输入“PC-lintunitcheck”(3)<命令行>栏输入以下命令:C:\PCLint8\LINT-NT–u-iC:\PCLint8\si\stdenv-si%f其中,C:\PCLint8是PC-Lint的安装目录(4)<工作目录>栏输入以下路径:x:\code(5)选中<先保存所有文件>的复选框(6)在<命令输出>栏中,选中<输出到列表>和<捕捉输出>(7)点<插入>将命令行插入UltraEdit的菜单,此时在UltraEdit的<高级>菜单中会增加一个<PC-lintunitcheck>栏目,点击该栏目即可对当前文件执行PC-lint。检查的执行结果如下图所示:图3.2.4.2makefile方式这里makefile指的是一类文件,用在C/C++的Make工具中,Make工具通过makefile文件来描述源程序之间的相互关系,并自动维护编译工作。Makefile文件按照特定的语法进行编写,文件中需要说明如何编译各个源文件,并连接生成可执行文件。Makefile文件作为一种描述文档一般需要包含以下内容:

◆宏定义

◆源文件之间的相互依赖关系

◆可执行的命令

Makefile中允许使用简单的宏指代源文件及其相关编译信息,也称宏为变量。在引用宏时只需在变量前加$符号,但值得注意的是,如果变量名的长度超过一个字符,在引用时就必须加圆括号()。平台目前使用的Make工具是Tornado集成环境中的自带的make.exe(一般位于Tornado安装目录\host\x86-win32\bin),它实际上是GNUMakeversion3.74(vpath+),以上的版本信息具体情况可能会略有不同,可以通过make–v来查看。那么,在说明平台的makefile结构和如何将PC-lint结合到makefile中使用之前,先来介绍GNUMake及makefile。GNUMake和makefile介绍GNUMake在大型的开发项目中,通常有几十到上百个的源文件,如果每次均手工键入gcc命令进行编译的话,则会非常不方便。因此,人们通常利用make工具来自动完成编译工作。这些工作包括:如果仅修改了某几个源文件,则只重新编译这几个源文件;如果某个头文件被修改了,则重新编译所有包含该头文件的源文件。利用这种自动编译可大大简化开发工作,避免不必要的重新编译。实际上,make工具通过一个称为makefile的文件来完成并自动维护编译工作。makefile需要按照某种语法进行编写,其中说明了如何编译各个源文件并连接生成可执行文件,并定义了源文件之间的依赖关系。当修改了其中某个源文件时,如果其他源文件依赖于该文件,则也要重新编译所有依赖该文件的源文件。makefile文件是许多编译器,包括WindowsNT下的编译器维护编译信息的常用方法,只是在集成开发环境中,用户通过友好的界面修改makefile文件而已。默认情况下,GNUmake工具在当前工作目录中按如下顺序搜索makefile:*GNUmakefile*makefile*Makefile在UNIX系统中,习惯使用Makefile作为makfile文件。如果要使用其他文件作为makefile,则可利用类似下面的make命令选项指定makefile文件:$make-fMakefile.debugmakefile基本结构makefile中一般包含如下内容:*需要由make工具创建的项目,通常是目标文件和可执行文件。通常使用“目标(target)”一词来表示要创建的项目。*要创建的项目依赖于哪些文件。*创建每个项目时需要运行的命令。例如,假设你现在有一个C/C++源文件test.C,该源文件包含有自定义的头文件test.h,则目标文件test.o明确依赖于两个源文件:test.C和test.h。另外,你可能只希望利用g++命令来生成test.o目标文件。这时,就可以利用如下的makefile来定义test.o的创建规则:#Thismakefilejustisaexample.#Thefollowinglinesindicatehowtest.odepends#test.Candtest.h,andhowtocreatetest.otest.o:test.Ctest.hg++-c-gtest.C从上面的例子注意到,第一个字符为#的行为注释行。第一个非注释行指定test.o为目标,并且依赖于test.C和test.h文件。随后的行指定了如何从目标所依赖的文件建立目标。当test.C或test.h文件在编译之后又被修改,则make工具可自动重新编译test.o,如果在前后两次编译之间,test.C和test.h均没有被修改,而且test.o还存在的话,就没有必要重新编译。这种依赖关系在多源文件的程序编译中尤其重要。通过这种依赖关系的定义,make工具可避免许多不必要的编译工作。当然,利用Shell脚本也可以达到自动编译的效果,但是,Shell脚本将全部编译任何源文件,包括哪些不必要重新编译的源文件,而make工具则可根据目标上一次编译的时间和目标所依赖的源文件的更新时间而自动判断应当编译哪个源文件。一个makefile文件中可定义多个目标,利用maketarget命令可指定要编译的目标,如果不指定目标,则使用第一个目标。通常,makefile中定义有clean目标,可用来清除编译过程中的中间文件,例如:clean:rm-f*.o运行makeclean时,将执行rm-f*.o命令,最终删除所有编译过程中产生的所有中间文件。makefile变量GNU的make工具除提供有建立目标的基本功能之外,还有许多便于表达依赖性关系以及建立目标的命令的特色。其中之一就是变量或宏的定义能力。如果你要以相同的编译选项同时编译十几个C源文件,而为每个目标的编译指定冗长的编译选项的话,将是非常乏味的。但利用简单的变量定义,可避免这种乏味的工作:#DefinemacrosfornameofcompilerCC=gcc#DefineamacrofortheCCflagsCCFLAGS=-D_DEBUG-g-m486#Aruleforbuildingaobjectfiletest.o:test.ctest.h$(CC)-c$(CCFLAGS)test.c在上面的例子中,CC和CCFLAGS就是make的变量。GNUmake通常称之为变量,而其他UNIX的make工具称之为宏,实际是同一个东西。在makefile中引用变量的值时,只需变量名之前添加$符号,如上面的$(CC)和$(CCFLAGS)。GNUmake的主要预定义变量GNUmake有许多预定义的变量,这些变量具有特殊的含义,可在规则中使用。表1-5给出了一些主要的预定义变量,除这些变量外,GNUmake还将所有的环境变量作为自己的预定义变量。表1-5GNUmake的主要预定义变量预定义变量含义$*不包含扩展名的目标文件名称。$+所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件。$<第一个依赖文件的名称。$?所有的依赖文件,以空格分开,这些依赖文件的修改日期比目标的创建日期晚。$@目标的完整名称。$^所有的依赖文件,以空格分开,不包含重复的依赖文件。$%如果目标是归档成员,则该变量表示目标的归档成员名称。例如,如果目标名称为mytarget.so(image.o),则$@为mytarget.so,而$%为image.o。AR归档维护程序的名称,默认值为ar。ARFLAGS归档维护程序的选项。AS汇编程序的名称,默认值为as。ASFLAGS汇编程序的选项。CCC编译器的名称,默认值为cc。CFLAGSC编译器的选项。CPPC预编译器的名称,默认值为$(CC)-E。CPPFLAGSC预编译的选项。CXXC++编译器的名称,默认值为g++。CXXFLAGSC++编译器的选项。FCFORTRAN编译器的名称,默认值为f77。FFLAGSFORTRAN编译器的选项。隐含规则GNUmake包含有一些内置的或隐含的规则,这些规则定义了如何从不同的依赖文件建立特定类型的目标。GNUmake支持两种类型的隐含规则:*后缀规则(SuffixRule)。后缀规则是定义隐含规则的老风格方法。后缀规则定义了将一个具有某个后缀的文件(例如,.c文件)转换为具有另外一种后缀的文件(例如,.o文件)的方法。每个后缀规则以两个成对出现的后缀名定义,例如,将.c文件转换为.o文件的后缀规则可定义为:.c.o:$(CC)$(CFLAGS)$(CPPFLAGS)-c-o$@$<*模式规则(patternrules)。这种规则更加通用,因为可以利用模式规则定义更加复杂的依赖性规则。模式规则看起来非常类似于正则规则,但在目标名称的前面多了一个%号,同时可用来定义目标和依赖文件之间的关系,例如下面的模式规则定义了如何将任意一个X.c文件转换为X.o文件:%.c:%.o$(CC)$(CFLAGS)$(CPPFLAGS)-c-o$@$<平台的makefile结构平台的makefile文件也称为工程文件,主要由名为makefile和*.mak的两类文件构成。平台的makefile文件可以分为两个等级:平台级和子系统级。平台级的makefile是生成最终的执行代码的工程文件,它还需要调用源程序体系中的子系统级的工程文件(或更深级别的工程文件)来最终完成自己的工作,它一般位于一级目录中的PROJECT目录。子系统级的makefile,主要是根据不同的编译选项来生成各种类型的目标文件(例如、各种逻辑单板的DEBUG、RELEASE版),它一般分布在一级目录CODE的各子系统、模块的目录中。它所需的各种选项由平台级的工程文件传递下来。PROJECT目录的组织规则是按照网元、物理单板和逻辑单板三层组织结构进行组织的。对于网元级目录,目前包括:BSC、PCF、AGW、HA、RNC、WCN,分别用来存放BSC、PCF、AGW、HA、RNC、WCDMACN的版本。对于物理单板级,没有工程文件,在其下按照该物理单板支持的逻辑单板创建相应的逻辑单板的目录,对于一种物理单板,可能有多种逻辑单板,或者多种逻辑单板的合一版本。在本目录中,存放所有的逻辑单板以及一些典型的合一单板的目录。对于逻辑单板级,存放的是相应逻辑单板的工程文件。平台级在Project目录下,有下列文件。CalculateCompilePara.mak:计算各种CPU的编译参数,包括字节序和编译器的路径等。CheckParam.mak:输入参数的合法性检查。CpuCompileOptionConfig.mak:配置各种CPU的编译选项。DivisionPlatCompileControl.mak:用于配置编译平台或者事业部的选项。LinkMultiCPUBoard.bat:用于有多个CPU时对每个CPU连接可执行文件。LinkOneCPUVersion.mak:用于连接特定序号的CPU的可执行文件。Makefile:顶级makefile,被makenet.bat调用,用于编译所有的网元的所有单板。MakeNet.bat:编译网元的批处理文件。MakeOneCpuType.mak:用于支持多种CPU子卡的编译MakeOneNet.mak:被makefile调用,用于编译一个指定网元的所有单板。MakeSubsystem.mak:用于编译指定的子系统NetCommon.mak:调用RunMake.bat完成对一块单板的编译,并提供对单个子系统进行编译时的入口。PlatCfg.mak:平台的配置文件,其中配置了平台支持的物理板、逻辑板、CPU等。PlatLink.mak:链接文件。Pub.mak:调用相关子系统的makefile,以便进行编译。RunMake.bat:完成对Tornado路径的自动切换,并且调用Pub.mak开始编译。VersionInfoConfig.mak:用于配置版本的信息,包括版本的路径以及版本号等。子系统级(以支撑为例)在./code/oss目录下,有下列文件。OssCfg.mak——支撑子系统的配置文件。Oss.mak——支撑子系统的顶级makefile。对于支撑的各个子模块,各有一个以后缀名为.mak的文件,负责自身文件的编译过程。一共包含下面几个文件:./code/pub/pub.mak——平台级公用部分。./code/oss/Common/Common.mak——子撑子系统对内的公用部分。./code/oss/File/File.mak——文件子模块./code/oss/Device/Device.mak——设备子模块。./code/oss/Excep/Excep.mak——异常子模块。./code/oss/Comm/Comm.mak——通信子模块。./code/oss/Mem/Mem.mak——内存子模块./code/oss/Pub/Pub.mak——支撑子系统对外的公用部分。./code/oss/Sche/Sche.mak——调度子模块。./code/oss/SDL/SDL.mak——SDL子模块。./code/oss/Timer/Timer.mak——定时器子模块。./code/oss/VOS/VOS.mak——Vos子模块。平台makefile的调用方式这里以UPCF单板、OSS子系统、COMMON子模块为例进行说明。假设我们要编译UPCF单板的OSS子系统,最终生成名为Oss_SubsysEx.o的目标文件。程序目录已被映射为X:盘。TornadoforArm已安装在D:\Tornado\Arm目录下。进入X:\Project目录,调用tenv.bat参数为arm设置相应的环境变量;进入X:\project\PCF\mnic\upcf目录,调用make.exe参数为Oss开始编译;make自动搜索到当前目录下的makefile文件,开始执行编译;makefile除设置版本、CPU、单板等变量外,包含进../../PlatNetelementCfg.mak等文件;PlatNetelementCfg.mak除设置网元变量外,包含进

$(_PROJECT_PATH)/netcommon.mak文件;netcommon.mak计算CPU的数量,并通过命令的方式执行

$(_PROJECT_PATH)/MakeOneCpuIndex.mak;MakeOneCpuIndex.mak根据CPU的类型调用RunMake.bat并把所需的参数传递给该批处理;RunMake.bat执行

callmake-C%make_project_path%-fPub.mak%make_subsystem%调入Pub.mak并把子系统参数Oss传递给它;Pub.mak根据参数Oss执行相应的部分

@$(MAKE)-C$(_SOURCE_PATH)/oss-foss.mak调用程序级的oss.mak;oss.mak包含进OSS系统各子模块的makefile,其中包括COMMON子模块的common.mak;common.mak生成本模块的目标文件;oss.mak把各模块的目标文件连接成子系统的目标文件,完成编译;上面的过程中,只列出了关键步骤的主线makefile,并没有写出只作了变量设置的makefile,是为了便于描述,不致显得零乱。平台makefile同PC-lint的集成通过上节的执行过程可以看出,从第9步开始makefile由平台级转到了子系统级,真正的编译工作也是从第9步开始的,Pub.mak根据传入的参数Oss去执行相应部分,完成具体的功能。那么,首先我们来看一下Pub.mak具体结构:Default:BaseFunc…BaseFunc:MakeForce …CleanLinkFile:MakeForce …MakeForce:##BSP子系统Bsp:BaseFuncBspTargetBspTarget: …BspClean: …BspCleanAll: …##OSS子系统Oss:BaseFunc@echo开始支撑子系统的编译 $(_MAK_CONTINUE_WHEN_ERROR)@$(MAKE)-C$(_SOURCE_PATH)/oss-foss.makOssOnlyOssTarget: …OssClean: …OssCleanAll: …##SCS子系统…##DBS子系统…##SIG子系统…##BRS子系统…##MCS子系统…##OAM子系统…##PP子系统…##TEST子系统…##DivisionAppTarget…实际上,在我们上面的例子中,当执行makeOss之后,在Pub.mak里只是执行的Oss:那一段的带有下划线的代码,完成OSS子系统的编译。Pub.mak为每一个子系统都定义了若干个目标,还是以OSS子系统为例,就有:Oss、OssTarget、OssClean、OssCleanAll这几个目标,分别完成子系统的编译和生成文件的清理,其他的各个子系统都定义了同样类似的目标。前面我们讲了这么多,有makefile的原理,有平台目前makefile的结构,其实最终的目的都是为了看如何把PC-lint同makefile结合起来,完成系统代码批量检查的功能。那么,Pub.mak就是关键所在,我们可以在Pub.mak里为每个子系统增加一个目标定义来完成调用PC-lint进行静态代码分析。比如:可以为OSS子系统增加一个目标OssLint。下面将列出为增加OssLint对平台的makefile所作的修改:Pub.makOssLint: @echo开始支撑子系统的Lint $(_MAK_CONTINUE_WHEN_ERROR)@$(MAKE)-C$(_SOURCE_PATH)/oss-foss.makOssLintoss.mak#定义PCLint所需的变量(这部分设置暂时放在这)_PCLINT_PATH=E:/PCLink/x/PC.Lint.v8.00NLINT=$(_PCLINT_PATH)/lint-ntLINTOPTION=-zero-os($(subst.lob,.txt,$@))-i$(_PCLINT_PATH)/std.lntLINTOPTIONoss=$(LINTOPTION)$(_OSS_INCLUDE_PATH)#PCLint的执行入口 OssLint:$(_OSS_LINT_PATH)/Oss_SubSys_Obj.lob @echo只完成支撑子系统各模块的Lint。$(_OSS_LINT_PATH)/Oss_SubSys_Obj.lob:$(_Oss_All_Lint_Objects) @ifnotexist$(_OSS_LINT_PATH)$(MKDIR)$(subst/,\,$(_OSS_LINT_PATH)) $(LINT)$(LINTOPTION)$(_Oss_All_Lint_Objects)-oo($@) @echo输出内容为$@Common.mak#PCLint_Oss_Common_Lint_Depend+=$(addprefix$(_OSS_COMMON_LINT_PATH)/,$(subst.c,.lob,$(notdir$(_Oss_Common_All_C))))_Oss_All_Lint_Objects+=$(_Oss_Common_Lint_Depend)$(_OSS_COMMON_LINT_PATH)/%.lob:$(_OSS_COMMON_SORUCE_PATH)/source/%.c @echo开始Lint$< @ifnotexist$(_OSS_COMMON_LINT_PATH)$(MKDIR)$(subst/,\,$(_OSS_COMMON_LINT_PATH)) $(ECHO)Linting$@ $(LINT)$(OSS_LINT_CFLAGS)-u+fdi$(LINTOPTIONoss)$<-oo($@) @echoDone!OssCfg.mak#用于PCLint存放lob文件(子系统)ifeq(TRUE,$(_MAK_EXIST_MULTI_CPU))_OSS_LINT_PATH=$(_TEMP_PATH)/Oss/Lint/$(_OSS_NET_ELEMENT)/\$(subst_OSS_,,$(_OSS_VERSION_TYPE))/$(_OSS_PHYSICAL_BOARD_NAME)/\$(_OSS_LOGIC_BOARD_NAME)/CPU$(_CURRENT_CPU_INDEX)/\$(_OSS_CPU_NAME)else_OSS_LINT_PATH=$(_TEMP_PATH)/Oss/Lint/$(_OSS_NET_ELEMENT)/\$(subst_OSS_,,$(_OSS_VERSION_TYPE))/$(_OSS_PHYSICAL_BOARD_NAME)/\$(_OSS_LOGIC_BOARD_NAME)/$(_OSS_CPU_NAME)endif#用于PCLint存放lob文件(子模块)_OSS_PUB_LINT_PATH =$(_OSS_LINT_PATH)/Pub/OssPub_OSS_COMMON_LINT_PATH=$(_OSS_LINT_PATH)/Common_OSS_SCHE_LINT_PATH =$(_OSS_LINT_PATH)/Sche_OSS_COMM_LINT_PATH =$(_OSS_LINT_PATH)/Comm_OSS_TIMER_LINT_PATH =$(_OSS_LINT_PATH)/Timer_OSS_MEM_LINT_PATH =$(_OSS_LINT_PATH)/Mem_OSS_DEV_LINT_PATH=$(_OSS_LINT_PATH)/Device_OSS_FILE_LINT_PATH =$(_OSS_LINT_PATH)/File_OSS_EXCEP_LINT_PATH =$(_OSS_LINT_PATH)/Excep_OSS_VOS_LINT_PATH =$(_OSS_LINT_PATH)/Vos_OSS_SDL_LINT_PATH =$(_OSS_LINT_PATH)/Sdl#配置DEBUG或者是RELEASE版本的编译标志ifeq(_OSS_DEBUG,$(_OSS_VERSION_TYPE))_OSS_VERSION_LINT_FLAG=-D_OSS_DEBUGelse_OSS_VERSION_LINT_FLAG=-D_OSS_RELEASEendif#定义Lint的参数OSS_LINT_CFLAGS=$(LINT_CFLAGS)$(_OSS_VERSION_LINT_FLAG)#定义最上层的PCLint参数TOPLINT_COMMON_CFLAGS=$(COMMON_DEVICE_DEFINE)\-D_REENTRANT-DRW_MULTI_THREAD\$(_MAK_TORNADO_INCLUDE_PATH)#为ARM配置编译、链接选项ifeq($(_CPU_TYPE),_CPU_ARM)LINT_CFLAGS=$(TOPLINT_COMMON_CFLAGS)\-DCPU=ARMSA110endif#为每种类型的CPU都要设置,这里略过…经过上面的修改就可以通过makefile调用PC-lint进行代码的检查了(这里只是针对OSS子系统COMMON模块,其他部分类似)。它将对每一个.C文件做单元检查并生成一个目标模块.lob,这个过程中产生的所有错误、警告信息都将存入一个同名的.txt文件,并最后把相应的目标模块连接成子系统的目标模块Oss_SubSys_Obj.lob,这个过程将检查多个模块连接在一起后是否会存在问题,些处也会把产生的告警存入名为Oss_SubSys_Obj.txt的文件。需要注意的是PC-lint的所有输出文件(*.lob、*.txt)的名字都是makefile中定义的。注:lob文件(LintObjectModule)是一个C或C++模块内的外部信息的总结(二进制形式)。PC-lint能使用这些信息来和其它模块比较一致性。保存检查结果的目录如下所示:tar├─temp├─Oss├─Lint├─PCF├─DEBUG├─MNIC├─UPCF├─ARM├─Oss_SubSys_Obj.txtOss_SubSys_Obj.lobCommon├─OSS_Config.txtOSS_Config.lobOSS_Device_Cfg.txtOSS_Device_Cfg.lobOss_LogicBoardCfg.txtOss_LogicBoardCfg.lobOss_ProcessType.txtOss_ProcessType.lobOss_SubsysEx.txtOss_SubsysEx.lob平台推广方案(建议)推广使用的前提1、通过对PC-lint在一定范围的试用,形成一个全平台统一的PC-lint检查选项模板,此模板应按照PC-lint不同的告警级别进行分类,按照从低到高逐渐提高告警级别的方式,一步一步改善程序质量。2、根据不同的模板和

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论