2 Star 0 Fork 1

ethan-net/codeviz

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
GPL-2.0
WHERE DOES THIS CONTENT COMES FROM?
-----------------------------------
The website of codeviz was down today and It was difficult to find the source
code for download. I used:

https://web.archive.org/web/20150502053825/http://www.csn.ul.ie/~mel/projects/codeviz/#download

to find and download the source code you see here. The only change I made
was adding this header to this file.

README
------

This is the README for the CodeViz set of scripts. The tools are for
the creation of call graphs for C and C++ so that function flow can be
visualised. They are licensed under the GPL, see the COPYING file for details.

Introduction
------------

At some stage in everyone's programming career, they will need to read through
a lot of code written by another programmer. An important part of program
comprehension is building a picture of how the program is structured from
a high-level view and call graphs can be an invaluable aid when building
this piecture. This is particularly useful if the original programmer uses
clear function names. 

This project provides the ability to generate call graphs to aid the task of
understanding code. It uses a highly modular set of collection methods and
can be adapted to support any language although only C and C++ are currently
supported. Each collection method has different advantages and disadvantages.

Installing 
----------

cd codeviz
cp ./lib/* -rv /usr/lib/   (Or your preferred perl library path)
cp ./bin/* /usr/local/bin

Alternatively just run the scripts directly from the package bin/ directory
as the libraries can be found as long as the libs are installed in a global
perl directory or at the lib/ directory is the same level as bin/.

The graphs are rendered using dot which is part of the GraphViz project.
Install the package for your distribution or obtain it directly from
http://www.graphviz.org

Scripts
-------

genfull - Use this to generate the full call graph for a project. This will
	be quite large and probably should be pared down with gengraph. A
	number of collection methods are available but cdepn is the
	default. Run genfull --man to get a full man page. Do not bother
	putting the output full.graph through dot yourself as it is unlikely
	to be rendered within a reasonable amount of time

gengraph - This will generate a small subgraph and postscript file for a
	given set of functions. Run gengraph --man for full details

Generating cdepn Files for genfull
----------------------------------

If the full.graph for the source you are interested in have already been
created, you can skip this section. See ./graphs to see if a full.graph
is available.

The cobjdump and cppobjdump (for C and C++ respectively) will generate
adequate call graphs but the information is a bit lacking. For example,
the source file of a function declaration is unknown and macros and inline
functions will be totally missing. Ideally, the cdepn method should be used
but it requires a patched version of gcc and g++ to work. The patches and
some scripts are available in the compilers/ directory.

The patched version of gcc and g++ outputs .cdepn files for every c and c++
file compiled. This .cdepn file contains information such as when functions
are called, where they are declared and so on. Earlier versions of CodeViz
supported multiple gcc versions but this one only support 4.6.2.

First, the source tar has to be downloaded.  For those who have better things
to do than read the gcc install doc, just do the following

cd compilers
ncftpget ftp://ftp.gnu.org/pub/gnu/gcc/gcc-4.6.2/gcc-4.6.2.tar.gz
./install_gcc-4.6.2.sh <optional install path>

This script will untar gcc, patch it and install it to the supplied path. If
no path is given, it'll be installed to $HOME/gcc-graph . I usually install
it to /usr/local/gcc-graph with

./install_gcc-4.6.2.sh /usr/local/gcc-graph

If you seriously want to patch by hand, just read the script as it goes through
each of the steps one at a time. There is one step to note though.

For now, we will presume a patched version of gcc and g++ is now in
$HOME/gcc-graph/.  Most projects will use the variable CC for deciding
which version of gcc to use. The handiest way to use the patched one is with
something like

make CC=$HOME/gcc-graph/bin/gcc CXX=$HOME/gcc-graph/bin/g++

Or alternatively, adjust your path that gcc-graph will appear before the
normal gcc. As each source file is compiled, the corresponding cdepn file
will be created.

In the case of building the Linux Kernel, the commands would be;

make CC=$HOME/gcc-graph/bin/gcc bzImage
make CC=$HOME/gcc-graph/bin/gcc modules

Similar methods will work for other projects presuming that the Makefile
uses the CC or CXX macros correctly to indicate the compiler to use. If it's
a Makefile of your own type or it does not use proper macros, you may have
to edit the Makefile yourself or else adjust your path to put gcc-graph first.
For example, with bash, the following will work.

PATH=$HOME/gcc-graph/bin:$PATH

When building, watch the compiler output to make sure the .cdepn files are being
created.

Generating nccout files for genfull
-----------------------------------

An alternative to using a patched version of gcc is to use ncc
(http://freshmeat.net/projects/ncc) which is a C compiler specifically
designed for code browsing. It comes with it's own navigation tool and
is well worth checking out.

CodeViz supports ncc with the cncc collection method (just like cdepn is for
use with gcc) and supports C only. The really big thing going for the ncc
collection method is that it can traverse function pointers. If you download
and install ncc, use the cncc collection method if it is C code and function
pointers are common.

Once ncc is installed, in the case of building the Linux Kernel, the commands would be:

make -i CC='ncc -ncoo -ncfabs' bzImage
make -i CC='ncc -ncoo -ncfabs' modules
find . -name \*.nccout | xargs cat > code.map.nccout

Generating full.graph 
---------------------

Some full.graph files are provided with the tar in the downloads section. If
one you want is not available, read on.

To create a full.graph, the script genfull is used. run genfull --help to see
all options but the easiest thing to do is run the script with no arguments
in the top level source directory after a compile and a file full.graph will
be created in the top level source directory. 

While it should be possible to put full.graph though dot and see the postscript
file, it is recommended you do not try. A full graph is extremely large and
unlikely to be rendered in a reasonable amount of time. One really should
use the gengraph program to create smaller graphs.

Problems that might exist with full.graph
-----------------------------------------

In more complex code, the full.graph may not be perfect. For example, there may
be naming collisions where there is duplicate function names between modules or
if there is multiple binaries being compiled, genfull will not distinguish
between them. If you think this will be a problem, there is two steps you can
make.

First, compare the graph generated by cdepn with the one generated by
cobjdump. As cobjdump is analysing a binary, it is highly unlikely the graph
is wrong, it just will have no information on inline functions or macros. With
the linux kernel, this test would look something like

genfull -g cobjdump -o full.graph-objdump
genfull -g cdepn -o full.graph-cdepn
gengraph -t -d 5 -g full.graph-objdump  -f kswapd -o kswapd-objdump.ps
gengraph -t -d 5 -g full.graph-cdepn -f kswapd -o kswapd-cdepn.ps

This would generate two full.graphs and two call graphs of the function
kswapd() which could be compared to make sure the cdepn graph is accurate. A
similar method can be used for other projects.

The second problem that may occur is where function names are duplicated
between modules. In this case, the best course of action is to use the -s
switch to genfull to limit which branches of the tree are examined. For
example, in the linux kernel there is an alloc_pages() function in mm/ and
drivers/char/drm . If one was examining the VM alone and naming collisions were
expected to be a problem, genfull could be invoked as

genfull -s "mm include/linux drivers/block arch/i386"

which would cover most of the functions of interest. In other projects, it will
be a case of different libraries colliding with each other. For instance, with
avifile, genfull with no arguments will create a horrible mess. Instead, the
-s switch must be used to generate a full.graph for each part of the project.
For example, the player would be graphed with

genfull -s "player" -o full.graph-player

and each of the libraries would be graphed separately.

Generating Call Graphs 
----------------------

The script gengraph generates a call graph for a specified function based on
the full.graph file. gengraph --man will provide all the information you need.
The most important switch to note is -g which determines what collection method
to use. Once the script completes, a postscript file will be available which
can be viewed with any postscript viewer. By default, the output filename will
be functionname.ps

If it takes a long time to generate a graph, it is usually a good idea to first
limit it's depth to something reasonable with -d . We'll take an example of
graphing alloc_pages() with kernel 2.4.20

Step 1: gengraph -f alloc_pages
Result: Taking way too long, hit ctrl-c and limited by some reasonable depth to
get an idea of what was happening

Step 2: gengraph -d 10 -f alloc_pages
Result: Output graph is massive, mainly with kernel stock functions of no
interest. Use the -t switch to omit functions that are usually of no interest.
For other projects, edit the gengraph script and go to the line "sub
generate_trimlist", this function has a list of functions to "trim" with the -t
switch is used

Step 3: gengraph -t -d 10 -f alloc_pages
Result: Output graph is still massive but a glance at the graph shows that a
call to "shrink_cache()" is resulting in a massive graph below it that does not
look like it is directly related to page allocation. Lets just show that
function but not traverse it with the -s switch

Step 4: gengraph -t -d 10 -s "shrink_cache" -f alloc_pages
Result: Graph size is drastically reduced. Most of the remaining graph
involves two functions "try_to_free_pages_zone()" and "__free_pages_ok". We'll
not traverse try_to_free_pages_zone() and will ignore __free_pages_ok()
altogether with the -i switch

Step 5: gengraph -t -d 10 -s "shrink_cache try_to_free_pages_zone" -i
"__free_pages_ok" -f alloc_pages
Result: Perfect, shows a nice graph which clearly shows what the important
functions are in relation to just page allocation. Later the branches that were
not traversed in this graph can be graphed separately

The bottom line is that the first graph is usually too large and needs to be
cut down. How to pare it down in a combination of experience with the code
and common sense. I find it usually helps to just limit the depth first by
4 and start ignoring functions that are obviously not of current interest
and traverse them later

Generating Graphs based on Regular Expressions
----------------------------------------------

Support is available for selecting functions to graph, show and ignore based
on regular expressions. The format of the expression is the same as perl 
except without the //'s. For example, to generate a graph that d
that look like an alloc function in the kernel, this would work

gengraph -t -d 4 --func-re "^.?.?alloc(_page)?$" -i "pmd_alloc" -o allocs.ps

Note that with --func-re in particular, it is important that you use the -o
switch or dot will fail to create a graph with complaints about bad output
filenames.

Post-Processing Options
-----------------------

Both genfull and gengraph support the use of post-procesing steps. Currently,
two are supported. The first is stack usage by a single function.  This is x86
specific as it depends on object files regardless of the collection method
used. This is mainly of benefit to the Linux kernel as normal applications
can expand their stack and do not need to worry about stack usage as
much. The second module shows cumulative usage in gengraph between pairs of
functions. This is really handy for showing the usage between a system call
and a lower-level function to identify places where stack is used too much.

See the man pages for genfull and gengraph for more information on the use
of the post-processing options.

Daemon/Client Support
---------------------

With a large input graph, the longest operation for the generation of the call
graph is the reading of the input file. To compare, to generate a small graph
on the authors machine, it takes 4 seconds to read the input graph and 0.1
seconds to generate the output file. To address, this, gengraph can run as a
daemon if the -q (--daemon) switch is specified. Use -v if you want to see what
it is doing.

	gengraph -q -g /usr/src/linux-2.4.20-clean/full.graph

When this returns, the daemon is running. To generate a graph using the daemon,
run
	gengraph -q -t -d 2 -f alloc_pages

Note the use of the -q switch which says that gengraph should run as a client
to the daemon instance. If you are bored, compare the difference in running
times between normal gengraph and when it is used as a client :-) . To stop
the daemon, do the following

	echo QUIT > /tmp/codeviz.pipe

and the daemon will shutdown and cleanup.

Generating Graphs for the Web
-----------------------------

Gengraph is now suitable for use with CGI scripts. To generate GIF output 
instead of postfix, use the -w switch. How you choose to implement is up
to yourself but what I did was the following

o Have CGI script call gengraph to output GIF to /tmp
o In the HTML, have <img src=/cgi-bin/readgif?output.gif>

Where output.gif is actually some temporary file in /tmp created by the CGI
script with a unique name and readgif is a simply exectuable which reads
GIFs from /tmp and then unlinks them.

There is no demo of this available because the webserver which hosts this 
project is a bit loaded. While I could run a demo, my popularity would take
a bit of a dent.

There is also support for generating HTML files with source-highlight if you
have it installed. See the detailed manpage for the --shighlight option for
more details.

Misc Notes
----------

Reports of success or failure, especially with C++, using any of the collection
methods are appreciated.

Bugs and Feedback 
-----------------
Email any comments, feedback and bug reports to mel@csn.ul.ie. Enjoy.....

Credits
-------

The vast majority of this has been implemented by Mel Gorman
<mel@csn.ul.ie>.  However, the diff to gcc and original cdepn.pl that
this project was originally based on was written by Martin Devera (Devik)
(http://luxik.cdi.cz/~devik). They have since changed considerably to support
other languages and be more flexible but the original idea was his, thanks
Martin. Encouragement and prodding to support ncc is courtesy of the author
of ncc Xanthakis Stelios (sxanth@ceid.upatras.gr). The main guts of the 
implementation of the regular expression support and HTML rendering is
courtesy of Robert Lehr (bozzio@the-lehrs.com).
GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. <one line to give the program's name and a brief idea of what it does.> Copyright (C) 19yy <name of author> 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. <signature of Ty Coon>, 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License.

简介

暂无描述 展开 收起
GPL-2.0
取消

发行版

暂无发行版

贡献者

全部

近期动态

不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/ethan-net/codeviz.git
git@gitee.com:ethan-net/codeviz.git
ethan-net
codeviz
codeviz
master

搜索帮助