The Kopi Project is a Java software project from DMS which provides a framework for developing database applications using Java, JDBC and SWING.
Kopi contains a set of tools which allow you to edit and generate classfiles: dis (Java disassembler), KSM (Java assembler) and KJC. KJC compiles Java source code to bytecode, with all the same plus even more features as commercial compilers. KJC is available for free under the terms of the GNU Public License.
The Kopi Project also includes XKJC, a compiler for embedded SQL in Java. Built over JDBC, it allows the execution of Java-typed SQL statements and the mixing of expressions from both SQL and Java.
The last tool provided by DMS is Visual Kopi. Visual Kopi is an application framework using JDBC and JFC/Swing which lets you create database applications in a high level specification language. It also provides the ability to write triggers and commands in Java with seamlessly embedded SQL statements.
This documentation is divided into chapters independant of each other:
CHAPTER 1
- The Kopi Classfile: Kopi classfile is an extensible package written completely in Java that allows you to read, edit and write classfiles. It is used by KJC (Java compiler), KSM (Java assembler) and DIS (Java disassembler).
CHAPTER 2
- KJC - The Kopi Java Compiler: KJC is the first compiler written completly in Java, available under the terms of the GNU General Public License. It allows you to extend features at any level, from syntax to code generation.
CHAPTER 3
- XKJC - The Kopi EXtended Java Compiler: XKJC is a compiler for embedded SQL in Java. This language is a super set of Java; i.e., it is compatible with Java source code. This allows the execution of Java-typed SQL statements and the mixing of expressions from both SQL and Java.
CHAPTER 4
- VLIB - The Visual Kopi: VLIB is an application framework using SWING which lets you create database applications in a high level specification language.
The actual Kopi Team:
In addition of these persons, several people have written parts of Kopi:
Others contributors (bug reports, suggestions) are:
A special thanks to Rebecca KELLEY for her assistance in the preparation of this document.
All grammar of KJC tools are specified in ANTLR language. ANTLR, ANother Tool for Language Recognition, (formerly PCCTS) is a parser and translator generator tool, akin to the venerable lex/yacc duo, that lets you construct recognizers, compilers, and source-to-source translators from grammatical descriptions containing C++ or Java actions. You can build translators for database formats, graphical data files (e.g., PostScript, AutoCAD), text processing files (e.g., HTML, SGML), etc.... ANTLR is designed to handle all of your translation tasks. ANTLR is recommended by the co-inventor of LL(k) parsers and by the inventor of SLR(k) and LALR(k).
Home page:http://www.antlr.org.
The GNU Java getopt classes support short and long argument parsing in a manner 100% compatible with the version of GNU getopt in glibc 2.0.6 with a mostly compatible programmer's interface as well. Note that this is a port, not a new implementation. I am currently unaware of any bugs in this software, but there certainly could be some lying about. I would appreciate bug reports as well as hearing about positive experiences.
Home page:http://www.urbanophile.com/arenn/hacking/download.html.
Mauve is a project to create a free Java test suite. This package will both serve as a library regression test suite and test conformance to various Java specification levels.
Home page:http://sourceware.cygnus.com/mauve/.
Kopi classfile is an extensible package written completely in Java that allows you to read, edit and write classfiles. It is used by KJC (Java compiler), KSM (Java assembler) and DIS (Java disassembler).
This list shows typical tools that may be built with Kopi Classfile:
This package allows you to edit classfiles and to check and optimize instructions in an elegant way. Generated code from "normal input" is in the same order of size and speed as thus generated by other commercial compilers such as Javac or jikes. Applied optimisation is mainly peephole optimisation and has also faster bytecode replacement and switch selection capabilities. And last but not least, this package is able to compute the stack's depth and the number of local variables used by each method.
There are two main sections in this chapter:
The description of the tools in Kopi Assembly Language (See Kopi Assembly Language.)
- An assembly language for the Java classfile format. Two tools are available:
The documentation for the disassembler in The Kopi Disassembler (DIS) (See The Kopi Disassembler.)
- A Java disassembler that allows one to read and edit a classfile in kopi-assembler.
The documentation for the assembler in The Kopi Assembler (KSM) (See The Kopi Assembler.)
- A Java assembler used to write classfile from kopi-assembler.
The description of the API in Kopi Classfile API (See Kopi Classfile API.)
- The package classfile itself, that allows one to handle Java code generation from within an other Java application without worrying about code optimization, stackand local variable handling, code checking and constant pool optimization.
The core API in Read a classfile (See Read a classfile.)
- An API for embedding Java code generation in other tools.
The performed optimizations in Pluggable Bytecode optimizer (See Pluggable Bytecode optimizer.)
- An in depth report about performed optimizations.
The syntax was designed to be both readable and fully functional (It keep a total power of expression). The primary goal was to let the assembler (the classfile API) do as much work as possible, making for example unnecessary to specify the maximum amount of stack used or the number of local variables, since this information can be deduced from the program to assemble. The instructions opcodes are limited to the strict minimum, and all the instructions defined to optimize a program (such as load_1) will be replaced by the assembler from generics instructions (from load 1).
The file structure is similar to a Java compilation unit. The syntax looks like a normal Java program for the member's definition. Only the method body is described in assembler. Some special information found in classfiles such as LineNumberTable, LocalVariableTable and attributes are also defined in the method body, but all of this information is optional.
The code of methods is pure Java assembler as defined at http://java.sun.com/docs/books/vmspec/2nd-edition/html/Instructions.doc.html.
The easiest way to understand Kopi assembler is to look at an example or to decompile your own classes with DIS.
Example
// compiler version: 45.3 @source "HelloWorldApp.java" class HelloWorldApp extends java.lang.Object { /** * main * * @stack 2 * @locals 1 */ public static void main(java.lang.String[]) { @line 3 @getstatic java.io.PrintStream java.lang.System.out @const "Hello World!" @invokevirtual void java.io.PrintStream.println(java.lang.String) @line 2 @return } /** * init * * @stack 1 * @locals 1 */ void init() { @line 1 @aload 0 @invokespecial void java.lang.Object.init() @return } }
To launch KSM from the command line, type
java at.dms.ksm.Main
The command line parameters are:
java at.dms.ksm.Main [dhV] file.ksm+ usage: at.dms.ksm.Main [option]* [--help] files.ksm --destination, d _: Sets the destination directory --help, h: displays the help information --verbose, v: Displays information while processing files [false] --version, V: prints out the version information file: the files to assemble
This tool allows you to see the code actually generated by your compiler and may help you to optimize or understand a portion of the code. This tool may also help you modify some classes from their bytecode in conjunction with KSM(to regenerate them).
To launch KSM from the command line, type:
java at.dms.dis.Main
The command line parameters are:
java at.dms.dis.Main [cdhisxV] (file.class | class)+ --classpath, p _: Sets the classpath --destination, d _: Sets the destination directory --help, h: displays the help information --inter, i: Only displays the interfaces of classes [false] --sorted, s: Prints fields and methods sorted [false] --stack, x: Prints stack information [false] --stdout, c: Prints on the standard output [false] --verbose, v: Displays information while processing files [false] --version, V: prints out the version information class: a class (fully qualified name) accessible from the current classpath
This package contains the API to edit classfiles from within a Java program. If you want to read or write classfiles in a human readable form, you should use KSM and DIS which offer an interface to classfile.
Basically, this package contains three parts: one to read data from a file, one to create a consistant class from another program, and a third part to check the code of each function (compute stack and local variable usage, and optionnally optimize code) and then dump the class into a file.
You just have to create a ClassInfo from a file:
ClassInfo clazz = new ClassInfo(new RandomAccessFile(``AClass.class''), false);
or with its full name and a class path using the provided class ClassPath:
ClassPath path = new ClassPath(``.''); ClassInfo clazz = path.getClassFile(``pack.AClass'', true); // rmq: the last parameter allows you // to load only the interface (skip code)
Once you've read your class, you can access all the information you need from the provided API such as getName(), getSuperClass(), getMethods(), getSourceFile(). If you have loaded an entire class (not only the interface), you'll be able to change some information (the source file, the name, some modifiers...) and then to dump it to file again.
You can create a class from scratch and then add all the attributes and members you want. See KSM or KJC for a real example of usage.
You can edit your class using the provided API:
ClassInfo clazz = new ClassInfo(new File(``AClass.class''); clazz.setName(``BClass'');
After you have built or edited the instructions, you can check and optimize the code:
// obtained from any non empty method CodeInfo code = clazz.getMethods()[0]; // 2 is the number of optimization loop, 0 for none code.optimizeAndCheck(2)
The main check is to ensure that the stack depth is correct for every branch in the program. We may add later some verifications made by the Java Verifier at runtime.
After you have built or edited a ClassInfo, you can dump it into a file with:
ClassInfo clazz = new ClassInfo(new File(``AClass.class''); clazz.setName(``BClass'') clazz.write(new DataOutputStream(new FileOutputStream(``BClass.class'');
This simple example sets all methods to be public in the class passed as argv[0] and writes this new class in a file argv[1]
/** * This simple example set all methods to * be public in the class passed as first * parameters and write this new class in a file argv[1] */ import at.dms.classfile.*; import java.io.*; public class Editor implements Constants { public static void main(String[] argv) throws at.dms.classfile.ClassFileFormatException, java.io.FileNotFoundException, java.io.IOException { DataInputStream is = new DataInputStream(new FileInputStream(argv[0])); ClassInfo clazz = new ClassInfo(is, false); MethodInfo[] method = clazz.getMethods(); for (int i = 0; i < method.length; i++) method[i].setModifiers(toPublic(method[i].getModifiers())); clazz.write(new DataOutputStream(new FileOutputStream(argv[1]))); } private static short toPublic(short modifiers) { return (short)((modifiers | ACC_PUBLIC) & ~(ACC_PROTECTED | ACC_PRIVATE)); } }
This is a list of non restrictive possible tools to build with this package:
There are two fully implemented examples that come with Kopi suite:
This is a small example to show how a "high level" assembly language is translated into Java bytecode. This example is very small (10 classes) and is a good starting point for learning how the classfile package works. KSM is composed of a parser that reads ".ksm" files and some subclasses of classfiles for handling assembler labels and jumps. KSM syntax is easy because you don't have to use the most optimized pseudo-instruction in your code, you can use generic instruction that classfile will optimize afterwards.
By example if you use "push 1" to push the constant one into the stack, classfile will translate this instruction to "iconst_1", which is smaller and faster. Another feature of KSM is that you don't have to compute the amount of stack used, or the number of local variables; the classfile package will do it for you.
This is a big example (160 classes) that shows how to use the classfile package as a back end for a compiler. Classfile was first designed as a part of KJC, but because this package may be used for other purposes, it has been separated from the compiler. That makes the code easy to handle and improve.
It is also very easy to create a classfile optimizer. We will soon provide a minimalist code optimizer that can read every classfile provided and generates optimized versions in the destination directory. Our optimizer will be used only for testing purpose and won't do anything more than:
But it would be very easy to transform it to a true obfuscator/optimizer by collecting used fields and methods and renaming every member of class to the smallest size possible.
It is very easy to build a disassembler over Kopi classfile by accessing every information in the classfile with the provided API. An example of such a disassembler, DIS, is provided with the Kopi suite. It converts classfile in a syntax that is understood by KSM. That allows you to disassemble a classfile, modify some code, and then regenerate the classfiles. Our disassembler is very small also but powerful enough to disassemble every classfiles into KSM syntax. And, if you want to disassemble classfiles in another syntax, you just have to subclass the AssemblerPrettyPrinter.
From the classfile assembler, it is all the same to generate Java byte code or C. The problem of such tools is to provide a gc and a window toolkit. but it should not be to difficult to create a tool that compiles natively command-line Java programs.
A useful tool based on the Kopi classfile may be a cross reference analyser.
This chapter explains which optimisations are provided by the bytecode optimizer. These optimizations are:
This tool allows you to optimize a classfile or a complete directory using the optimizer engine of kjc on already generated classfiles. This tool exists mainly for testing purpose.
To launch optimize from the command line, type:
java at.dms.optimize.Main
The command line parameters are:
java at.dms.optimize.Main (file.class | directory)+ --help, h: displays the help information --level, l _: Level of optimization [2] --verbose, v: Displays information while processing files [false] --version, V: prints out the version information class: a class (fully qualified name) accessible from the current classpath
Unreachable code is simply removed from the CodeInfo. And
instructions
are removed if they are not targeted in a method.
This is the current list of peephole optimization performed by KJC:
goto L1 L1: ... => ...
... ifeq L1 L1: ... => ... pop[2] ...
... opc_goto L1 ... L1: goto L2 => ... goto L2 ... L1: goto L2
... goto L1 ... L1: ireturn => ... ireturn ... ireturn
iconst_0 ifeq L1 ... L1: ... => ... L1: ...
or
iconst_[0, 1, null] if_icmpeq L1 ... L1: ... => ifeq L1 ... L1: ...
KJC is the first compiler written entirely in Java and available under the terms of the GNU Public License. It allows you to extend features at any level from syntax to code generation (By example by adding support for generic type). It is very easy to add features and to maintain this compiler, and we hope that a large comunity of Java developers will help us bring it to a level of efficiency comparable to others commercial compilers.
One of the major advantage of a Java compiler written in Java is that it can be called from an other Java program and that then the output can be executed via dynamic loading. This compilation is executed without overhead and is then quite fast. Thus, you can use KJC to dynamically recompile portions of your program to a fully optimized version for a target only known at runtime. And this without breaking the "Write Once, Run Anywhere" benefit of Java.
KJC is not the first freely available Java compiler but it provides some new features not previously available. These features are:
Since KJC is a GNU a project, it is easy to improve by sending us patches or suggestions. Since it is maintained by a small team of engineers, the development cycle of new releases is far shorter than the JavaC one.
There are mainly two other compilers for Java freely available: Javac and jikes. Javac is error-proof and has a role of reference, and jikes is extremly fast. This table shows the differences between these two compilers and KJC:
Feature | Javac | Jikes | KJC
|
License model | Community Source Code | Jikes Public license | GNU Public License
|
Language | Java | C++ | Java
|
Supported platform | All platforms with a Java VM | Almost all | All platforms with a Java VM
|
Speed | Slow | Very fast | -
|
Extendability | Poor | Poor | Good
|
Generated code | Good with -O | No optimizations | -
|
Auditing | No | Poor with -warning | Still at an early level
|
KJC is distributed under the term of a GNU public license and thus can be integrated freely in any other GNU project. The source code is part of the standard distribution and will help you understand the behavior of the program. It will also allow you to extend it.
This Java compiler written in Java is easily extensible. We have developed a lot of tools over KJC like XKJC and VKJC. These tools generates classfiles without any knowledge of the underlying Java bytecode convention (Stack size, verifier convention, ...).
An auditing tool helps you follow the Java code convention and avoid common errors that can be easily detected by a compiler. We have started to extend KJC with warnings to enforce the respect of this convention. This part of KJC is still in an early development stage, but will be our main focus for the next release (1.4). See: <XREF LINKEND="REF-ELEMENT">
KJC can read a .Java file and rewrite it following the Java Code Conventions. This can be useful when you get some source files from someone else and want to convert them into something readable. It is also useful for tools extending KJC to generate 100% pure Java code.
The code generation is based on at.dms.classfile and at.dms.optimizer. This last package is focused on bytecode optimization and will be improved in the next release. It already supports multi-pass optimizations, dead code removal and peephole optimization.
Once you have added kjc.zip in your CLASSPATH
you can launch
KJC by typing the following command at the prompt:
%java at.dms.kjc.Main
The command line options currently supported by KJC are (KJC -help):
--beautify, -b: Beautifies the source code [false] --classpath, -C[String]: Changes class path to classpath --debug, -g: Produces debug information (does nothing yet) [false] --deprecation, -D: Tests for deprecated members [false] --destination, -d[String]: Writes files to destination --filter, -f[String]: Warning filter [at.dms.kjc.DefaultFilter] --help, h: Displays the help information --java, -j: Generates java source code instead of class [false] --lang, -l[String]: Sets the source language (1.1, 1.2, kopi) [1.1] --multi, -m: Compiles in multi threads mode [false] --nowrite, -n: Only checks files, doesn't generate code [false] --optimize, -O[int]: Optimizes X times [1] --proc, -p[int]: Maximal number of threads to use [2] --verbose, -v: Prints out information during compilation [false] --version, V: Prints out the version information --warning, -w[int]: Maximal level of warnings to be displayed [0]
This new feature of KJC helps to enforce Java coding standard and to avoid most common bugs by providing useful warnings about your code. This warnings are referenced at the end of this documentation and are fully configurable.
This is our first step in this direction and we are looking forward to add new checks as they come from contributors. So feel free to send us remarks and suggestions about this new feature in order to help us to build a powerful tool.
The rules come from the JLS, Sun's "Java Coding Convention", and several other sources and are based on our experience.
May be the best way to use the diagnostic messages of KJC is to turn ON all warnings and maintain the source code free of them. But you may not agree with our coding convention and you have then the possibility to define a warning filter for your own needs. If you want to use KJC on an existing program that doesn't follow our coding convention (or worse the one from Sun) you will receive tons of warnings and it won't be helpful at all. In this case you can set the minimal warning level with the -w switch to only check your code against worst common failures.
In the next release we may add a -Wxxx option to select a warning subset.
There are five levels of warning:
This portion of code is surely wrong but accepted by the language.
It may be something like: ((String)null).toString();
This portion of code is correct but can lead to a more global failure.
For instance because a variable is declared but never used or a variable is assigned to itself.
This portion of code is syntaxically dirty or potentially dangerous.
Like a then statement without brace or missing default label in switches.
All other warnings.
Everything that enforce our coding standard.
Other information about the code that are not specifically focused on error search but rather on code beauty.
Like unordered modifiers, usage of package/protected fields or usage of package import instead of class import.
One can select the level of warning to be displayed with the -w switch. The default value is 0 and -warning without parameter sets it to 3.
One can write his personal warning filter by calling kjc with the switch -filter XXX where XXX is the name of a class which extends at.dms.compiler.WarningFilter and is accessible on the CLASSPATH. An example of such a filter is the default filter for KJC:
public class DefaultFilter implements at.dms.compiler.WarningFilter { // ---------------------------------------------------------------------- // FILTER // ---------------------------------------------------------------------- /** * Filters a warning * @param warning a warning to be filtred * @return FLT_REJECT, FLT_FORCE, FLT_ACCEPT */ public int filter(CWarning warning) { if (warning.getDescription().equals(KjcMessages.UNUSED_PARAMETER) || warning.getDescription().equals(KjcMessages.CONSTANT_VARIABLE_NOT_FINAL) || warning.getDescription().equals(KjcMessages.UNUSED_CATCH_PARAMETER)) { return FLT_REJECT; } else { return FLT_ACCEPT; } } }
For each warning, this method select whether it should be:
Displayed in every case.
Hidden in every case.
Displayed if the level is lower than the minimal warning limit and not filtered by the default filter of KJC.
The list of warnings is available at the end of this documentation in the reference section<XREF LINKEND="REF-ELEMENT">.
The next release (1.5) will have the following features:
Java with embedded SQL
Our company developes database application written in our own specificatin language (that may be after distributed with a GPL licence). This language allows developer to define triggers and actions in the XKJC language that is a superset of Java with embedded SQL. XKJC allows the mixing of Java-typed expression from both SQL and Java.
Since SQL statements are parsed, it allows one to write a very clear code as compared to JDBC (see XKJC vs JDBC section). It allows onr to make requests with embedded Java expressions computed at runtime. It comes with a support for BLOB and Java serialisation mechanism, allowing to store Java objects in any JDBC database and to retreive them both nicely and efficiently.
As in SQL all types have a NULL value, the distinction between primitive types and Object types of the Java language are problematic. To handle this, XKJC contains an operator overloading capability that allows the mixing of primitive types with objects.
The mechanism of overloading looks like the one provided by C++ compiler except that only expression operator are overidable (+, -, *, /, %, ==, !=, &, |, << >>, >>>, ^, ~, ++, -) and the cast operation. There is no implicit conversion, and that make it easy to understand.
There is an example of a typical XKJC programme:
#cursor(int id) { SELECT Vector Obj FROM BLOBS WHERE ID = :id } typed; typed.open(6); if (typed.next()) for (int i = 0; i < typed.Obj.size(); i++) System.out.println("vect(" + i + "): " + typed.Obj.elementAt(i)); typed.close();
KJC allow you to unspecify names of parameters in method definition if they are not used:
void foo(int); // a non used paramter name would have generated a warning
A mechanism of assertion is very useful for debugging and testing a program but slighty inefficient for a final release. KJC provide a simple mechanisme of assertion that is removed when -O option is checked.
we introduce a new method #assert that check a condition is verified:
void foo(int i) { #assert(i>0); // or #assert(i>0, ``a message''); } can be translated in Java as: void foo(int i) { if (!i>0) throw new new RuntimeException(); }
we introduce a new method #fail that correspond to a check(false) expression:
void foo(int i) { if (i > 0) A(); else #fail(``Bad value''); // or #fail(); }
can be translated in Java as:
void foo(int i) { if (i > 0) A(); else throw new RuntimeException(``Bad value''); }
not yet documented, but you can take a look in the oper folder of XKJC sources.
By providing an easy way to include SQL statement inside your Java code (not between double quote), XKJC made it more easy to read and maintain. With explicit typing the compiler check that expression are correct and involve the overloading mechanism to execute expression such as:
By providing explicit connection to SQL statement you are able to work on more than one database at the same time. But since common applications work with only one database, we provide a mechanism of implicit transaction that allows to save time by wrinting:
#execute{SELECT COUNT(*) FROM Cars INTO count};
instead of:
#execute[Main.getDatabase().getFreeConnection()] { SELECT COUNT(*) FROM Cars INTO count };
The cursor are the common way to get more than one row of data from the database. It's like ResultSet but it's typed:
The only SQL statement in XKJC is the #execute that allow to fetch data from the database with a "SELECT INTO".
Examples:
- #execute { SELECT String name, Image image, BigDecimal speed FROM Cars WHERE ID = 1 INTO theName, theImage, theSpeed };
- #execute { SELECT String name FROM Cars WHERE ID =:id INTO names[id] };
- #execute[conn] { SELECT COUNT(*) FROM Cars INTO count };
The last example use an explicit connection while the others use an implicit connection (ie, the context should inherit from DBContextHandler and its default connection will be used).
SQL expression returns an int value that correspond to the number of row modified by the expression. An expression can use a cursor to identifie a row of the database (WHERE CURRENT OF) with fully implemented JDBC drivers.
Examples:
- #update { UPDATE Cars WHERE ID =:id SET name = :(javaName + '-' + id) };
- #update(cursor) { UPDATE Cars SET name = :(javaName + '-' + id) };
- #update [conn] { DELETE FROM Cars WHERE :id > 10 };
The last example use an explicit connection while the others use an implicit connection (ie, the context should inherit from DBContextHandler and its default connection will be used).
Every SQL statements should be executed within transaction. This allows to reexcute statements interupted by deadlock (after asking the user if he wants to) or abort a whole transaction if something is wrong (like if a Java exception is thrown). The syntax is:
#protected([``an optional message'']){ ... ... // a list of Java and SQL statements ... };
If an exception is thrown during execution of this block, the current transaction is aborted, else it commited. A way to handle deadlock is provided.
The main thing that is missing here is a program that checks the definition of database types provided by the programmer against the database. This could be realized with the metadata subsystem of JDBC, but this is for a future version. There is also no way to create table or meta data in the database, since XKJC is intended only to DML SQL (Data Manipulation Language).
Visual Kopi...
Other tools developed for the Kopi project...
To launch Optgen from the command line, type
java at.dms.optgen.Main
The command line parameters are:
java at.dms.optgen.Main file.opt+ no options
The goal of this tool is to generate a command line option controller (based on gnu.getopt) from a description file.
To launch Msggen from the command line, type
java at.dms.msggen.Main
The command line parameters are:
java at.dms.msggen.Main file.msg+ no options
The goal of this tool is to generate a class with messages from a description files.
To launch Lexgen from the command line, type
java at.dms.lexgen.Main
The command line parameters are:
java at.dms.lexgen.Main file.t+ no options
The goal of this tool is to generate a perfect hashtable function and corresponding tokens for a specified list of keywords.
To launch Memcnt from the command line, type
java at.dms.memcnt.Main
The command line parameters are:
java at.dms.mamcnt.Main classfile --help, h: displays the help information --verbose, v: Displays information while processing files [false] --version, V: prints out the version information
The goal of this tool is to instrument a classfile to count every new objects created during runtime.
To launch MKJC from the command line, type
java at.dms.mkjc.Main
The command line parameters are:
java at.dms.mkjc.Main file.macro --beautify, -b: Beautifies the source code [false] --classpath, -C[String]: Changes class path to classpath --debug, -g: Produces debug information (does nothing yet) [false] --deprecation, -D: Tests for deprecated members [false] --destination, -d[String]: Writes files to destination --filter, -f[String]: Warning filter [at.dms.kjc.DefaultFilter] --help, h: displays the help information --java, -j: Generates java source code instead of class [false] --lang, -l[String]: Sets the source language (1.1, 1.2, kopi) [1.1] --multi, -m: Compiles in multi threads mode [false] --nowrite, -n: Only checks files, doesn't generate code [false] --optimize, -O[int]: Optimizes X times [1] --proc, -p[int]: Maximal number of threads to use [2] --verbose, -v: Prints out information during compilation [false] --version, V: prints out the version information --warning, -w[int]: Maximal level of warnings to be displayed [0]
The goal of this tool is to generate AST from a comprehensive java-like syntax.
To launch lpr from the command line, type
java at.dms.lpr.LpR java at.dms.lpr.LpQ java at.dms.lpr.LpRm
The command line parameters are:
java at.dms.lpr.LpR file+ --bindSourcePort, -B: Binds the source port [false] --copies, -#[int]: Sets the number of copies to print [1] --dataFirst, -D: Sends data first (for old NT lpd servers) [false] --filetype, -f[String]: Sets the file type --help, h: displays the help information --indent, -i[int]: Sets the indent size [-1] --job, -J[String]: Sets the job identifier --localHost, -L[String]: Sets the local host [localhost] --mail, -m: Mails when job is done [false] --noBurst, -H: Suppresses the burst page [false] --printClass, -C[String]: Sets the print class --printHost, -H[String]: Sets the print hosts [localhost] --proxyHost, -X[String]: Sets the proxy host to use (UNIX) --queue, -P[String]: Sets the queue to work on --remotePort, -d[int]: Sets the remote port [-1] --remove, -r: Removes the file when printing is done [false] --sourcePort, -s[int]: Sets the source port [-1] --timeout, -t[int]: Sets the timeout value in millisc [60000] --title, -T[String]: Sets the title for the job --tmpdir, -t[String]: Sets the tmp dir to use [/tmp/] --user, -u[String]: Sets the user who invoked the command --version, V: prints out the version information --width, -w[int]: Sets the page width [-1] --windows, -W: Uses a windows style protocol to communicate with the server [false] java at.dms.lpr.LpRm file+ --bindSourcePort, -B: Binds the source port [false] --help, h: displays the help information --localHost, -L[String]: Sets the local host [localhost] --longFormat, -l: Displays more informations about jobs [false] --mine, -m: Shows only the jobs of the current user [false] --printHost, -H[String]: Sets the print hosts [localhost] --proxyHost, -X[String]: Sets the proxy host to use (UNIX) --queue, -P[String]: Sets the queue to work on --remotePort, -d[int]: Sets the remote port [-1] --sourcePort, -s[int]: Sets the source port [-1] --timeout, -t[int]: Sets the timeout value in millisc [60000] --user, -u[String]: Sets the user who invoked the command --version, V: prints out the version information java at.dms.lpr.LpQ --bindSourcePort, -B: Binds the source port [false] --help, h: displays the help information --localHost, -L[String]: Sets the local host [localhost] --longFormat, -l: Displays more informations about jobs [false] --mine, -m: Shows only the jobs of the current user [false] --printHost, -H[String]: Sets the print hosts [localhost] --proxyHost, -X[String]: Sets the proxy host to use (UNIX) --queue, -P[String]: Sets the queue to work on --remotePort, -d[int]: Sets the remote port [-1] --sourcePort, -s[int]: Sets the source port [-1] --timeout, -t[int]: Sets the timeout value in millisc [60000] --user, -u[String]: Sets the user who invoked the command --version, V: prints out the version information
The goal of this tool is to print on a lpd queue from java.
To launch mailer from the command line, type
java at.dms.mailer.Mailer mailhost recipient subject text sender [aFileToAttach aName]
The goal of this tool is to send a mail with a possible attachement (uuencoded).
To launch sqlc from the command line, type
java at.dms.sqlc.Main sqlfile
The command line parameters are:
java at.dms.sqlc.Main sqlfile --help, h: displays the help information --version, V: prints out the version information --warning, w: Displays warning for misleading sql constructions [false]
The goal of this tool is to parse and verify sql statements.
To launch sqlc from the command line, type
java at.dms.dbi.Main sqlfile
The command line parameters are:
java at.dms.dbi.Main sqlfile --beautify, -b: Prints the source code (beautifier) [false] --commit, -c[String]: add a transDB to the data dict. --destination, -d[String]: the location to generate the database interface --driver, -D[String]: Sets the driver to use for DB access --help, h: displays the help information --interfaceGen, -i[String]: Sets the package name of Database.k --login, -l[String]: Sets thename of the user for login --passwd, -p[String]: Sets the passwd to login --simulate, -t: Runs the script but abort it [false] --stdin, -e: Reads from standard input [false] --stdout, -s: Prints on standard output [false] --syntax, -S[String]: Sets the syntax to use for output (jdbc | tbx) [jdbc] --url, -u[String]: Sets the url of the database --version, V: prints out the version information --warning, w: Displays warning for misleading sql constructions [false]
The goal of this tool is to parse and verify sql statements and to generate a data dictionary. It also allows one to convert JDBC-SQL to other SQL syntax (transbase).
warning(2): Else part of if-statement should be enclosed in block statement (JCC)
TBR.
TBR.
if (aCond) { aStatement(); } else aStatement();
Implemented.
warning(2): Then part of if-statement should be enclosed in block statement (JCC).
TBR.
TBR.
if (aCond) aStatement();
Implemented.
warning(2): Loop body should be enclosed in block statement (JCC).
TBR.
TBR.
while (aCond) aStatement();
Implemented.
warning(1): Field aField is already declared in a super class and is visible here (§kopi).
TBR.
TBR.
class A { protected aField; } class B extends A { protected aField; }
Implemented.
warning(1): Declared exception aQualifiedException is an unchecked exception (§kopi)
TBR.
TBR.
void aMethod() throws java.lang.RuntimeException { }
Implemented.
warning(1): Declared exception aQualifiedException is never thrown (§kopi)
TBR.
TBR.
void aMethod() throws java.io.IOException { // nothing }
Implemented.
warning(2): Old_style array bound declaration (§kopi)
TBR.
TBR.
int aField[];
Implemented.
notice: Consider replacing package import aQualifiedPackageImport by import of class(es) aListOfClassesImport (§kopi)
TBR.
TBR.
import java.io.*; // but only java.io.File is used in this compilation unit
Implemented.
warning(1): Assignment of an expression to itself (§kopi)
TBR.
TBR.
Constructor(int aParan) { // The parameter is missspelled. this.aParam = aParam; }
Implemented.
warning(2): Stray comma (§kopi)
TBR.
TBR.
new int[] {1, 2, }
Implemented.
warning(3): Stray semicolon (§kopi)
TBR.
TBR.
void aMethod() { };
Implemented.
warning(2): The type aType does not need to be casted in aSupertype (§kopi)
TBR.
TBR.
Object o = (Object)Integer.valueOf("1");
Implemented.
warning(1): The instanceof evaluation is not necessary (§kopi)
TBR.
TBR.
if (Integer.valueOf("1") instanceof Integer) { }
Implemented.
section INSTANCE_PREFIXES_STATIC_METHOD - TBR
warning(2): Avoid using an instance to access a class (static) method; use a class name instead (§kopi)
TBR.
TBR.
class A { static int i() {return 1;}; static int aMethod(A a) { return a.i(); } }
Implemented.
warning(2): Avoid using an instance to access a class (static) field; use a class name instead (§kopi)
TBR.
TBR.
class A { static i; static aMethod(A a) { a.i = 0; } }
Implemented.
warning(3): The catch parameter aCatchParameter is not used (§kopi)
TBR.
TBR.
try { // ... } catch (Exception e) { }
Implemented.
warning3: The imported class aClass is not used (§kopi)
TBR.
TBR.
import java.io.File; // but not anymore used
Implemented.
warning(1): The local variable aVariable is not used (§kopi)
TBR.
TBR.
{ int count; // not used anymore }
Implemented.
warning(1): The imported package \"{0}\" is not used (§kopi)
TBR.
TBR.
import java.lang.*;
Implemented.
warning(3): The parameter aParameter is not used (§kopi)
TBR.
TBR.
void aMethod(int aParameter) { // aParameter is not used anymore }
Implemented.
warning(1): The private field aField is not used (§kopi)
TBR.
TBR.
private int notUsedAnymore;
Implemented.
warning(1): The private method aMethod is not used (§kopi)
TBR.
TBR.
private int notUsed() {}
Implemented.
warning(2): On-Demand-Import of package java.lang is not necessary (§kopi)
TBR.
TBR.
import java.lang.Integer;
Implemented.
warning(2): On-Demand-Import of current package is not necessary (§kopi)
TBR.
TBR.
import currentpackage.AClass;
Implemented.
warning(1): The modifier aModifier is implicit and therefore does not need to be specified (§kopi)
TBR.
TBR.
interface AnInterface { public final int i = 0; }
Not Implemented.
warning(2): Fall through is dangerous and should not be used (§kopi)
TBR.
TBR.
switch (x) { case a: aStatement(); case b: aSecondStatement() }
Implemented.
warning(2): Every switch must have a default clause (§kopi)
TBR.
TBR.
switch (x) { case 1: // case 2: // } // default value usually means that there is an error.
Implemented.
warning(1): Catch block is empty (§kopi)
TBR.
TBR.
try { aStatement(); } catch (AnException ex) { // Should do something about it. }
Implemented.
warning(3): Field aField should be declared private or public (§kopi)
TBR.
TBR.
class AClass { int i; }
Implemented.
warning(2): The order of the modifiers does not follow the convention [aModifier] (§kopi)
TBR.
TBR.
final public static int i;
Implemented.
notice: There is no package declaration for this compilation unit (§kopi)
TBR.
TBR.
// no package XXX class AClass { }
Implemented.
warning(3): Attribute lists are hard to read and are preferably replaced by a list of attribute declaration (§kopi)
TBR.
TBR.
class AClass { int a, b, c; }
Not Implemented.
notice: This local variable is constant and should be declared final (§kopi)
TBR.
That allows the compiler to perform better optimizations. TBR.
int aMethod() { int i =0; // return i; }
Implemented.
warning(2): Assignment operator may have been used in place of equality operator (§kopi)
TBR.
TBR.
if (b = true) { aStatement(); }
Implemented.
warning(2): A method with the same name but different parameters exists in super class (§kopi)
TBR.
TBR.
class AClass { int aMethod() { } } class ASecondClass extends AClass { int aMethod(boolean b) { // it does not override aMethod } }
Not Implemented.
warning(1): Comparison of strings with '==' operator is surely wrong (§kopi)
TBR.
TBR.
boolean aMethod() { return "1" == Integer.toString(1); }
Implemented.
warning(2): Comparing boolean expression to constant values is not necessary (§kopi)
TBR.
TBR.
if (aCond() == true) { }
Implemented.
warning(2): Assignment of loop variable aVariable inside loop body (§kopi)
TBR.
TBR.
for (int i = 0; i < 10; i++) { for (int j - 0; j < 10; i++) { // do something but i is incremented twice } }
Implemented.
notice: Field aField may have not been explicitely initialized (§kopi)
TBR.
TBR.
class A { private boolean aCondition; }
Implemented.
warning(2): Field aField is constant and could be declared final (§kopi)
TBR.
TBR.
class A { // never reassigned private int aCondition = 1; }
Not implemented.
warning(2): Field aField could be declared static (§kopi)
TBR.
TBR.
class A { // never reassigned in instance methods private int aField = 1; }
Not implemented.
warning(2): The method aMethod returns a value that is never used (§kopi)
TBR. If you really want to call a function as a procedure, use the /*unused*/ comment tag:
class A { boolean aMethod() {...} void anOtherMethod() { /*unused*/aMethod(); /*unused return parameter*/aMethod(); } }
TBR.
class A { boolean aMethod() {...} void anOtherMethod() { aMethod(); } }
Not implemented.
If a branch instruction jumps to the next instruction, it can be removed or replaced by a pop instruction.
These instructions will be replaced by a pop2
These instructions will be replaced by a pop
These instructions will be replaced by a pop
/** * test * * @stack 0 * @locals 1 */ public static void test() { @goto _L1 _L1: @return } ===> /** * test * * @stack 0 * @locals 1 */ public static void test() { @return } or /** * test * * @stack 0 * @locals 1 */ public static void test() { @const 1 @ifne _L1 _L1: @return } ===> /** * test * * @stack 0 * @locals 1 */ public static void test() { const 1 pop @return }
Implemented.
If a branch instruction jumps to a goto, the target can be set to the target of this goto.
/** * test * * @stack 0 * @locals 1 */ public static void test() { @goto _L1 _L1: @goto _L2 _L2: @return } ===> /** * test * * @stack 0 * @locals 1 */ public static void test() { @goto _L2 _L1: @goto _L2 _L2: @return }
Implemented.
If a goto jumps to a return, it can be replaced by a return.
/** * test * * @stack 0 * @locals 1 */ public static void test() { @goto _L1 _L1: @return } ===> /** * test * * @stack 0 * @locals 1 */ public static void test() { @return _L1: @return }
Implemented.
nop can be removed in almost every case.
/** * test * * @stack 0 * @locals 1 */ public static void test() { @nop @return } ===> /** * test * * @stack 0 * @locals 1 */ public static void test() { @return }
Implemented.
If a branch instruction follows a push 0, it can be removed or replaced by a simpler instruction.
These instructions will be replaced by a icmp:
This instruction will be replaced by a goto:
This instruction will be removed:
/** * test * * @stack 0 * @locals 1 */ public static void test() { @push 1 @push 0 @if_icmp _L1 @goto _L1 _L1: @return } ===> /** * test * * @stack 0 * @locals 1 */ public static void test() { @push 1 @if_eq _L1 @goto _L1 _L1: @return }
Implemented.
If a branch instruction follows a push 1, it can be removed or replaced by a goto.
This instruction will be replaced by a goto:
This instruction will be removed:
/** * test * * @stack 0 * @locals 1 */ public static void test() { @push 1 @ifne _L1 @goto _L1 _L1: @return } ===> /** * test * * @stack 0 * @locals 1 */ public static void test() { @goto _L1 @goto _L1 _L1: @return }
Implemented.
If a branch instruction follows a push null it can be removed or replaced by a goto.
This instruction will be replaced by a goto:
This instruction will be removed:
/** * test * * @stack 0 * @locals 1 */ public static void test() { @push null @if_nonnull _L1 @goto _L1 _L1: @return } ===> /** * test * * @stack 0 * @locals 1 */ public static void test() { @goto _L1 _L1: @return }
Implemented.
If a push is followed by a pop, both can be removed.
/** * test * * @stack 0 * @locals 1 */ public static void test() { @push null @pop @return } ===> /** * test * * @stack 0 * @locals 1 */ public static void test() { @return }
Implemented.
This special pattern is generated by naive compiler for boolean comparison.
/** * test * * @stack 0 * @locals 1 */ public static int test() { @iload 2 @iload 1 @if_icmplt _L1 @const 0 @goto _L2 _L1: @const 1 _L2: @ifeq _L3 @const 10 @goto _L4 _L3: @const 11 _L4: @ireturn } ===> /** * test * * @stack 2 * @locals 3 */ public static int test() { @iload 2 @iload 1 @if_icmpge _L5 @const 10 @ireturn _L5: @const 11 @ireturn }
Implemented.
A jump over a goto can be replaced by its reverse code if targets are identical.
/** * test * * @stack 0 * @locals 1 */ public static int test() { @iload 1 @ifeq _L1 @goto _L2 _L1: @const 1 @ireturn _L2: @const 2 @ireturn } ===> /** * test * * @stack 1 * @locals 2 */ public static int test() { @iload 1 @ifne _L4 @const 1 @ireturn _L4: @const 2 @ireturn }
Implemented.
A branch following a ixor -1 can be replaced by its reverse code.
/** * test * * @stack 0 * @locals 1 */ public static int test() { @iload 1 @const -1 @ixor @ifeq _L1 @const 3 @ireturn _L1: @const 2 @ireturn } ===> /** * test * * @stack 1 * @locals 2 */ public static int test() { @iload 1 @ifne _L4 @const 3 @ireturn _L4: @const 2 @ireturn }
Implemented.
A duplicate push can be replaced by a push and a dup
/** * test * * @stack 0 * @locals 1 */ public static int test() { @const -1 @const -1 @iadd @ireturn } ===> /** * test * * @stack 2 * @locals 1 */ public static int test() { @const -1 @dup @iadd @ireturn }
Implemented.
A duplicate getfield can be replaced by a getfield and a dup
static int i; /** * test * * @stack 0 * @locals 1 */ public static int test() { @getstatic int Test.i @getstatic int Test.i @iadd @ireturn } ===> static int i; /** * test * * @stack 2 * @locals 1 */ public static int test() { @getstatic int Test.i @dup @iadd @ireturn }
Implemented.
A store following load can be replaced by a dup, store sequence. This allows the compiler to further optimize once the load is removed (reduce liveness of the local variable)
/** * test * * @stack 0 * @locals 1 */ public static int test() { @const 2 @istore 1 @iload 1 @ireturn } ===> /** * test * * @stack 2 * @locals 2 */ public static int test() { @const 2 @dup @istore 1 @ireturn }
Implemented.
The compiler uses several tools for automatic generation of messages, tokens, lexer, parser and command-line processor. All these tools are freely available under a GNU Public License or less restrictive clone. All of these tools are included in the distribution. There is first a set of tools necessary at build time:
ANTLR, ANother Tool for Language Recognition, (formerly PCCTS) is a language tool that provides a framework for constructing recognizers, compilers, and translators from grammatical descriptions containing C++ or Java actions
Jperf is a minimal perfect hash function generator utility written in Java and based on ggperf
The goal of this tool is to generate a perfect hashtable function and corresponding tokens for a specified list of keywords.
The goal of this tool is to generate a command line option controller (based on gnu.getopt) from a description file.
The goal of this tool is to generate a class with messages from a description file.
There is a second set of libraries used at runtime. All these tools are freely available under a GNU Library Public License or less restrictive clone. These libraries are very small and included in the distribution in binary format. Source format are available on the web or from the credit page on our web server. There is two packages:
Only a very small subsest of the runtime library is used by KJC. The whole AST part is removed from our runtime.
The GNU Java getopt classes support short and long argument parsing in a manner 100% compatible with the version of GNU getopt in glibc 2.0.6 with a mostly compatible programmer's interface as well.
One other file was not originally developed by DMS, it is the grammar of Java for ANTLR. This file is in the public domain and actualy we are trying to keep our code as close as possible to the original.
The compiler is built on several packages as shown by the following graphic:
This package allows one to edit classfiles and to check and optimize instructions in an elegant way. This package is able to compute the stack's depth and the number of local variables used by each method.
This package contains utility classes used at runtime. This includes basic definition of messages and options, Vector and Array caches and convertion.
This package contains utility classes used specifically by the compiler at runtime. This includes a more refined version of the definition of messages, definition of error and warning classes, definition of basic parser and lexer and utility methods.
This tool allows one to optimize a method. It performs dead code elimination, some peephole optimizations and branch tensionning.
This tool allows one to optimize a method. It transforms the (stack-based) JVM bytecode to an intermediate representation based on quadruple and performs some powerful optimizations (CSE, dead code elimination, copy propagation, register allocation). And it regenerates java bytecode with a stack schleduling engine.
This package contains the Java compiler. The classes for the AST (Abstract Syntax Tree) are prefixed with a J, the classes for the definitions of members are prefixed with a C. This part is explained more deeply in the next section.
This tool allows one to generate java classfile from an assembler definition. It is very useful in conjunction with DIS to modify some classes.
This tool allows one to see the code actually generated by the compiler and may help one to optimize or understand a portion of the code. This tool may also help one modify some classes from their bytecode in conjunction with KSM(to regenerate them).
The main class of the compiler is in `Main.java'. This file is responsible for initialization, decoding arguments, opening and closing files, and sequencing the passes.
The different passes are:
The parsing pass is invoked only once, to parse the entire input. This pass reads the entire text of each compilation unit, constructing syntax trees. The tree representation does follow Java syntax, except for TryCatchFinally statements that are splitted in two different statements.
The second pass checks the interface. All exported types are checked (a corresponding class definition should exist in either the source files or in the classpath). A CMember object is associated to every exported members, such object contains all the information required at check time (access flags, types, values).
This is a very small pass to compute exported constants before they are used in body of methods.
The code of each method is checked. After a class is checked, the parsing tree is destroyed and only method bodies are retained.
The code of each classes is generated and for each method two more passes of optimisations are available:
Peephole optimization and branch tensionning are performed.
More extensive optimizations are performed (dead code elimination, register allocation).
And then the code is dumped in files. Each time that a class code is generated and dumped into a file, this class is freed from memory.
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 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.
[This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.]
Preamble
The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software-to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some specially designated software packages-typically libraries-of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use, 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 and use pieces of it in new free programs; and that you are informed that you can do these things.
To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others.
Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs.
When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library.
We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances.
For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system.
Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for making modifications to it. For a library, 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 library.
Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's complete 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 distribute a copy of this License along with the Library.
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 Library or any portion of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful.
(For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.)
These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, 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 Library, 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 Library.
In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices.
Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you 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.
If distribution of 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 satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things:
a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place.
e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be 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.
It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute.
7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above.
b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library 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.
9. 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 Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library 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 with this License.
11. 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 Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library 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 Library.
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.
12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library 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.
13. The Free Software Foundation may publish revised and/or new versions of the Lesser 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 Library 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 Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, 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
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "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 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. 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 LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
c
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
License type : KSM is distributed under the terms of the GNU General Public License. (See Appendix 2.)
License type : DIS is distributed under the terms of the GNU PUBLIC License. (See Appendix 2.)
License type : Kopi Classfile is distributed under the terms of the GNU Lesser General Public License. (See Appendix 1.)
License type : optimize is distributed under the terms of the GNU PUBLIC License. (See Appendix 2.)
License type : KJC is distributed under the terms of the GNU General Public License. (See Appendix 2.)
License type : XKJC is distributed under the terms of the GNU General Public License. (See Appendix 2.)
License type : Optgen is distributed under the terms of the GNU General Public License.
License type : Optgen is distributed under the terms of the GNU General Public License. (See Appendix 2.)
License type : Mesgen is distributed under the terms of the GNU General Public License. (See Appendix 2.)
License type : Lexgen is distributed under the terms of the GNU General Public License. (See Appendix 2.)
License type : Memcnt is distributed under the terms of the GNU Lesser General Public License.(See Appendix 1.)
License type : MKJC is distributed under the terms of the GNU General Public License. (See Appendix 2.)
License type : Lpr is distributed under the terms of the GNU Lesser General Public License. (See Appendix 1.)
License type : Mailer is distributed under the terms of the GNU Lesser General Public License. (See Appendix 1.)
License type : Sqlc is distributed under the terms of the GNU General Public License. (See Appendix 2.)
License type : Dbi is distributed under the terms of the GNU General Public License. (See Appendix 2.)