├── .gitignore ├── COPYING ├── HyperSQL.ini ├── HyperSQL.py ├── README.md ├── diagram.js ├── doc ├── CHANGELOG ├── HyperSQLFull.ini ├── apidoc │ └── mk_pydoc ├── config.txt ├── frmf2xml.sh ├── javadoc.txt ├── limits.txt ├── todo.txt ├── unittests.txt └── ut_plsql.py ├── hypersql.css ├── lang ├── de ├── de_DE │ └── LC_MESSAGES │ │ ├── depgraph.mo │ │ ├── depgraph.po │ │ ├── hyperjdoc.mo │ │ ├── hyperjdoc.po │ │ ├── hyperopts.mo │ │ ├── hyperopts.po │ │ ├── hypersql.mo │ │ └── hypersql.po ├── en ├── en_US │ └── LC_MESSAGES │ │ ├── depgraph.mo │ │ ├── depgraph.po │ │ ├── hyperjdoc.mo │ │ ├── hyperjdoc.po │ │ ├── hyperopts.mo │ │ ├── hyperopts.po │ │ ├── hypersql.mo │ │ └── hypersql.po └── tool │ └── pot │ ├── depgraph.pot │ ├── hyperjdoc.pot │ ├── hyperopts.pot │ ├── hypersql.pot │ └── makepot ├── lib ├── depgraph.py ├── generator │ ├── __init__.py │ ├── commonhtml.py │ ├── db_html.py │ └── sqlstats.py ├── hypercore │ ├── __init__.py │ ├── cache.py │ ├── charts.py │ ├── codeformatter.py │ ├── config.py │ ├── elements.py │ ├── gettext_init.py │ ├── helpers.py │ ├── javadoc.py │ ├── logger.py │ ├── options.py │ ├── unittest.py │ └── xml_forms.py ├── iz_tools │ ├── IniParser.py │ ├── __init__.py │ ├── progressbar.py │ ├── system.py │ ├── text.py │ └── typecheck.py ├── parsers │ ├── __init__.py │ ├── filefinder.py │ └── sqlfinder.py └── progress.py ├── sql.keywords ├── sql.types └── tools ├── gen_sequences_scripts.sql ├── gen_table_scripts.sql └── gen_view_scripts.sql /.gitignore: -------------------------------------------------------------------------------- 1 | *.bak 2 | *.ini 3 | *.log 4 | *.pyc 5 | cache 6 | html 7 | doc/apidoc/*.py? 8 | doc/apidoc/*.txt 9 | doc/apidoc/*.html 10 | doc/apidoc/*.css 11 | -------------------------------------------------------------------------------- /HyperSQL.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | title_prefix = HyperSQL 3 | project_info = This is my HyperSQL project. 4 | project_info_file = 5 | project_logo = 6 | project_logo_url = 7 | encoding = utf8 8 | 9 | [FileNames] 10 | top_level_directory = . 11 | rcsnames = RCS CVS .svn .git 12 | sql_file_exts = sql pks pkb pkg pls 13 | cpp_file_exts = c cpp h 14 | htmldir = html/ 15 | css_file = hypersql.css 16 | css_url = 17 | file = FileNameIndexNoPathnames.html 18 | filepath = FileNameIndexWithPathnames.html 19 | view = ViewIndex.html 20 | package = PackageIndex.html 21 | package_full = PackagesWithFuncsAndProcsIndex.html 22 | function = FunctionIndex.html 23 | procedure = ProcedureIndex.html 24 | bug = BugIndex.html 25 | todo = TodoIndex.html 26 | 27 | [Pages] 28 | file = 1 29 | filepath = 1 30 | mview = 0 31 | view = 0 32 | package = 1 33 | package_full = 1 34 | function = 1 35 | procedure = 1 36 | sequence = 0 37 | synonym = 0 38 | tab = 0 39 | type = 0 40 | trigger = 0 41 | form = 0 42 | form_full = 0 43 | bug = 1 44 | depgraph = 1 45 | report = 0 46 | stat = 0 47 | todo = 1 48 | 49 | 50 | [Process] 51 | purge_on_start = 0 52 | blind_offset = 0 53 | include_source = 1 54 | whereused_scan_shortrefs = 0 55 | whereused_scan_instring = 0 56 | 57 | [Logging] 58 | screenlevel = ERROR 59 | filelevel = DEBUG 60 | logfile = HyperSQL.log 61 | progress = 1 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HyperSQL 2 | ## Description 3 | ***HyperSQL*** is like a doxygen plus javadoc for SQL, hypermapping SQL views, packages, procedures, and functions to HTML source code listings and 4 | showing all code locations where these are used, while some basic syntax highlighting is applied to the SQL code. The internal "where used" 5 | functionality also scans C++ and Java source files. 6 | 7 | ***HyperSQL*** doesn't connect to any database, but rather works on files. Hence it should work for databases other than Oracle (which it was 8 | designed for initially) as well, though I've not tested that. If you do not maintain your database objects that way (but rather develop directly 9 | inside the database), some scripts in the `tools/` directory of the HyperSQL distribution might help you extract those from your Oracle database. 10 | For objects you can `COMMENT ON` (tables, views) they even create basic JavaDoc comments along. 11 | 12 | Further details as well as a documentation can be found in [the project's wiki](https://github.com/IzzySoft/HyperSQL/wiki). 13 | 14 | 15 | ## History 16 | The original version (1.0) was written by Randy Phillips in September 2001. A customer of mine required a script like this, but some additions 17 | were required as well. At this time, the latest release was version 1.0 from 2001, and no update was ever published since (see 18 | [original project site](http://hypersql.sourceforge.net/)). It also looked very much like Randy abandoned the project. 19 | 20 | So I decided to adopt the project at least temporarily (after establishing contact with Randy, he decided to hand over the project to 21 | me completely). It was (and still is) using the GPL, so there were no problems from the license side. As said, I very much liked the idea of 22 | ***HyperSQL***, but felt it needs some polish. So on one day in February 2010, I sat down and wrote version 1.1. Versions 1.2 and 1.3 followed 23 | the next day - and as you can see here, development still goes on (with a few breaks sometimes). 24 | 25 | For quite a while, I was using SVN on my own server to maintain the code. But due to demand of other users who wanted to participate, I've decided to move 26 | the code to *Github*, to make this part easier – especially as there are times I do not work myself on the project (due to lack of demand). 27 | 28 | 29 | ## Features 30 | * flexible configuration by use of `.ini` files 31 | * offering a lot of command line options to override configuration options on-the-fly 32 | * generates nicely formatted HTML files, CSS adjustable by use of `.css` files 33 | * parses SQL, C++ and Java files according to file extensions you configured 34 | * parses Oracle Forms XML files 35 | * generates hyperlinked listings of all objects found (SQL views, packages, functions, procedures, forms, etc.) 36 | * hyperlinks object names to their appearance in the source code 37 | * generates "where used" and "what used" lists, to show where your objects have been used by other objects (if they have) – helps you to find 38 | unused code if not, or example usages if found 39 | * generates dependency graphs 40 | * generates API references from JavaDoc style comments 41 | * generates a central bug and a central todo list, compiled from all the `@bug` and `@todo` items in your JavaDoc comments 42 | * checks validity of your JavaDoc style comments up to a certain degree, and you even may define "mandatory tags" 43 | * generates XML for UnitTests from your JavaDoc-embedded `@testcase`s 44 | 45 | [![Code Statistics](https://i.imgur.com/mQV7B44m.png)](https://i.imgur.com/mQV7B44.png) [![Dependency Graphs](https://i.imgur.com/54kPRzCm.png)](https://i.imgur.com/54kPRzC.png) 46 | 47 | 48 | ## License 49 | As stated above, *HyperSQL* uses the GPLv2 license. For details, see the [License file](doc/COPYING). 50 | 51 | 52 | ## Mentions 53 | * [HyperSQL automatically documents SQL code](https://sourceforge.net/blog/hypersql-automatically-documents-sql-code/) (SourceForge blog 7/2010) 54 | * [Javadoc-style Documentation for PL/SQL](http://www.idmworks.com/tips-and-tricks-javadoc-style-documentation-for-plsql/) (IDMWorks Blog 9/2011) 55 | -------------------------------------------------------------------------------- /doc/HyperSQLFull.ini: -------------------------------------------------------------------------------- 1 | [General] 2 | title_prefix = HyperSQL 3 | project_info = This is my HyperSQL project. 4 | project_info_file = 5 | project_logo = 6 | project_logo_url = 7 | encoding = utf8 8 | ticket_url = 9 | wiki_url = 10 | 11 | [FileNames] 12 | top_level_directory = . 13 | rcsnames = RCS CVS .svn .git 14 | ignorefile = .hsqlignore 15 | sql_file_exts = sql pks pkb pkg pls 16 | cpp_file_exts = c cpp h 17 | htmldir = html/ 18 | css_file = hypersql.css 19 | css_url = 20 | custom_css_files = 21 | unittest_dir = 22 | 23 | file = FileNameIndexNoPathnames.html 24 | filepath = FileNameIndexWithPathnames.html 25 | tab = TableIndex.html 26 | view = ViewIndex.html 27 | mview = MViewIndex.html 28 | trigger = TriggerIndex.html 29 | type = TypeIndex.html 30 | synonym = SynonymIndex.html 31 | sequence = SequenceIndex.html 32 | package = PackageIndex.html 33 | package_full = PackagesWithFuncsAndProcsIndex.html 34 | function = FunctionIndex.html 35 | procedure = ProcedureIndex.html 36 | form = FormIndex.html 37 | form_full = FormFullIndex.html 38 | bug = BugIndex.html 39 | todo = TodoIndex.html 40 | 41 | report = ReportIndex.html 42 | stat = StatIndex.html 43 | depgraph = DepGraphIndex.html 44 | 45 | 46 | [Pages] 47 | file = 1 48 | filepath = 1 49 | mview = 0 50 | view = 0 51 | package = 1 52 | package_full = 1 53 | function = 1 54 | procedure = 1 55 | sequence = 0 56 | synonym = 0 57 | tab = 0 58 | type = 0 59 | trigger = 0 60 | form = 0 61 | form_full = 0 62 | bug = 1 63 | depgraph = 1 64 | report = 0 65 | stat = 0 66 | todo = 1 67 | 68 | [DepGraph] 69 | objects = view pkg proc func 70 | processor = fdp 71 | fontname = 72 | fontsize = 73 | ranksep_dot = 74 | ranksep_twopi = 75 | len_neato = 76 | len_fdp = 77 | mindist_circo = 78 | file2file = 1 79 | file2object = 0 80 | object2file = 1 81 | object2object = 1 82 | deltmp = 1 83 | 84 | [Display] 85 | navbar_elems_per_row = 6 86 | link_urls = 1 87 | 88 | [Process] 89 | purge_on_start = 0 90 | blind_offset = 0 91 | include_source = 1 92 | include_source_limit = 0 93 | whereused_scan_shortrefs = 0 94 | whereused_scan_instring = 0 95 | javadoc = 1 96 | export_unittests = 0 97 | cache = 1 98 | link_code_calls = 1 99 | 100 | [Logging] 101 | screenlevel = ERROR 102 | filelevel = DEBUG 103 | logfile = HyperSQL.log 104 | progress = 1 105 | verification = 0 106 | maxkbytes = 0 107 | backupcount = 3 108 | capture_warnings = 0 109 | 110 | [Verification] 111 | javadoc_shortdesc_mode = unit 112 | verify_javadoc = 0 113 | javadoc_mandatory = 0 114 | author_in_report = 0 115 | mandatory_tags = desc 116 | mandatory_code_tags = author 117 | mandatory_codetag_objects = func proc pkg 118 | stats_javadoc_forms = 0 119 | verify_forms = 0 120 | -------------------------------------------------------------------------------- /doc/apidoc/mk_pydoc: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Generate the Api Reference using pydoc 3 | 4 | cd ${0%/*} 5 | 6 | # cleanup first 7 | rm -f *.txt 8 | rm -f *.html 9 | rm -f *.pyc 10 | rm -f *.py 11 | 12 | # prepare packages 13 | for d in iz_tools hypercore generator parsers; do 14 | [ -d $d ] && rm -rf $d 15 | mkdir -p $d; 16 | cp ../../lib/$d/*.py $d/ 17 | [ -f $d/setup.py ] && rm $d/setup.py 18 | done 19 | 20 | # get the code here 21 | cp ../../HyperSQL.py . 22 | cp ../../lib/*.py . 23 | cp ../../hypersql.css . 24 | [ -f test*.py ] && rm test*.py 25 | 26 | # Generate the apidoc 27 | for file in *.py iz_tools/*.py hypercore/*.py generator/*.py parsers/*.py; do 28 | pydoc ./$file >${file%.py}.txt 29 | pydoc -w ./$file 30 | done 31 | 32 | # cleanup 33 | rm -f __init__.html 34 | rm -f *.py* 35 | for d in iz_tools hypercore generator parsers; do 36 | rm -rf $d 37 | done 38 | 39 | # Generate an index 40 | echo ' 41 | HyperSQL Api Reference 42 | 43 | 44 |

HyperSQL Api Reference

45 |

Api References are available for the following modules:

46 | 52 | ' >> index.html 53 | echo generated index.html 54 | -------------------------------------------------------------------------------- /doc/frmf2xml.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # DESCRIPTION 4 | # This file is used to call the Forms2XML conversion tool. 5 | # It takes .fmb, .mmb, and .olb files and converts them into XML. 6 | # 7 | # NOTES 8 | # It wraps the class oracle.forms.util.xmltools.Forms2XML and passes 9 | # any parameters given onto the tool. 10 | # You can only use the standard nine parameters, but these can include 11 | # wildcards in the filenames. 12 | # 13 | 14 | # Test whether the DISPLAY is set (JDAPI needs that :-( ) 15 | [ -z "$DISPLAY" ] && { 16 | echo "You must have a valid DISPLAY variable set up to use this script." 17 | exit 1 18 | } 19 | 20 | # Setup environment incl. the path to include the necessary Forms dlls. 21 | export PATH=$ORACLE_HOME/bin:$ORACLE_HOME/jdk/bin$PATH 22 | export CLASSPATH=$ORACLE_HOME/jre:$ORACLE_HOME/jlib:$ORACLE_HOME/network/jlib 23 | export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$ORACLE_HOME/jdk/jre/lib/i386/server:$ORACLE_HOME/jdk/jre/lib/i386/native_threads:$ORACLE_HOME/jdk/jre/lib/i386:$LD_LIBRARY_PATH 24 | export ORACLE_TERM=vt220 25 | export O_JDK_HOME=${O_JDK_HOME:-/igweb/iAS10gR2/jdk} 26 | export FORMS_PATH=${FORMS_PATH}:$ORACLE_HOME/forms 27 | export FORMS_API_TK_BYPASS=TRUE 28 | 29 | # Run the tool with the required jar files added to the classpath 30 | $ORACLE_HOME/jdk/bin/java -classpath $ORACLE_HOME/forms/java/frmxmltools.jar:$ORACLE_HOME/forms/java/frmjdapi.jar:$ORACLE_HOME/lib/xmlparserv2.jar:$ORACLE_HOME/lib/xschema.jar oracle.forms.util.xmltools.Forms2XML $* 31 | -------------------------------------------------------------------------------- /doc/javadoc.txt: -------------------------------------------------------------------------------- 1 | Support for Javadoc style comments 2 | ================================== 3 | 4 | HyperSQL versions after v1.3 include support for Javadoc style comments. There 5 | is no plausibility check currently, so it's up to you to take care for correct 6 | spelling, syntax, and logic. Basically, you could define a procedure with an 7 | return value - sure, PL/SQL doesn't support this - but HyperSQL wouldn't complain. 8 | Just when writing the HTML code, it would ignore the @return value specified. 9 | 10 | Same applies to the other keywords: if your inline documentation contains tags 11 | unsupported by HyperSQL, they will be silently ignored - so you can keep them in 12 | the hope they will be added (and file a ticket to request this), all other stuff 13 | will still be processed. A side effect of this is, you won't be informed about 14 | possible typos - but you will find all those in your log file if your log level 15 | is set to at least INFO. 16 | 17 | 18 | Description 19 | ----------- 20 | 21 | HyperSQLs Javadoc parser is somehow limited - which forces you to stick to its 22 | rules. Together with those for the syntax highlighter, the good thing about it 23 | is it enforces a clean coding style ;) Please don't ask for it: These limitations 24 | will stay. It works this way, and I don't have the time for something more 25 | sophisticated. 26 | 27 | So these are the rules, explained using an example: 28 | 29 | /** This is an example procedure. It does something special. 30 | * I just cannot remember what. 31 | * @procedure special 32 | * @param in varchar2 command_me The special thing to do 33 | * @param in number many_times How often this should be done 34 | * @param inout varchar2 the_thing The thing to manipulate 35 | * @version $Id$ 36 | */ 37 | 38 | Everything between the opening tag ('/**') and the first line starting with '@' 39 | will be treated as the description. For the overviews, a short description will 40 | be created from this - by cutting everything following the first "stop mark 41 | character" (dot, semi colon, line break). So in our example, the short desc 42 | would be "This is an example procedure." 43 | 44 | It is a good idea to start each new line with the star - this way, when browsing 45 | your code, it is easy to tell how far the comment goes. HyperSQL expects you 46 | doing so. 47 | 48 | All information for a tag can be kept in one line - but (with versions post-3.7.5) 49 | they can also span multiple lines, which will make the JavaDoc block better 50 | human-readable in your source code. 51 | 52 | Moreover, all Javadoc information for a given object MUST be kept in one block, 53 | i.e. enclosed between '/**' and '*/' - the parser will close at the '*/' mark. 54 | If you miss the object type, everything else is probably lost (since HyperSQL 55 | would not know where it belongs to). However, if you set process.blind_offset in 56 | your configuration accordingly, this may still work if your Javadoc block starts 57 | immediately before/after the object declaration itself, e.g.: 58 | 59 | CREATE OR REPLACE PACKAGE something AS 60 | /** This is some package */ 61 | 62 | By default, this feature is switched off (blind_offset = 0). 63 | 64 | 65 | Supported Tags 66 | -------------- 67 | 68 | Object types: 69 | 70 | * @form 71 | * @function 72 | * @mview 73 | * @pkg 74 | * @procedure 75 | * @sequence 76 | * @synonym 77 | * @table 78 | * @trigger 79 | * @type 80 | * @view 81 | 82 | Object properties: 83 | 84 | * @col [ [] 85 | * @param [in|out|inout] [ [] 86 | * @return [ [] 87 | * @throws [] 88 | 89 | Other object information: 90 | 91 | * @author 92 | * @bug 93 | * @copyright 94 | * @deprecated 95 | * @example 96 | * @ignore 97 | * @ignorevalidation 98 | * @info 99 | * @private 100 | * @see 101 | * @since 102 | * @testcase 103 | * @ticket <[id] text> 104 | * @todo 105 | * @used [ ...] 106 | * @uses [ ...] 107 | * @version 108 | * @verbatim 109 | * @webpage 110 | * @wiki [text] 111 | 112 | Further Information 113 | ------------------- 114 | 115 | More detailed information can be found in the projects wiki, especially on the page 116 | http://projects.izzysoft.de/trac/hypersql/wiki/JavaDoc 117 | -------------------------------------------------------------------------------- /doc/limits.txt: -------------------------------------------------------------------------------- 1 | Known issues and limitations 2 | ============================ 3 | 4 | - if two objects have the same name (e.g. a table and its synonym), the dependency graph cannot tell them apart 5 | (same for where/what used currently) 6 | - filtering "/* block comments */" on parameter parse doesn't filter "/* nested /* comments */ */" correctly 7 | - used_by for types not always recognized (e.g. not in RETURNS of functions, with "PIPE ROW( ", 8 | or when used by other types) 9 | - some pages might not render correctly in MSIE, which sometimes runs in "compatibility mode" (especially on 10 | Intranet sites). HyperSQL tries to snap it out of that via the "X-UA-Compatible" Meta tag, but MSIE does 11 | not always honor that – nothing HyperSQL can do about that. If you're running into that issue, please 12 | see https://stackoverflow.com/a/16365626/2533433 for a work-around (in short: have your web server send 13 | the same setting with the HTTP headers). 14 | 15 | 16 | Known, but intended: 17 | -------------------- 18 | 19 | - @used/@uses are added to JavaDoc, but not to depency links. They are intended to point to "outside resources". 20 | - doesn't match full-qualified names between code and JavaDoc (e.g. "table_name" and "schema.table_name"). 21 | Consider this intended, as code might cover multiple database schemata and thus mappings are not clear 22 | by default. 23 | -------------------------------------------------------------------------------- /doc/todo.txt: -------------------------------------------------------------------------------- 1 | TO-DO LIST 2 | ========== 3 | * C++ files need doxygen hyperlinks for where used pages 4 | * Scan Java files for where used 5 | * Fully handle Types (see: limitations.txt) 6 | -------------------------------------------------------------------------------- /doc/unittests.txt: -------------------------------------------------------------------------------- 1 | Unit Tests 2 | ========== 3 | 4 | HyperSQL allows you to define Unit-Tests with your JavaDoc-style documentation. 5 | The ideas behind this are: 6 | 7 | * defining them here makes it more likely they are kept up-to-date 8 | * providing an easy syntax makes it more likely developers will add/maintain them 9 | * exporting them to XML gives you the possibility to automatically create/run 10 | those tests using a programming language of your choice 11 | 12 | Currently, I'm not aware of any openly available program processing those XML files, 13 | but with some luck they may be provided in the future. I hereby strongly encourage 14 | the developers amongst you to create them, and feed them back to this project, so 15 | they may be included with future versions of HyperSQL or at least mentioned in its 16 | documentation together with a link to your project, if you prefer that. The 17 | following definitions should give you all required information - plus if you have 18 | any questions left, I'll do my best to answer them. 19 | 20 | 21 | Defining testcases with your JavaDoc style documentation 22 | -------------------------------------------------------- 23 | 24 | This can be done using the @testcase tag. It's content can be multi-line, but all 25 | line-breaks are optional. First a basic example given the 26 | "FUNCTION foo (bar IN NUMBER) RETURNS VARCHAR2": 27 | 28 | @function foo 29 | @param in number bar The foo bar description 30 | @return varchar2 31 | @testcase 32 | name { foo_bar_five }; 33 | comment { Converting 5 to a word should give us "five" }; 34 | message { foo(5) did not return "five"! }; 35 | param { bar 5 }; 36 | return { = five }; 37 | 38 | This should look quite intuitive, so now we can go for the formal description. 39 | First, what is written there in a line we now call an "element", which has the 40 | form " { };". is always a WORD, can be anything 41 | depending on the . Second: all elements are generally optional - which are 42 | required depends on the "object" the @testcase is attached to (a procedure e.g. 43 | has no return value) - but a testcase with no value to check makes no sense at 44 | all, and will be silently ignored. Third, @testcase will only be evaluated for 45 | functions and procedures (stand-alone or in packages). 46 | 47 | So here comes the more formal syntax: 48 | 49 | element := [ element ] name | comment | message | param | check | return 50 | 51 | name := "name" { word }; 52 | comment := "comment" { text }; 53 | message := "message" { text }; 54 | param := "param" { param_name value }; 55 | check := "check" | "check_param" | "checkparam" { param_name operator value }; 56 | return := "return" | "check_return" | "checkreturn" { operator value }; 57 | 58 | word := [A-z_]+ 59 | text := .+ 60 | param_name := word 61 | value := text 62 | operator:= "<" | ">" | "=" | "!=" 63 | 64 | Note that the definition for "word" and "text" is given as regular expression: 65 | The "+" at the end means it needs at least one character of the definition before, 66 | [A-z_] means you can use only upper-case letters and the underscore. The "." 67 | stands for any character - so even line breaks are permitted here. Terms in 68 | double quotes are meant literally. Just compare it with the example above ;) 69 | 70 | 71 | The generated XML file 72 | ---------------------- 73 | 74 | Output will be generated on a per-input-file basis (one output file per input file, 75 | but only if the input file contains any testcases). So the name of the generated 76 | XML file corresponds to the name of the input file (including some encoded 77 | directory information, if the input file was located in a subdirectory). 78 | 79 | Content starts with the XML declaration, followed by one element 80 | serving as our "root". This "root" contains one or more TESTSUITEs, representing 81 | either a database package or a collection of all stand-alone functions and 82 | procedures of the input file. Each TESTSUITE holds one or more OBJECTs, where 83 | each OBJECT represents a single procedure or function and contains its 84 | SIGNATURE and TESTCASEs. 85 | 86 | Again, all this is best explained given a basic example, using our above foo() function: 87 | 88 | 89 | 90 | 91 | 92 | 93 | foo 94 | 95 | varchar2 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | The TESTCASE for a procedure would not have the RET child, but instead probably 108 | some OUT Variable to check: 109 | 110 | 111 | 112 | So there you've got all what's currently implemented. Admitted, this will not 113 | allow for complex cases - but those may be supported by a later version (see below). 114 | 115 | 116 | Generating the real code 117 | ------------------------ 118 | 119 | WARNING: THE FOLLOWING IS NOT WELL TESTED, SO DON'T USE IT STRAIGHT ON YOUR 120 | PRODUCTION DATABASE WITHOUT HAVING EVERYTHING TESTED OUT YOURSELF! 121 | YOU HAVE BEEN WARNED! 122 | 123 | More or less as a "proof of concept", you will find a script named "ut_plsql.py" 124 | in the "doc/" directory of this distribution. It will accept the name of a single 125 | XML file as input, generate PL/SQL unit-test code, and write it to STDOUT. Thus 126 | given a directory containing (only) all your generated XML files and this script, 127 | plus the script made executable (Unix/Linux: "chmod u+x ut_plsql.py"), on a 128 | Unix/Linux machine you could simply run 129 | 130 | for file in *.xml; do ./ut_plsql.py $file > ${file%*.xml}.sql; done 131 | 132 | and afterwards find a corresponding *.sql file for each of your XML files. One 133 | more line: 134 | 135 | for file in *.sql; do sqlplus scott/tiger@orcl <$file; done 136 | 137 | And you have the unit-test packages installed into your database. OF COURSE YOU 138 | SHOULD CHECK THE SQL FILES FIRST!!! Never do such things blindly. Most important 139 | is to make sure there are no existing packages with the same name as one of those 140 | you are going to install... 141 | 142 | Each of those test-unit packages will have a procedure called "test_run_all()". 143 | Execute it to run all unit-tests of the given package. 144 | 145 | 146 | As said before, this is mostly a "proof of concept". It should however work for 147 | simple cases (feedback welcome); but you are strongly encouraged to write your 148 | own code generators (you may use this code to your convenience according to the 149 | terms of its license, the GPL). Use whatever language fits YOU best, and the 150 | generated code can reflect that as well. As author of HyperSQL, I appreciate 151 | your reporting back, and will happily mention (and link to or even include) your 152 | code generator with HyperSQL! 153 | 154 | 155 | Future Plans 156 | ------------ 157 | 158 | Don't take them as already scheduled - but there are some ideas of what might 159 | possibly added in the future. You may thing e.g. of procedures without any OUT 160 | parameter, which just alter some data. Or functions/procedures which need some 161 | preparation and/or post-checking/cleanup to be done. For those, the TESTCASE 162 | could get two more children: 163 | 164 | 165 | 166 | 167 | The AFTER stuff may even need some more attention: You might want to check here 168 | whether a certain table contains certain data the function/procedure inserted or 169 | updated. And other things might be there as well (feel free to visit the projects 170 | website to add ideas with the ticket system). 171 | 172 | 173 | 174 | 175 | Where the anonymous PLSQL could just be executed, not returning anything, it 176 | could check the data altered/inserted by the tested function/procedure to see 177 | whether it meets the expectations, and write the result into some (temporary) 178 | table. The SQL then should return a value to be interpreted as either TRUE or 179 | FALSE - which simply means whether our test succeeded or not. All those 180 | "temporary" data could then be cleaned up using the AFTER declaration. 181 | 182 | As said above, this is just some brainstorming - non of this is scheduled or 183 | even implemented yet. But we have the possibilities to extend the features 184 | already offered... 185 | -------------------------------------------------------------------------------- /hypersql.css: -------------------------------------------------------------------------------- 1 | /* 2 | * =============================================== 3 | * Stylesheet for HyperSQL 4 | * Modify if you like :-) 5 | * =============================================== 6 | */ 7 | 8 | /* 9 | * General stuff 10 | */ 11 | body { background: #fff; } 12 | 13 | body, table, td, th { 14 | font-size: 13px; 15 | font-family: Verdana, Arial, Helvetica, sans-serif 16 | } 17 | 18 | a:visited { color: #990000; } 19 | 20 | dt { 21 | font-weight: bold; 22 | font-style: italic; 23 | } 24 | 25 | .objdef { 26 | margin-left:15px; 27 | text-indent:-15px; 28 | } 29 | 30 | .jdreturn { 31 | list-style-type:none; 32 | margin-left:-40px; 33 | } 34 | .jd_objname { 35 | margin-bottom:10px; 36 | } 37 | 38 | /* 39 | * Code Formatting 40 | */ 41 | code, pre { background: #ffc; } 42 | code a, pre a { text-decoration: none; } 43 | 44 | pre { 45 | border: 2px ridge #ccc; 46 | margin-left: 10px; 47 | margin-right: 10px; 48 | } 49 | 50 | .sqlkeyword, .sqltype, .sqlbrace { font-weight: bold; } 51 | .sqlkeyword { color: #900; } 52 | .sqltype {color: #00f; } 53 | .sqlcomment { color: #660; } 54 | .sqlnumeric { color: #090; } 55 | .sqlstring { color: #521; } 56 | 57 | /* 58 | * Navigation 59 | */ 60 | .toppagelink { 61 | float: right; 62 | margin-right:5px; 63 | background-color: #d5d5d5; 64 | } 65 | .toppagelink a { 66 | text-decoration: none !important; 67 | font-size: 80%; 68 | } 69 | 70 | .navbar { 71 | background: #eef; 72 | font-weight: bold; 73 | text-align: center; 74 | } 75 | td.navbar { width: 600px; } 76 | 77 | .navbar .active_element { 78 | font-weight: bolder; 79 | font-style: italic; 80 | background: #ffe; 81 | border-bottom: 2px dotted; 82 | } 83 | 84 | .topend { margin-bottom: 20px; } 85 | .bottomstart { margin-top: 3em; } 86 | #bottombar { text-align: center; } 87 | 88 | #generated { 89 | margin: 10px; 90 | font-size: 10px; 91 | } 92 | 93 | .title { 94 | text-align: right; 95 | font-weight: bold; 96 | font-style: italic; 97 | font-size: 16px; 98 | width: 1%; 99 | } 100 | 101 | /* 102 | * Table stuff 103 | */ 104 | table.apilist { 105 | background: transparent; 106 | border: 1px outset #808080; 107 | margin-left: auto; 108 | margin-right: auto; 109 | } 110 | 111 | table.apilist th { background: #ccf; } 112 | table.apilist th.sub { background: #eef; } 113 | table.apilist td.sub { 114 | text-align: center; 115 | border: 1px solid #ccf; 116 | background: #eee; 117 | } 118 | 119 | table.stat { margin-bottom: 20px; } 120 | 121 | th.delim { height: 3px; font-size: 2px; } 122 | 123 | td.whereused { 124 | text-align: center; 125 | white-space: nowrap; 126 | } 127 | 128 | table#projectinfo { 129 | height: 300px; 130 | max-width: 600px; 131 | } 132 | 133 | .verbatim { 134 | white-space: pre-wrap; 135 | font-family: monospace; 136 | } 137 | 138 | .tr0 { background-color: transparent; } 139 | .tr1 { background-color: #eeeeff; } 140 | .stat tr td:first-child { padding-right:1em; } 141 | .stat tr td:last-child { padding-left:1em; } 142 | 143 | /* 144 | * Header 145 | */ 146 | h1, h2, h3, h4 { text-align: center; } 147 | 148 | h1 { font-size: 18px; } 149 | h2 { font-size: 16px; } 150 | h3 { font-size: 15px; } 151 | h4 { font-size: 14px; font-style: italic; } 152 | 153 | #infotitle { margin-top:100px; } 154 | #infotitle + #projectinfo { margin-top:3em; } 155 | 156 | /* 157 | * Charts 158 | */ 159 | div.pie_chart { 160 | position:relative; 161 | max-width:220px; 162 | margin-left:auto; 163 | margin-right:auto; 164 | } 165 | td.pie_chart, td.pie_chart120 { width: 220px; } 166 | td.pie_chart120 { height:120px; } 167 | -------------------------------------------------------------------------------- /lang/de: -------------------------------------------------------------------------------- 1 | de_DE -------------------------------------------------------------------------------- /lang/de_DE/LC_MESSAGES/depgraph.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IzzySoft/HyperSQL/7d59a7e69a99b2ed2938a5c1e0f80e9a914b9121/lang/de_DE/LC_MESSAGES/depgraph.mo -------------------------------------------------------------------------------- /lang/de_DE/LC_MESSAGES/depgraph.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Project-Id-Version: depgraph\n" 4 | "Report-Msgid-Bugs-To: \n" 5 | "POT-Creation-Date: 2010-09-11 21:49+0200\n" 6 | "PO-Revision-Date: 2010-09-11 21:57+0100\n" 7 | "Last-Translator: Andreas Itzchak Rehberg \n" 8 | "Language-Team: \n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=UTF-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "X-Poedit-Language: German\n" 13 | "X-Poedit-Country: GERMANY\n" 14 | 15 | #: ../../../lib/depgraph.py:75 16 | #: ../../../lib/depgraph.py:110 17 | #: ../../../lib/depgraph.py:120 18 | #: ../../../lib/depgraph.py:141 19 | #: ../../../lib/depgraph.py:156 20 | #: ../../../lib/depgraph.py:168 21 | #: ../../../lib/depgraph.py:181 22 | #: ../../../lib/depgraph.py:184 23 | #: ../../../lib/depgraph.py:209 24 | #: ../../../lib/depgraph.py:224 25 | #: ../../../lib/depgraph.py:227 26 | #, python-format 27 | msgid "%(func)s was called with wrong parameter type: required: [%(req)s], given: [%(got)s]" 28 | msgstr "%(func)s wurde mit falschem Parametertyp aufgerufen: erwartet: [%(req)s], erhalten: [%(got)s]" 29 | 30 | #: ../../../lib/depgraph.py:230 31 | msgid "make_graph() called on an empty graph!" 32 | msgstr "make_graph() wurde für einen leeren Graphen aufgerufen!" 33 | 34 | #: ../../../lib/depgraph.py:123 35 | #, python-format 36 | msgid "parameter %(parm)s to %(func)s must not be empty!" 37 | msgstr "Parameter %(parm)s für %(func)s darf nicht leer sein!" 38 | 39 | #: ../../../lib/depgraph.py:197 40 | #, python-format 41 | msgid "unsupported Graphviz module \"%s\"" 42 | msgstr "nicht unterstütztes Graphviz-Modul \"%s\"" 43 | 44 | -------------------------------------------------------------------------------- /lang/de_DE/LC_MESSAGES/hyperjdoc.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IzzySoft/HyperSQL/7d59a7e69a99b2ed2938a5c1e0f80e9a914b9121/lang/de_DE/LC_MESSAGES/hyperjdoc.mo -------------------------------------------------------------------------------- /lang/de_DE/LC_MESSAGES/hyperjdoc.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Project-Id-Version: hyperjdoc\n" 4 | "Report-Msgid-Bugs-To: \n" 5 | "POT-Creation-Date: 2010-05-25 18:19+0200\n" 6 | "PO-Revision-Date: 2010-05-25 18:30+0100\n" 7 | "Last-Translator: Andreas Itzchak Rehberg \n" 8 | "Language-Team: \n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=UTF-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "X-Poedit-Language: German\n" 13 | "X-Poedit-Country: GERMANY\n" 14 | 15 | #: ../../lib/hyperjdoc.py:792 16 | #, python-format 17 | msgid "@%(tag)s requires parameter, none given in %(file)s line %(line)s" 18 | msgstr "@%(tag)s erfordert Parameter, es wurde jedoch keiner angegeben in %(file)s Zeile %(line)s" 19 | 20 | #: ../../lib/hyperjdoc.py:776 21 | #, python-format 22 | msgid "@%(tag)s requires at least one parameter, none given in %(file)s line %(line)s" 23 | msgstr "@%(tag)s erfordert zumindest einen Parameter, es wurde jedoch keiner angegeben in %(file)s Zeile %(line)s" 24 | 25 | #: ../../lib/hyperjdoc.py:755 26 | #, python-format 27 | msgid "@param requires at least one parameter, none given in %(file)s line %(line)s" 28 | msgstr "@param erfordert zumindest einen Parameter, es wurde jedoch keiner angegeben in %(file)s Zeile %(line)s" 29 | 30 | #: ../../lib/hyperjdoc.py:337 31 | msgid "Additional Info" 32 | msgstr "Zusätzliche Info" 33 | 34 | #: ../../lib/hyperjdoc.py:313 35 | #: ../../lib/hyperjdoc.py:642 36 | #: ../../lib/hyperjdoc.py:648 37 | msgid "Author" 38 | msgstr "Autor" 39 | 40 | #: ../../lib/hyperjdoc.py:323 41 | msgid "Available Since" 42 | msgstr "Verfügbar seit" 43 | 44 | #: ../../lib/hyperjdoc.py:331 45 | msgid "BUG" 46 | msgstr "BUG" 47 | 48 | #: ../../lib/hyperjdoc.py:297 49 | msgid "Column" 50 | msgstr "Spalte" 51 | 52 | #: ../../lib/hyperjdoc.py:296 53 | msgid "Columns" 54 | msgstr "Spalten" 55 | 56 | #: ../../lib/hyperjdoc.py:315 57 | msgid "Copyright" 58 | msgstr "Copyright" 59 | 60 | #: ../../lib/hyperjdoc.py:333 61 | msgid "DEPRECATED" 62 | msgstr "VERALTET" 63 | 64 | #: ../../lib/hyperjdoc.py:274 65 | #: ../../lib/hyperjdoc.py:298 66 | msgid "Data Type" 67 | msgstr "Datentyp" 68 | 69 | #: ../../lib/hyperjdoc.py:275 70 | #: ../../lib/hyperjdoc.py:298 71 | msgid "Description" 72 | msgstr "Beschreibung" 73 | 74 | #: ../../lib/hyperjdoc.py:309 75 | msgid "Example Usage" 76 | msgstr "Beispiel Anwendung" 77 | 78 | #: ../../lib/hyperjdoc.py:261 79 | msgid "Just used internally." 80 | msgstr "Nur intern benutzt" 81 | 82 | #: ../../lib/hyperjdoc.py:317 83 | msgid "License" 84 | msgstr "Lizenz" 85 | 86 | #: ../../lib/hyperjdoc.py:160 87 | msgid "Missing description" 88 | msgstr "Fehlende Beschreibung" 89 | 90 | #: ../../lib/hyperjdoc.py:181 91 | #, python-format 92 | msgid "Missing description for %(type)s column (#%(index)s)" 93 | msgstr "Fehlende Beschreibung für %(type)s column (#%(index)s)" 94 | 95 | #: ../../lib/hyperjdoc.py:170 96 | #, python-format 97 | msgid "Missing description for %(type)s parameter (#%(index)s)" 98 | msgstr "Fehlende Beschreibung für %(type)s parameter (#%(index)s)" 99 | 100 | #: ../../lib/hyperjdoc.py:185 101 | #, python-format 102 | msgid "Missing description for column \"%(pname)s\" for %(otype)s %(oname)s in %(file)s line %(line)s" 103 | msgstr "Fehlende Beschreibung für Spalte \"%(pname)s\" für %(otype)s %(oname)s in %(file)s Zeile %(line)s" 104 | 105 | #: ../../lib/hyperjdoc.py:184 106 | #, python-format 107 | msgid "Missing description for column %s" 108 | msgstr "Fehlende Beschreibung für Spalte %s" 109 | 110 | #: ../../lib/hyperjdoc.py:182 111 | #, python-format 112 | msgid "Missing description for column of type \"%(type)s\" for %(otype)s %(name)s in %(file)s line %(line)s" 113 | msgstr "Fehlende Beschreibung für Spalte vom Typ \"%(type)s\" für %(otype)s %(name)s in %(file)s Zeile %(line)s" 114 | 115 | #: ../../lib/hyperjdoc.py:174 116 | #, python-format 117 | msgid "Missing description for parameter \"%(pname)s\" for %(otype)s %(oname)s in %(file)s line %(line)s" 118 | msgstr "Fehlende Beschreibung für Parameter \"%(pname)s\" für %(otype)s %(oname)s in %(file)s Zeile %(line)s" 119 | 120 | #: ../../lib/hyperjdoc.py:173 121 | #, python-format 122 | msgid "Missing description for parameter %s" 123 | msgstr "Fehlende Beschreibung für Parameter %s" 124 | 125 | #: ../../lib/hyperjdoc.py:171 126 | #, python-format 127 | msgid "Missing description for parameter of type \"%(type)s\" for %(otype)s %(name)s in %(file)s line %(line)s" 128 | msgstr "Fehlende Beschreibung für Parameter vom Typ \"%(type)s\" für %(otype)s %(name)s in %(file)s Zeile %(line)s" 129 | 130 | #: ../../lib/hyperjdoc.py:163 131 | #, python-format 132 | msgid "Missing mandatory tag \"%(tag)s\" for %(otype)s %(name)s in %(file)s line %(line)s" 133 | msgstr "Fehlendes obligatorisches Tag \"%(tag)s\" für %(otype)s %(name)s in %(file)s Zeile %(line)s" 134 | 135 | #: ../../lib/hyperjdoc.py:162 136 | #, python-format 137 | msgid "Missing mandatory tag: @%s" 138 | msgstr "Fehlendes obligatorisches Tag: @%s" 139 | 140 | #: ../../lib/hyperjdoc.py:177 141 | #, python-format 142 | msgid "Missing name for %(type)s column (#%(index)s)" 143 | msgstr "Fehlender Name für %(type)s Spalte (#%(index)s)" 144 | 145 | #: ../../lib/hyperjdoc.py:166 146 | #, python-format 147 | msgid "Missing name for %(type)s parameter (#%(index)s)" 148 | msgstr "Fehlender Name für %(type)s Parameter (#%(index)s)" 149 | 150 | #: ../../lib/hyperjdoc.py:178 151 | #, python-format 152 | msgid "Missing name for column of type \"%(type)s\" for %(otype)s %(name)s in %(file)s line %(line)s" 153 | msgstr "Fehlender Name für Spalte vom Typ \"%(type)s\" für %(otype)s %(name)s in %(file)s Zeile %(line)s" 154 | 155 | #: ../../lib/hyperjdoc.py:167 156 | #, python-format 157 | msgid "Missing name for parameter of type \"%(type)s\" for %(otype)s %(name)s in %(file)s line %(line)s" 158 | msgstr "Fehlender Name für Parameter vom Typ \"%(type)s\" für %(otype)s %(name)s in %(file)s Zeile %(line)s" 159 | 160 | #: ../../lib/hyperjdoc.py:187 161 | msgid "Missing return value" 162 | msgstr "Fehlender Return-Wert" 163 | 164 | #: ../../lib/hyperjdoc.py:188 165 | #, python-format 166 | msgid "Missing return value for %(otype)s %(name)s in %(file)s line %(line)s" 167 | msgstr "Fehlender Return-Wert für %(otype)s %(name)s in %(file)s Zeile %(line)s" 168 | 169 | #: ../../lib/hyperjdoc.py:248 170 | #, python-format 171 | msgid "No object type specified for object id %(name)s, ID %(id)s in %(file)s line %(line)s" 172 | msgstr "Kein Objekttyp angegeben für %(name)s, ID %(id)s in %(file)s Zeile %(line)s" 173 | 174 | #: ../../lib/hyperjdoc.py:272 175 | msgid "Parameter" 176 | msgstr "Parameter" 177 | 178 | #: ../../lib/hyperjdoc.py:202 179 | #, python-format 180 | msgid "Parameter count mismatch for %(otype)s %(name)s in %(file)s line %(line)s (%(lc)s / %(lj)s)" 181 | msgstr "Falsche Parameteranzahl für %(otype)s %(name)s in %(file)s Zeile %(line)s (%(lc)s / %(lj)s)" 182 | 183 | #: ../../lib/hyperjdoc.py:201 184 | #, python-format 185 | msgid "Parameter count mismatch: Code has %(cparms)s parameters, Javadoc %(jparms)s" 186 | msgstr "Falsche Parameteranzahl: %(cparms)s im Code, %(jparms)s in Javadoc" 187 | 188 | #: ../../lib/hyperjdoc.py:271 189 | msgid "Parameters" 190 | msgstr "Parameter" 191 | 192 | #: ../../lib/hyperjdoc.py:261 193 | msgid "Private" 194 | msgstr "Privat" 195 | 196 | #: ../../lib/hyperjdoc.py:287 197 | msgid "Return values" 198 | msgstr "Return-Werte" 199 | 200 | #: ../../lib/hyperjdoc.py:363 201 | msgid "See also" 202 | msgstr "Siehe auch" 203 | 204 | #: ../../lib/hyperjdoc.py:264 205 | msgid "Syntax" 206 | msgstr "Syntax" 207 | 208 | #: ../../lib/hyperjdoc.py:365 209 | msgid "TODO" 210 | msgstr "TODO" 211 | 212 | #: ../../lib/hyperjdoc.py:329 213 | msgid "Throws Exception" 214 | msgstr "Wirft Exception" 215 | 216 | #: ../../lib/hyperjdoc.py:339 217 | msgid "Ticket" 218 | msgstr "Ticket" 219 | 220 | #: ../../lib/hyperjdoc.py:246 221 | #, python-format 222 | msgid "Unnamed object with ID %(id)s (%(file)s line %(line)s has no object type set!" 223 | msgstr "Unbenanntes Objekt mit der ID %(id)s (%(file)s Zeile %(line)s) hat keinen Objekt-Typ definiert!" 224 | 225 | #: ../../lib/hyperjdoc.py:327 226 | msgid "Used" 227 | msgstr "Wird benutzt" 228 | 229 | #: ../../lib/hyperjdoc.py:325 230 | msgid "Uses" 231 | msgstr "Benutzt" 232 | 233 | #: ../../lib/hyperjdoc.py:335 234 | msgid "Version Info" 235 | msgstr "Versionsinfo" 236 | 237 | #: ../../lib/hyperjdoc.py:319 238 | msgid "Webpage" 239 | msgstr "Website" 240 | 241 | #: ../../lib/hyperjdoc.py:353 242 | msgid "Wiki" 243 | msgstr "Wiki" 244 | 245 | #: ../../lib/hyperjdoc.py:368 246 | msgid "^ Top" 247 | msgstr "^ Top" 248 | 249 | #: ../../lib/hyperjdoc.py:795 250 | #, python-format 251 | msgid "unsupported JavaDoc tag \"%(tag)s\" in %(file)s line %(line)s" 252 | msgstr "unbekanntes JavaDoc Tag \"%(tag)s\" in %(file)s Zeile %(line)s" 253 | 254 | #~ msgid "" 255 | #~ "@return requires at least one parameter, none given in %(file)s line %" 256 | #~ "(line)s" 257 | #~ msgstr "" 258 | #~ "@return erfordert zumindest einen Parameter, es wurde jedoch keiner " 259 | #~ "angegeben in %(file)s Zeile %(line)s" 260 | 261 | -------------------------------------------------------------------------------- /lang/de_DE/LC_MESSAGES/hyperopts.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IzzySoft/HyperSQL/7d59a7e69a99b2ed2938a5c1e0f80e9a914b9121/lang/de_DE/LC_MESSAGES/hyperopts.mo -------------------------------------------------------------------------------- /lang/de_DE/LC_MESSAGES/hyperopts.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Project-Id-Version: hyperopts\n" 4 | "Report-Msgid-Bugs-To: \n" 5 | "POT-Creation-Date: 2010-04-14 17:57+0200\n" 6 | "PO-Revision-Date: 2010-04-14 18:05+0100\n" 7 | "Last-Translator: Andreas Itzchak Rehberg \n" 8 | "Language-Team: \n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=UTF-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "X-Poedit-Language: German\n" 13 | "X-Poedit-Country: GERMANY\n" 14 | 15 | #: ../../lib/hyperopts.py:37 16 | msgid "Cache Options" 17 | msgstr "Cache Optionen" 18 | 19 | #: ../../lib/hyperopts.py:77 20 | msgid "Dependency Graph Options" 21 | msgstr "Optionen für die Abhängigkeits-Graphen" 22 | 23 | #: ../../lib/hyperopts.py:65 24 | msgid "Logging Options" 25 | msgstr "Logging Optionen" 26 | 27 | #: ../../lib/hyperopts.py:27 28 | msgid "Options can be used to override configured values." 29 | msgstr "Optionen können benutzt werden, um Werte aus der Konfigurationsdatei für diese Ausführung zu überschreiben." 30 | 31 | #: ../../lib/hyperopts.py:45 32 | msgid "Processing Options" 33 | msgstr "Optionen für die Verarbeitung" 34 | 35 | #: ../../lib/hyperopts.py:27 36 | msgid "Syntax: %prog [options] [project]" 37 | msgstr "Syntax: %prog [Optionen] [Projekt]" 38 | 39 | #: ../../lib/hyperopts.py:61 40 | msgid "check for Javadoc errors and write the corresponding report" 41 | msgstr "auf Javadoc Fehler prüfen und den entsprechenden Report generieren" 42 | 43 | #: ../../lib/hyperopts.py:33 44 | msgid "config file to use" 45 | msgstr "alternative Einstellungsdatei benutzen" 46 | 47 | #: ../../lib/hyperopts.py:35 48 | msgid "directory the generated HTML files should be written to" 49 | msgstr "Verzeichnis, in das die generierten HTML-Dateien geschrieben werden sollen" 50 | 51 | #: ../../lib/hyperopts.py:34 52 | msgid "directory to parse for source files" 53 | msgstr "Verzeichnis, in dem nach den Quellcode-Dateien gesucht werden soll" 54 | 55 | #: ../../lib/hyperopts.py:62 56 | msgid "do not check for Javadoc errors and do not write the corresponding report" 57 | msgstr "nicht auf Javadoc-Fehler prüfen (und den zugehörigen Report natürlich auch nicht erstellen)" 58 | 59 | #: ../../lib/hyperopts.py:79 60 | msgid "do not draw the specified graph (multiple definitions allowed)" 61 | msgstr "den angegebenen Abhängigkeits-Graphen nicht erstellen. Kann mehrfach spezifiziert werden (jeweils ein Graph)" 62 | 63 | #: ../../lib/hyperopts.py:60 64 | msgid "do not include (and link to) highlighted source" 65 | msgstr "Source-Code nicht highlighten, verlinken, und einfügen" 66 | 67 | #: ../../lib/hyperopts.py:50 68 | msgid "do not link to targets in code calls" 69 | msgstr "keine Links in den Source-Code einfügen" 70 | 71 | #: ../../lib/hyperopts.py:74 72 | msgid "do not log javadoc verification messages" 73 | msgstr "Nachrichten von der JavaDoc-Verifikation nicht in der Log-Datei protokollieren" 74 | 75 | #: ../../lib/hyperopts.py:48 76 | msgid "do not process javadoc" 77 | msgstr "Javadoc nicht verarbeiten" 78 | 79 | #: ../../lib/hyperopts.py:52 80 | msgid "do not process this page. Multiple definitions (for multiple pages) are possible." 81 | msgstr "diese Seite nicht erstellen. Kann mehrfach spezifiziert werden (jeweils eine Seite pro Spezifikation)" 82 | 83 | #: ../../lib/hyperopts.py:54 84 | msgid "do not purge old HTML files before creating the new ones" 85 | msgstr "HTML-Dateien vom vorigen Lauf nicht entfernen" 86 | 87 | #: ../../lib/hyperopts.py:56 88 | msgid "do not scan in strings for where/what objects are used" 89 | msgstr "Strings nicht auf verwendete Objekte untersuchen" 90 | 91 | #: ../../lib/hyperopts.py:58 92 | msgid "do not scan short references for where/what objects are used" 93 | msgstr "Kurzreferenzen bei der Suche nach verwendeten Objekten nicht berücksichtigen" 94 | 95 | #: ../../lib/hyperopts.py:70 96 | msgid "do not write progress information to STDOUT" 97 | msgstr "keine Fortschritts-Anzeige auf der Standardausgabe verwenden" 98 | 99 | #: ../../lib/hyperopts.py:78 100 | msgid "draw the specified graph (multiple definitions allowed)" 101 | msgstr "den angegebenen Abhängigkeits-Graphen erstellen. Mehrfachnennungen möglich (ein Graph pro Spezifikation)" 102 | 103 | #: ../../lib/hyperopts.py:59 104 | msgid "include (and link to) highlighted source" 105 | msgstr "Sourcecode highlighten, verlinken, und einbinden" 106 | 107 | #: ../../lib/hyperopts.py:84 108 | msgid "len parameter for the fdp processor" 109 | msgstr "len Parameter für den Graphviz-Prozessor fdp" 110 | 111 | #: ../../lib/hyperopts.py:85 112 | msgid "len parameter for the neato processor" 113 | msgstr "len Parameter für den Graphviz-Prozessor neato" 114 | 115 | #: ../../lib/hyperopts.py:49 116 | msgid "link to targets in code calls" 117 | msgstr "im Quellcode auf aufgerufene Funktionen/Prozeduren verlinken" 118 | 119 | #: ../../lib/hyperopts.py:73 120 | msgid "log javadoc verification messages" 121 | msgstr "Nachrichten von der JavaDoc-Verifikation in der Log-Datei protokollieren" 122 | 123 | #: ../../lib/hyperopts.py:72 124 | msgid "log level to use for STDOUT" 125 | msgstr "Log-Level für die Bildschirmausgabe" 126 | 127 | #: ../../lib/hyperopts.py:67 128 | msgid "log level to use for the log file" 129 | msgstr "Log-Level für die Logdatei" 130 | 131 | #: ../../lib/hyperopts.py:86 132 | msgid "mindist parameter for the circo processor" 133 | msgstr "mindist Parameter für den Graphviz-Prozessor circo" 134 | 135 | #: ../../lib/hyperopts.py:80 136 | msgid "name of the font to use for the graphs (e.g. Arial)" 137 | msgstr "von Graphviz zu verwendende Schriftart (z.B. Arial)" 138 | 139 | #: ../../lib/hyperopts.py:82 140 | msgid "objects to include with the dependency graphs. Multiple specifications (one per required object) are possible." 141 | msgstr "Objekte, die in den Abhängigkeitsgraphen verwendet werden sollen" 142 | 143 | #: ../../lib/hyperopts.py:40 144 | msgid "override the cache dir location" 145 | msgstr "Verzeichnis für Cache-Dateien" 146 | 147 | #: ../../lib/hyperopts.py:47 148 | msgid "process javadoc" 149 | msgstr "Javadoc verarbeiten" 150 | 151 | #: ../../lib/hyperopts.py:51 152 | msgid "process this page. Multiple definitions (for multiple pages) are possible." 153 | msgstr "die angegebene Seite erstellen. Mehrfachnennungen möglich (je eine Seite pro Nennung)" 154 | 155 | #: ../../lib/hyperopts.py:53 156 | msgid "purge old HTML files before creating the new ones" 157 | msgstr "HTML-Dateien von vorigen Ausführungen entfernen" 158 | 159 | #: ../../lib/hyperopts.py:42 160 | msgid "purge the specified cache at the very start. Possible values are: all, code, depdata. Multiple definitions are possible." 161 | msgstr "Cache-Dateien vom angegebenen Typ vor der Verarbeitung löschen. Mögliche Werte sind: all, code, depdata. Mehrfache Spezifizierung ist möglich." 162 | 163 | #: ../../lib/hyperopts.py:55 164 | msgid "scan in strings for where/what objects are used" 165 | msgstr "Strings nach verwendeten Objekten durchsuchen" 166 | 167 | #: ../../lib/hyperopts.py:57 168 | msgid "scan short references for where/what objects are used" 169 | msgstr "Kurzreferenzen bei der Suche nach verwendeten Objekten berücksichtigen" 170 | 171 | #: ../../lib/hyperopts.py:46 172 | msgid "set the \"blind offset\" to this number of lines" 173 | msgstr "\"blind offset\" auf die angegebene Zeilenzahl setzen" 174 | 175 | #: ../../lib/hyperopts.py:81 176 | msgid "size of the font to use for the graphs (e.g. 10 or 8.5)" 177 | msgstr "Schriftart-Größe für die erstellten Graphen (z.B. 10 oder 8.5)" 178 | 179 | #: ../../lib/hyperopts.py:87 180 | msgid "space between the levels (for the dot processor)" 181 | msgstr "Freiraum zwischen den Ebenen (für den Graphviz-Prozessor dot)" 182 | 183 | #: ../../lib/hyperopts.py:88 184 | msgid "space between the levels (for the twopi processor)" 185 | msgstr "Freiraum zwischen den Ebenen (für den Graphviz-Prozessor twopi)" 186 | 187 | #: ../../lib/hyperopts.py:66 188 | msgid "suppress all non-error output to STDOUT. This is equivalent to --noprogress --screen-loglevel ERROR and, as the name suggests, intended to be used for automated runs via a scheduler" 189 | msgstr "Alles außer Fehlermeldungen für die Standard-Ausgabe (STDOUT) ignorieren. Dies entspricht der Kombination aus --noprogress und --screen-loglevel ERROR und ist für die Benutzung mit automatischen Schedulern (z.B. Cron) gedacht." 190 | 191 | #: ../../lib/hyperopts.py:71 192 | msgid "suppress all output to STDOUT. This is equivalent to --noprogress --screen-loglevel NONE" 193 | msgstr "Alle Nachrichten auf der Standard-Ausgabe (STDOUT) deaktivieren. Dies entspricht der Kombination aus --noprogress und --screen-loglevel NONE" 194 | 195 | #: ../../lib/hyperopts.py:39 196 | msgid "turn the cache off" 197 | msgstr "Cache deaktivieren" 198 | 199 | #: ../../lib/hyperopts.py:38 200 | msgid "turn the cache on" 201 | msgstr "Cache aktivieren" 202 | 203 | #: ../../lib/hyperopts.py:68 204 | msgid "use the specified file to write our log into" 205 | msgstr "angegebene Datei als Log-Datei verwenden" 206 | 207 | #: ../../lib/hyperopts.py:83 208 | msgid "which graphviz module to use" 209 | msgstr "zu verwendender Graphviz-Prozessor (fdp, dot, neato, twopi, circo)" 210 | 211 | #: ../../lib/hyperopts.py:69 212 | msgid "write progress information to STDOUT" 213 | msgstr "Fortschrittsanzeige auf der Standardausgabe aktivieren" 214 | 215 | -------------------------------------------------------------------------------- /lang/de_DE/LC_MESSAGES/hypersql.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IzzySoft/HyperSQL/7d59a7e69a99b2ed2938a5c1e0f80e9a914b9121/lang/de_DE/LC_MESSAGES/hypersql.mo -------------------------------------------------------------------------------- /lang/en: -------------------------------------------------------------------------------- 1 | en_US -------------------------------------------------------------------------------- /lang/en_US/LC_MESSAGES/depgraph.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IzzySoft/HyperSQL/7d59a7e69a99b2ed2938a5c1e0f80e9a914b9121/lang/en_US/LC_MESSAGES/depgraph.mo -------------------------------------------------------------------------------- /lang/en_US/LC_MESSAGES/depgraph.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Project-Id-Version: depgraph\n" 4 | "Report-Msgid-Bugs-To: \n" 5 | "POT-Creation-Date: 2010-09-11 21:49+0200\n" 6 | "PO-Revision-Date: 2010-09-11 21:56+0100\n" 7 | "Last-Translator: Andreas Itzchak Rehberg \n" 8 | "Language-Team: \n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=UTF-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "X-Poedit-Language: English\n" 13 | "X-Poedit-Country: UNITED STATES\n" 14 | "X-Poedit-SourceCharset: utf-8\n" 15 | 16 | #: ../../../lib/depgraph.py:75 17 | #: ../../../lib/depgraph.py:110 18 | #: ../../../lib/depgraph.py:120 19 | #: ../../../lib/depgraph.py:141 20 | #: ../../../lib/depgraph.py:156 21 | #: ../../../lib/depgraph.py:168 22 | #: ../../../lib/depgraph.py:181 23 | #: ../../../lib/depgraph.py:184 24 | #: ../../../lib/depgraph.py:209 25 | #: ../../../lib/depgraph.py:224 26 | #: ../../../lib/depgraph.py:227 27 | #, python-format 28 | msgid "%(func)s was called with wrong parameter type: required: [%(req)s], given: [%(got)s]" 29 | msgstr "%(func)s was called with wrong parameter type: required: [%(req)s], given: [%(got)s]" 30 | 31 | #: ../../../lib/depgraph.py:230 32 | msgid "make_graph() called on an empty graph!" 33 | msgstr "make_graph() called on an empty graph!" 34 | 35 | #: ../../../lib/depgraph.py:123 36 | #, python-format 37 | msgid "parameter %(parm)s to %(func)s must not be empty!" 38 | msgstr "parameter %(parm)s to %(func)s must not be empty!" 39 | 40 | #: ../../../lib/depgraph.py:197 41 | #, python-format 42 | msgid "unsupported Graphviz module \"%s\"" 43 | msgstr "unsupported Graphviz module \"%s\"" 44 | 45 | -------------------------------------------------------------------------------- /lang/en_US/LC_MESSAGES/hyperjdoc.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IzzySoft/HyperSQL/7d59a7e69a99b2ed2938a5c1e0f80e9a914b9121/lang/en_US/LC_MESSAGES/hyperjdoc.mo -------------------------------------------------------------------------------- /lang/en_US/LC_MESSAGES/hyperjdoc.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Project-Id-Version: hyperjdoc\n" 4 | "Report-Msgid-Bugs-To: \n" 5 | "POT-Creation-Date: 2010-05-25 18:19+0200\n" 6 | "PO-Revision-Date: 2010-05-25 18:24+0100\n" 7 | "Last-Translator: Andreas Itzchak Rehberg \n" 8 | "Language-Team: \n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=UTF-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "X-Poedit-Language: English\n" 13 | "X-Poedit-Country: UNITED STATES\n" 14 | 15 | #: ../../lib/hyperjdoc.py:792 16 | #, python-format 17 | msgid "@%(tag)s requires parameter, none given in %(file)s line %(line)s" 18 | msgstr "@%(tag)s requires parameter, none given in %(file)s line %(line)s" 19 | 20 | #: ../../lib/hyperjdoc.py:776 21 | #, python-format 22 | msgid "@%(tag)s requires at least one parameter, none given in %(file)s line %(line)s" 23 | msgstr "@%(tag)s requires at least one parameter, none given in %(file)s line %(line)s" 24 | 25 | #: ../../lib/hyperjdoc.py:755 26 | #, python-format 27 | msgid "@param requires at least one parameter, none given in %(file)s line %(line)s" 28 | msgstr "@param requires at least one parameter, none given in %(file)s line %(line)s" 29 | 30 | #: ../../lib/hyperjdoc.py:337 31 | msgid "Additional Info" 32 | msgstr "Additional Info" 33 | 34 | #: ../../lib/hyperjdoc.py:313 35 | #: ../../lib/hyperjdoc.py:642 36 | #: ../../lib/hyperjdoc.py:648 37 | msgid "Author" 38 | msgstr "Author" 39 | 40 | #: ../../lib/hyperjdoc.py:323 41 | msgid "Available Since" 42 | msgstr "Available Since" 43 | 44 | #: ../../lib/hyperjdoc.py:331 45 | msgid "BUG" 46 | msgstr "BUG" 47 | 48 | #: ../../lib/hyperjdoc.py:297 49 | msgid "Column" 50 | msgstr "Column" 51 | 52 | #: ../../lib/hyperjdoc.py:296 53 | msgid "Columns" 54 | msgstr "Columns" 55 | 56 | #: ../../lib/hyperjdoc.py:315 57 | msgid "Copyright" 58 | msgstr "Copyright" 59 | 60 | #: ../../lib/hyperjdoc.py:333 61 | msgid "DEPRECATED" 62 | msgstr "DEPRECATED" 63 | 64 | #: ../../lib/hyperjdoc.py:274 65 | #: ../../lib/hyperjdoc.py:298 66 | msgid "Data Type" 67 | msgstr "Data Type" 68 | 69 | #: ../../lib/hyperjdoc.py:275 70 | #: ../../lib/hyperjdoc.py:298 71 | msgid "Description" 72 | msgstr "Description" 73 | 74 | #: ../../lib/hyperjdoc.py:309 75 | msgid "Example Usage" 76 | msgstr "Example Usage" 77 | 78 | #: ../../lib/hyperjdoc.py:261 79 | msgid "Just used internally." 80 | msgstr "Just used internally." 81 | 82 | #: ../../lib/hyperjdoc.py:317 83 | msgid "License" 84 | msgstr "License" 85 | 86 | #: ../../lib/hyperjdoc.py:160 87 | msgid "Missing description" 88 | msgstr "Missing description" 89 | 90 | #: ../../lib/hyperjdoc.py:181 91 | #, python-format 92 | msgid "Missing description for %(type)s column (#%(index)s)" 93 | msgstr "Missing description for %(type)s column (#%(index)s)" 94 | 95 | #: ../../lib/hyperjdoc.py:170 96 | #, python-format 97 | msgid "Missing description for %(type)s parameter (#%(index)s)" 98 | msgstr "Missing description for %(type)s parameter (#%(index)s)" 99 | 100 | #: ../../lib/hyperjdoc.py:185 101 | #, python-format 102 | msgid "Missing description for column \"%(pname)s\" for %(otype)s %(oname)s in %(file)s line %(line)s" 103 | msgstr "Missing description for column \"%(pname)s\" for %(otype)s %(oname)s in %(file)s line %(line)s" 104 | 105 | #: ../../lib/hyperjdoc.py:184 106 | #, python-format 107 | msgid "Missing description for column %s" 108 | msgstr "Missing description for column %s" 109 | 110 | #: ../../lib/hyperjdoc.py:182 111 | #, python-format 112 | msgid "Missing description for column of type \"%(type)s\" for %(otype)s %(name)s in %(file)s line %(line)s" 113 | msgstr "Missing description for column of type \"%(type)s\" for %(otype)s %(name)s in %(file)s line %(line)s" 114 | 115 | #: ../../lib/hyperjdoc.py:174 116 | #, python-format 117 | msgid "Missing description for parameter \"%(pname)s\" for %(otype)s %(oname)s in %(file)s line %(line)s" 118 | msgstr "Missing description for parameter \"%(pname)s\" for %(otype)s %(oname)s in %(file)s line %(line)s" 119 | 120 | #: ../../lib/hyperjdoc.py:173 121 | #, python-format 122 | msgid "Missing description for parameter %s" 123 | msgstr "Missing description for parameter %s" 124 | 125 | #: ../../lib/hyperjdoc.py:171 126 | #, python-format 127 | msgid "Missing description for parameter of type \"%(type)s\" for %(otype)s %(name)s in %(file)s line %(line)s" 128 | msgstr "Missing description for parameter of type \"%(type)s\" for %(otype)s %(name)s in %(file)s line %(line)s" 129 | 130 | #: ../../lib/hyperjdoc.py:163 131 | #, python-format 132 | msgid "Missing mandatory tag \"%(tag)s\" for %(otype)s %(name)s in %(file)s line %(line)s" 133 | msgstr "Missing mandatory tag \"%(tag)s\" for %(otype)s %(name)s in %(file)s line %(line)s" 134 | 135 | #: ../../lib/hyperjdoc.py:162 136 | #, python-format 137 | msgid "Missing mandatory tag: @%s" 138 | msgstr "Missing mandatory tag: @%s" 139 | 140 | #: ../../lib/hyperjdoc.py:177 141 | #, python-format 142 | msgid "Missing name for %(type)s column (#%(index)s)" 143 | msgstr "Missing name for %(type)s column (#%(index)s)" 144 | 145 | #: ../../lib/hyperjdoc.py:166 146 | #, python-format 147 | msgid "Missing name for %(type)s parameter (#%(index)s)" 148 | msgstr "Missing name for %(type)s parameter (#%(index)s)" 149 | 150 | #: ../../lib/hyperjdoc.py:178 151 | #, python-format 152 | msgid "Missing name for column of type \"%(type)s\" for %(otype)s %(name)s in %(file)s line %(line)s" 153 | msgstr "Missing name for column of type \"%(type)s\" for %(otype)s %(name)s in %(file)s line %(line)s" 154 | 155 | #: ../../lib/hyperjdoc.py:167 156 | #, python-format 157 | msgid "Missing name for parameter of type \"%(type)s\" for %(otype)s %(name)s in %(file)s line %(line)s" 158 | msgstr "Missing name for parameter of type \"%(type)s\" for %(otype)s %(name)s in %(file)s line %(line)s" 159 | 160 | #: ../../lib/hyperjdoc.py:187 161 | msgid "Missing return value" 162 | msgstr "Missing return value" 163 | 164 | #: ../../lib/hyperjdoc.py:188 165 | #, python-format 166 | msgid "Missing return value for %(otype)s %(name)s in %(file)s line %(line)s" 167 | msgstr "Missing return value for %(otype)s %(name)s in %(file)s line %(line)s" 168 | 169 | #: ../../lib/hyperjdoc.py:248 170 | #, python-format 171 | msgid "No object type specified for object id %(name)s, ID %(id)s in %(file)s line %(line)s" 172 | msgstr "No object type specified for object id %(name)s, ID %(id)s in %(file)s line %(line)s" 173 | 174 | #: ../../lib/hyperjdoc.py:272 175 | msgid "Parameter" 176 | msgstr "Parameter" 177 | 178 | #: ../../lib/hyperjdoc.py:202 179 | #, python-format 180 | msgid "Parameter count mismatch for %(otype)s %(name)s in %(file)s line %(line)s (%(lc)s / %(lj)s)" 181 | msgstr "Parameter count mismatch for %(otype)s %(name)s in %(file)s line %(line)s (%(lc)s / %(lj)s)" 182 | 183 | #: ../../lib/hyperjdoc.py:201 184 | #, python-format 185 | msgid "Parameter count mismatch: Code has %(cparms)s parameters, Javadoc %(jparms)s" 186 | msgstr "Parameter count mismatch: Code has %(cparms)s parameters, Javadoc %(jparms)s" 187 | 188 | #: ../../lib/hyperjdoc.py:271 189 | msgid "Parameters" 190 | msgstr "Parameters" 191 | 192 | #: ../../lib/hyperjdoc.py:261 193 | msgid "Private" 194 | msgstr "Private" 195 | 196 | #: ../../lib/hyperjdoc.py:287 197 | msgid "Return values" 198 | msgstr "Return values" 199 | 200 | #: ../../lib/hyperjdoc.py:363 201 | msgid "See also" 202 | msgstr "See also" 203 | 204 | #: ../../lib/hyperjdoc.py:264 205 | msgid "Syntax" 206 | msgstr "Syntax" 207 | 208 | #: ../../lib/hyperjdoc.py:365 209 | msgid "TODO" 210 | msgstr "TODO" 211 | 212 | #: ../../lib/hyperjdoc.py:329 213 | msgid "Throws Exception" 214 | msgstr "Throws Exception" 215 | 216 | #: ../../lib/hyperjdoc.py:339 217 | msgid "Ticket" 218 | msgstr "Ticket" 219 | 220 | #: ../../lib/hyperjdoc.py:246 221 | #, python-format 222 | msgid "Unnamed object with ID %(id)s (%(file)s line %(line)s has no object type set!" 223 | msgstr "Unnamed object with ID %(id)s (%(file)s line %(line)s has no object type set!" 224 | 225 | #: ../../lib/hyperjdoc.py:327 226 | msgid "Used" 227 | msgstr "Used" 228 | 229 | #: ../../lib/hyperjdoc.py:325 230 | msgid "Uses" 231 | msgstr "Uses" 232 | 233 | #: ../../lib/hyperjdoc.py:335 234 | msgid "Version Info" 235 | msgstr "Version Info" 236 | 237 | #: ../../lib/hyperjdoc.py:319 238 | msgid "Webpage" 239 | msgstr "Webpage" 240 | 241 | #: ../../lib/hyperjdoc.py:353 242 | msgid "Wiki" 243 | msgstr "Wiki" 244 | 245 | #: ../../lib/hyperjdoc.py:368 246 | msgid "^ Top" 247 | msgstr "^ Top" 248 | 249 | #: ../../lib/hyperjdoc.py:795 250 | #, python-format 251 | msgid "unsupported JavaDoc tag \"%(tag)s\" in %(file)s line %(line)s" 252 | msgstr "unsupported JavaDoc tag \"%(tag)s\" in %(file)s line %(line)s" 253 | 254 | #~ msgid "" 255 | #~ "@return requires at least one parameter, none given in %(file)s line %" 256 | #~ "(line)s" 257 | #~ msgstr "" 258 | #~ "@return requires at least one parameter, none given in %(file)s line %" 259 | #~ "(line)s" 260 | 261 | -------------------------------------------------------------------------------- /lang/en_US/LC_MESSAGES/hyperopts.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IzzySoft/HyperSQL/7d59a7e69a99b2ed2938a5c1e0f80e9a914b9121/lang/en_US/LC_MESSAGES/hyperopts.mo -------------------------------------------------------------------------------- /lang/en_US/LC_MESSAGES/hyperopts.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Project-Id-Version: hyperopts\n" 4 | "Report-Msgid-Bugs-To: \n" 5 | "POT-Creation-Date: 2010-04-14 17:57+0200\n" 6 | "PO-Revision-Date: 2010-04-14 18:01+0100\n" 7 | "Last-Translator: Andreas Itzchak Rehberg \n" 8 | "Language-Team: \n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=UTF-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "X-Poedit-Language: English\n" 13 | "X-Poedit-Country: UNITED STATES\n" 14 | 15 | #: ../../lib/hyperopts.py:37 16 | msgid "Cache Options" 17 | msgstr "Cache Options" 18 | 19 | #: ../../lib/hyperopts.py:77 20 | msgid "Dependency Graph Options" 21 | msgstr "Dependency Graph Options" 22 | 23 | #: ../../lib/hyperopts.py:65 24 | msgid "Logging Options" 25 | msgstr "Logging Options" 26 | 27 | #: ../../lib/hyperopts.py:27 28 | msgid "Options can be used to override configured values." 29 | msgstr "Options can be used to override configured values." 30 | 31 | #: ../../lib/hyperopts.py:45 32 | msgid "Processing Options" 33 | msgstr "Processing Options" 34 | 35 | #: ../../lib/hyperopts.py:27 36 | msgid "Syntax: %prog [options] [project]" 37 | msgstr "Syntax: %prog [options] [project]" 38 | 39 | #: ../../lib/hyperopts.py:61 40 | msgid "check for Javadoc errors and write the corresponding report" 41 | msgstr "check for Javadoc errors and write the corresponding report" 42 | 43 | #: ../../lib/hyperopts.py:33 44 | msgid "config file to use" 45 | msgstr "config file to use" 46 | 47 | #: ../../lib/hyperopts.py:35 48 | msgid "directory the generated HTML files should be written to" 49 | msgstr "directory the generated HTML files should be written to" 50 | 51 | #: ../../lib/hyperopts.py:34 52 | msgid "directory to parse for source files" 53 | msgstr "directory to parse for source files" 54 | 55 | #: ../../lib/hyperopts.py:62 56 | msgid "do not check for Javadoc errors and do not write the corresponding report" 57 | msgstr "do not check for Javadoc errors and do not write the corresponding report" 58 | 59 | #: ../../lib/hyperopts.py:79 60 | msgid "do not draw the specified graph (multiple definitions allowed)" 61 | msgstr "do not draw the specified graph (multiple definitions allowed)" 62 | 63 | #: ../../lib/hyperopts.py:60 64 | msgid "do not include (and link to) highlighted source" 65 | msgstr "do not include (and link to) highlighted source" 66 | 67 | #: ../../lib/hyperopts.py:50 68 | msgid "do not link to targets in code calls" 69 | msgstr "do not link to targets in code calls" 70 | 71 | #: ../../lib/hyperopts.py:74 72 | msgid "do not log javadoc verification messages" 73 | msgstr "do not log javadoc verification messages" 74 | 75 | #: ../../lib/hyperopts.py:48 76 | msgid "do not process javadoc" 77 | msgstr "do not process javadoc" 78 | 79 | #: ../../lib/hyperopts.py:52 80 | msgid "do not process this page. Multiple definitions (for multiple pages) are possible." 81 | msgstr "do not process this page. Multiple definitions (for multiple pages) are possible." 82 | 83 | #: ../../lib/hyperopts.py:54 84 | msgid "do not purge old HTML files before creating the new ones" 85 | msgstr "do not purge old HTML files before creating the new ones" 86 | 87 | #: ../../lib/hyperopts.py:56 88 | msgid "do not scan in strings for where/what objects are used" 89 | msgstr "do not scan in strings for where/what objects are used" 90 | 91 | #: ../../lib/hyperopts.py:58 92 | msgid "do not scan short references for where/what objects are used" 93 | msgstr "do not scan short references for where/what objects are used" 94 | 95 | #: ../../lib/hyperopts.py:70 96 | msgid "do not write progress information to STDOUT" 97 | msgstr "do not write progress information to STDOUT" 98 | 99 | #: ../../lib/hyperopts.py:78 100 | msgid "draw the specified graph (multiple definitions allowed)" 101 | msgstr "draw the specified graph (multiple definitions allowed)" 102 | 103 | #: ../../lib/hyperopts.py:59 104 | msgid "include (and link to) highlighted source" 105 | msgstr "include (and link to) highlighted source" 106 | 107 | #: ../../lib/hyperopts.py:84 108 | msgid "len parameter for the fdp processor" 109 | msgstr "len parameter for the fdp processor" 110 | 111 | #: ../../lib/hyperopts.py:85 112 | msgid "len parameter for the neato processor" 113 | msgstr "len parameter for the neato processor" 114 | 115 | #: ../../lib/hyperopts.py:49 116 | msgid "link to targets in code calls" 117 | msgstr "link to targets in code calls" 118 | 119 | #: ../../lib/hyperopts.py:73 120 | msgid "log javadoc verification messages" 121 | msgstr "log javadoc verification messages" 122 | 123 | #: ../../lib/hyperopts.py:72 124 | msgid "log level to use for STDOUT" 125 | msgstr "log level to use for STDOUT" 126 | 127 | #: ../../lib/hyperopts.py:67 128 | msgid "log level to use for the log file" 129 | msgstr "log level to use for the log file" 130 | 131 | #: ../../lib/hyperopts.py:86 132 | msgid "mindist parameter for the circo processor" 133 | msgstr "mindist parameter for the circo processor" 134 | 135 | #: ../../lib/hyperopts.py:80 136 | msgid "name of the font to use for the graphs (e.g. Arial)" 137 | msgstr "name of the font to use for the graphs (e.g. Arial)" 138 | 139 | #: ../../lib/hyperopts.py:82 140 | msgid "objects to include with the dependency graphs. Multiple specifications (one per required object) are possible." 141 | msgstr "objects to include with the dependency graphs. Multiple specifications (one per required object) are possible." 142 | 143 | #: ../../lib/hyperopts.py:40 144 | msgid "override the cache dir location" 145 | msgstr "override the cache dir location" 146 | 147 | #: ../../lib/hyperopts.py:47 148 | msgid "process javadoc" 149 | msgstr "process javadoc" 150 | 151 | #: ../../lib/hyperopts.py:51 152 | msgid "process this page. Multiple definitions (for multiple pages) are possible." 153 | msgstr "process this page. Multiple definitions (for multiple pages) are possible." 154 | 155 | #: ../../lib/hyperopts.py:53 156 | msgid "purge old HTML files before creating the new ones" 157 | msgstr "purge old HTML files before creating the new ones" 158 | 159 | #: ../../lib/hyperopts.py:42 160 | msgid "purge the specified cache at the very start. Possible values are: all, code, depdata. Multiple definitions are possible." 161 | msgstr "purge the specified cache at the very start. Possible values are: all, code, depdata. Multiple definitions are possible." 162 | 163 | #: ../../lib/hyperopts.py:55 164 | msgid "scan in strings for where/what objects are used" 165 | msgstr "scan in strings for where/what objects are used" 166 | 167 | #: ../../lib/hyperopts.py:57 168 | msgid "scan short references for where/what objects are used" 169 | msgstr "scan short references for where/what objects are used" 170 | 171 | #: ../../lib/hyperopts.py:46 172 | msgid "set the \"blind offset\" to this number of lines" 173 | msgstr "set the \"blind offset\" to this number of lines" 174 | 175 | #: ../../lib/hyperopts.py:81 176 | msgid "size of the font to use for the graphs (e.g. 10 or 8.5)" 177 | msgstr "size of the font to use for the graphs (e.g. 10 or 8.5)" 178 | 179 | #: ../../lib/hyperopts.py:87 180 | msgid "space between the levels (for the dot processor)" 181 | msgstr "space between the levels (for the dot processor)" 182 | 183 | #: ../../lib/hyperopts.py:88 184 | msgid "space between the levels (for the twopi processor)" 185 | msgstr "space between the levels (for the twopi processor)" 186 | 187 | #: ../../lib/hyperopts.py:66 188 | msgid "suppress all non-error output to STDOUT. This is equivalent to --noprogress --screen-loglevel ERROR and, as the name suggests, intended to be used for automated runs via a scheduler" 189 | msgstr "suppress all non-error output to STDOUT. This is equivalent to --noprogress --screen-loglevel ERROR and, as the name suggests, intended to be used for automated runs via a scheduler" 190 | 191 | #: ../../lib/hyperopts.py:71 192 | msgid "suppress all output to STDOUT. This is equivalent to --noprogress --screen-loglevel NONE" 193 | msgstr "suppress all output to STDOUT. This is equivalent to --noprogress --screen-loglevel NONE" 194 | 195 | #: ../../lib/hyperopts.py:39 196 | msgid "turn the cache off" 197 | msgstr "turn the cache off" 198 | 199 | #: ../../lib/hyperopts.py:38 200 | msgid "turn the cache on" 201 | msgstr "turn the cache on" 202 | 203 | #: ../../lib/hyperopts.py:68 204 | msgid "use the specified file to write our log into" 205 | msgstr "use the specified file to write our log into" 206 | 207 | #: ../../lib/hyperopts.py:83 208 | msgid "which graphviz module to use" 209 | msgstr "which graphviz module to use" 210 | 211 | #: ../../lib/hyperopts.py:69 212 | msgid "write progress information to STDOUT" 213 | msgstr "write progress information to STDOUT" 214 | 215 | -------------------------------------------------------------------------------- /lang/en_US/LC_MESSAGES/hypersql.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IzzySoft/HyperSQL/7d59a7e69a99b2ed2938a5c1e0f80e9a914b9121/lang/en_US/LC_MESSAGES/hypersql.mo -------------------------------------------------------------------------------- /lang/tool/pot/depgraph.pot: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # This file is put in the public domain. 3 | # FIRST AUTHOR , YEAR. 4 | # 5 | #, fuzzy 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: depgraph\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2010-09-11 21:49+0200\n" 11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 12 | "Last-Translator: FULL NAME \n" 13 | "Language-Team: LANGUAGE \n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=CHARSET\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | 18 | #: ../../../lib/depgraph.py:75 ../../../lib/depgraph.py:110 19 | #: ../../../lib/depgraph.py:120 ../../../lib/depgraph.py:141 20 | #: ../../../lib/depgraph.py:156 ../../../lib/depgraph.py:168 21 | #: ../../../lib/depgraph.py:181 ../../../lib/depgraph.py:184 22 | #: ../../../lib/depgraph.py:209 ../../../lib/depgraph.py:224 23 | #: ../../../lib/depgraph.py:227 24 | #, python-format 25 | msgid "" 26 | "%(func)s was called with wrong parameter type: required: [%(req)s], given: [%" 27 | "(got)s]" 28 | msgstr "" 29 | 30 | #: ../../../lib/depgraph.py:230 31 | msgid "make_graph() called on an empty graph!" 32 | msgstr "" 33 | 34 | #: ../../../lib/depgraph.py:123 35 | #, python-format 36 | msgid "parameter %(parm)s to %(func)s must not be empty!" 37 | msgstr "" 38 | 39 | #: ../../../lib/depgraph.py:197 40 | #, python-format 41 | msgid "unsupported Graphviz module \"%s\"" 42 | msgstr "" 43 | -------------------------------------------------------------------------------- /lang/tool/pot/hyperjdoc.pot: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # This file is put in the public domain. 3 | # FIRST AUTHOR , YEAR. 4 | # 5 | #, fuzzy 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: hyperjdoc\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2010-05-25 18:19+0200\n" 11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 12 | "Last-Translator: FULL NAME \n" 13 | "Language-Team: LANGUAGE \n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=CHARSET\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | 18 | #: ../../lib/hyperjdoc.py:792 19 | #, python-format 20 | msgid "" 21 | "@%(tag)s requires parameter, none given in %(file)s line %(line)s" 22 | msgstr "" 23 | 24 | #: ../../lib/hyperjdoc.py:776 25 | #, python-format 26 | msgid "" 27 | "@%(tag)s requires at least one parameter, none given in %(file)s line %(line)" 28 | "s" 29 | msgstr "" 30 | 31 | #: ../../lib/hyperjdoc.py:755 32 | #, python-format 33 | msgid "" 34 | "@param requires at least one parameter, none given in %(file)s line %(line)s" 35 | msgstr "" 36 | 37 | #: ../../lib/hyperjdoc.py:337 38 | msgid "Additional Info" 39 | msgstr "" 40 | 41 | #: ../../lib/hyperjdoc.py:313 ../../lib/hyperjdoc.py:642 42 | #: ../../lib/hyperjdoc.py:648 43 | msgid "Author" 44 | msgstr "" 45 | 46 | #: ../../lib/hyperjdoc.py:323 47 | msgid "Available Since" 48 | msgstr "" 49 | 50 | #: ../../lib/hyperjdoc.py:331 51 | msgid "BUG" 52 | msgstr "" 53 | 54 | #: ../../lib/hyperjdoc.py:297 55 | msgid "Column" 56 | msgstr "" 57 | 58 | #: ../../lib/hyperjdoc.py:296 59 | msgid "Columns" 60 | msgstr "" 61 | 62 | #: ../../lib/hyperjdoc.py:315 63 | msgid "Copyright" 64 | msgstr "" 65 | 66 | #: ../../lib/hyperjdoc.py:333 67 | msgid "DEPRECATED" 68 | msgstr "" 69 | 70 | #: ../../lib/hyperjdoc.py:274 ../../lib/hyperjdoc.py:298 71 | msgid "Data Type" 72 | msgstr "" 73 | 74 | #: ../../lib/hyperjdoc.py:275 ../../lib/hyperjdoc.py:298 75 | msgid "Description" 76 | msgstr "" 77 | 78 | #: ../../lib/hyperjdoc.py:309 79 | msgid "Example Usage" 80 | msgstr "" 81 | 82 | #: ../../lib/hyperjdoc.py:261 83 | msgid "Just used internally." 84 | msgstr "" 85 | 86 | #: ../../lib/hyperjdoc.py:317 87 | msgid "License" 88 | msgstr "" 89 | 90 | #: ../../lib/hyperjdoc.py:160 91 | msgid "Missing description" 92 | msgstr "" 93 | 94 | #: ../../lib/hyperjdoc.py:181 95 | #, python-format 96 | msgid "Missing description for %(type)s column (#%(index)s)" 97 | msgstr "" 98 | 99 | #: ../../lib/hyperjdoc.py:170 100 | #, python-format 101 | msgid "Missing description for %(type)s parameter (#%(index)s)" 102 | msgstr "" 103 | 104 | #: ../../lib/hyperjdoc.py:185 105 | #, python-format 106 | msgid "" 107 | "Missing description for column \"%(pname)s\" for %(otype)s %(oname)s in %" 108 | "(file)s line %(line)s" 109 | msgstr "" 110 | 111 | #: ../../lib/hyperjdoc.py:184 112 | #, python-format 113 | msgid "Missing description for column %s" 114 | msgstr "" 115 | 116 | #: ../../lib/hyperjdoc.py:182 117 | #, python-format 118 | msgid "" 119 | "Missing description for column of type \"%(type)s\" for %(otype)s %(name)s " 120 | "in %(file)s line %(line)s" 121 | msgstr "" 122 | 123 | #: ../../lib/hyperjdoc.py:174 124 | #, python-format 125 | msgid "" 126 | "Missing description for parameter \"%(pname)s\" for %(otype)s %(oname)s in %" 127 | "(file)s line %(line)s" 128 | msgstr "" 129 | 130 | #: ../../lib/hyperjdoc.py:173 131 | #, python-format 132 | msgid "Missing description for parameter %s" 133 | msgstr "" 134 | 135 | #: ../../lib/hyperjdoc.py:171 136 | #, python-format 137 | msgid "" 138 | "Missing description for parameter of type \"%(type)s\" for %(otype)s %(name)" 139 | "s in %(file)s line %(line)s" 140 | msgstr "" 141 | 142 | #: ../../lib/hyperjdoc.py:163 143 | #, python-format 144 | msgid "" 145 | "Missing mandatory tag \"%(tag)s\" for %(otype)s %(name)s in %(file)s line %" 146 | "(line)s" 147 | msgstr "" 148 | 149 | #: ../../lib/hyperjdoc.py:162 150 | #, python-format 151 | msgid "Missing mandatory tag: @%s" 152 | msgstr "" 153 | 154 | #: ../../lib/hyperjdoc.py:177 155 | #, python-format 156 | msgid "Missing name for %(type)s column (#%(index)s)" 157 | msgstr "" 158 | 159 | #: ../../lib/hyperjdoc.py:166 160 | #, python-format 161 | msgid "Missing name for %(type)s parameter (#%(index)s)" 162 | msgstr "" 163 | 164 | #: ../../lib/hyperjdoc.py:178 165 | #, python-format 166 | msgid "" 167 | "Missing name for column of type \"%(type)s\" for %(otype)s %(name)s in %" 168 | "(file)s line %(line)s" 169 | msgstr "" 170 | 171 | #: ../../lib/hyperjdoc.py:167 172 | #, python-format 173 | msgid "" 174 | "Missing name for parameter of type \"%(type)s\" for %(otype)s %(name)s in %" 175 | "(file)s line %(line)s" 176 | msgstr "" 177 | 178 | #: ../../lib/hyperjdoc.py:187 179 | msgid "Missing return value" 180 | msgstr "" 181 | 182 | #: ../../lib/hyperjdoc.py:188 183 | #, python-format 184 | msgid "Missing return value for %(otype)s %(name)s in %(file)s line %(line)s" 185 | msgstr "" 186 | 187 | #: ../../lib/hyperjdoc.py:248 188 | #, python-format 189 | msgid "" 190 | "No object type specified for object id %(name)s, ID %(id)s in %(file)s line %" 191 | "(line)s" 192 | msgstr "" 193 | 194 | #: ../../lib/hyperjdoc.py:272 195 | msgid "Parameter" 196 | msgstr "" 197 | 198 | #: ../../lib/hyperjdoc.py:202 199 | #, python-format 200 | msgid "" 201 | "Parameter count mismatch for %(otype)s %(name)s in %(file)s line %(line)s (%" 202 | "(lc)s / %(lj)s)" 203 | msgstr "" 204 | 205 | #: ../../lib/hyperjdoc.py:201 206 | #, python-format 207 | msgid "" 208 | "Parameter count mismatch: Code has %(cparms)s parameters, Javadoc %(jparms)s" 209 | msgstr "" 210 | 211 | #: ../../lib/hyperjdoc.py:271 212 | msgid "Parameters" 213 | msgstr "" 214 | 215 | #: ../../lib/hyperjdoc.py:261 216 | msgid "Private" 217 | msgstr "" 218 | 219 | #: ../../lib/hyperjdoc.py:287 220 | msgid "Return values" 221 | msgstr "" 222 | 223 | #: ../../lib/hyperjdoc.py:363 224 | msgid "See also" 225 | msgstr "" 226 | 227 | #: ../../lib/hyperjdoc.py:264 228 | msgid "Syntax" 229 | msgstr "" 230 | 231 | #: ../../lib/hyperjdoc.py:365 232 | msgid "TODO" 233 | msgstr "" 234 | 235 | #: ../../lib/hyperjdoc.py:329 236 | msgid "Throws Exception" 237 | msgstr "" 238 | 239 | #: ../../lib/hyperjdoc.py:339 240 | msgid "Ticket" 241 | msgstr "" 242 | 243 | #: ../../lib/hyperjdoc.py:246 244 | #, python-format 245 | msgid "" 246 | "Unnamed object with ID %(id)s (%(file)s line %(line)s has no object type set!" 247 | msgstr "" 248 | 249 | #: ../../lib/hyperjdoc.py:327 250 | msgid "Used" 251 | msgstr "" 252 | 253 | #: ../../lib/hyperjdoc.py:325 254 | msgid "Uses" 255 | msgstr "" 256 | 257 | #: ../../lib/hyperjdoc.py:335 258 | msgid "Version Info" 259 | msgstr "" 260 | 261 | #: ../../lib/hyperjdoc.py:319 262 | msgid "Webpage" 263 | msgstr "" 264 | 265 | #: ../../lib/hyperjdoc.py:353 266 | msgid "Wiki" 267 | msgstr "" 268 | 269 | #: ../../lib/hyperjdoc.py:368 270 | msgid "^ Top" 271 | msgstr "" 272 | 273 | #: ../../lib/hyperjdoc.py:795 274 | #, python-format 275 | msgid "unsupported JavaDoc tag \"%(tag)s\" in %(file)s line %(line)s" 276 | msgstr "" 277 | -------------------------------------------------------------------------------- /lang/tool/pot/hyperopts.pot: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # This file is put in the public domain. 3 | # FIRST AUTHOR , YEAR. 4 | # 5 | #, fuzzy 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: hyperopts\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2010-04-14 17:57+0200\n" 11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 12 | "Last-Translator: FULL NAME \n" 13 | "Language-Team: LANGUAGE \n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=CHARSET\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | 18 | #: ../../lib/hyperopts.py:37 19 | msgid "Cache Options" 20 | msgstr "" 21 | 22 | #: ../../lib/hyperopts.py:77 23 | msgid "Dependency Graph Options" 24 | msgstr "" 25 | 26 | #: ../../lib/hyperopts.py:65 27 | msgid "Logging Options" 28 | msgstr "" 29 | 30 | #: ../../lib/hyperopts.py:27 31 | msgid "Options can be used to override configured values." 32 | msgstr "" 33 | 34 | #: ../../lib/hyperopts.py:45 35 | msgid "Processing Options" 36 | msgstr "" 37 | 38 | #: ../../lib/hyperopts.py:27 39 | msgid "Syntax: %prog [options] [project]" 40 | msgstr "" 41 | 42 | #: ../../lib/hyperopts.py:61 43 | msgid "check for Javadoc errors and write the corresponding report" 44 | msgstr "" 45 | 46 | #: ../../lib/hyperopts.py:33 47 | msgid "config file to use" 48 | msgstr "" 49 | 50 | #: ../../lib/hyperopts.py:35 51 | msgid "directory the generated HTML files should be written to" 52 | msgstr "" 53 | 54 | #: ../../lib/hyperopts.py:34 55 | msgid "directory to parse for source files" 56 | msgstr "" 57 | 58 | #: ../../lib/hyperopts.py:62 59 | msgid "" 60 | "do not check for Javadoc errors and do not write the corresponding report" 61 | msgstr "" 62 | 63 | #: ../../lib/hyperopts.py:79 64 | msgid "do not draw the specified graph (multiple definitions allowed)" 65 | msgstr "" 66 | 67 | #: ../../lib/hyperopts.py:60 68 | msgid "do not include (and link to) highlighted source" 69 | msgstr "" 70 | 71 | #: ../../lib/hyperopts.py:50 72 | msgid "do not link to targets in code calls" 73 | msgstr "" 74 | 75 | #: ../../lib/hyperopts.py:74 76 | msgid "do not log javadoc verification messages" 77 | msgstr "" 78 | 79 | #: ../../lib/hyperopts.py:48 80 | msgid "do not process javadoc" 81 | msgstr "" 82 | 83 | #: ../../lib/hyperopts.py:52 84 | msgid "" 85 | "do not process this page. Multiple definitions (for multiple pages) are " 86 | "possible." 87 | msgstr "" 88 | 89 | #: ../../lib/hyperopts.py:54 90 | msgid "do not purge old HTML files before creating the new ones" 91 | msgstr "" 92 | 93 | #: ../../lib/hyperopts.py:56 94 | msgid "do not scan in strings for where/what objects are used" 95 | msgstr "" 96 | 97 | #: ../../lib/hyperopts.py:58 98 | msgid "do not scan short references for where/what objects are used" 99 | msgstr "" 100 | 101 | #: ../../lib/hyperopts.py:70 102 | msgid "do not write progress information to STDOUT" 103 | msgstr "" 104 | 105 | #: ../../lib/hyperopts.py:78 106 | msgid "draw the specified graph (multiple definitions allowed)" 107 | msgstr "" 108 | 109 | #: ../../lib/hyperopts.py:59 110 | msgid "include (and link to) highlighted source" 111 | msgstr "" 112 | 113 | #: ../../lib/hyperopts.py:84 114 | msgid "len parameter for the fdp processor" 115 | msgstr "" 116 | 117 | #: ../../lib/hyperopts.py:85 118 | msgid "len parameter for the neato processor" 119 | msgstr "" 120 | 121 | #: ../../lib/hyperopts.py:49 122 | msgid "link to targets in code calls" 123 | msgstr "" 124 | 125 | #: ../../lib/hyperopts.py:73 126 | msgid "log javadoc verification messages" 127 | msgstr "" 128 | 129 | #: ../../lib/hyperopts.py:72 130 | msgid "log level to use for STDOUT" 131 | msgstr "" 132 | 133 | #: ../../lib/hyperopts.py:67 134 | msgid "log level to use for the log file" 135 | msgstr "" 136 | 137 | #: ../../lib/hyperopts.py:86 138 | msgid "mindist parameter for the circo processor" 139 | msgstr "" 140 | 141 | #: ../../lib/hyperopts.py:80 142 | msgid "name of the font to use for the graphs (e.g. Arial)" 143 | msgstr "" 144 | 145 | #: ../../lib/hyperopts.py:82 146 | msgid "" 147 | "objects to include with the dependency graphs. Multiple specifications (one " 148 | "per required object) are possible." 149 | msgstr "" 150 | 151 | #: ../../lib/hyperopts.py:40 152 | msgid "override the cache dir location" 153 | msgstr "" 154 | 155 | #: ../../lib/hyperopts.py:47 156 | msgid "process javadoc" 157 | msgstr "" 158 | 159 | #: ../../lib/hyperopts.py:51 160 | msgid "" 161 | "process this page. Multiple definitions (for multiple pages) are possible." 162 | msgstr "" 163 | 164 | #: ../../lib/hyperopts.py:53 165 | msgid "purge old HTML files before creating the new ones" 166 | msgstr "" 167 | 168 | #: ../../lib/hyperopts.py:42 169 | msgid "" 170 | "purge the specified cache at the very start. Possible values are: all, code, " 171 | "depdata. Multiple definitions are possible." 172 | msgstr "" 173 | 174 | #: ../../lib/hyperopts.py:55 175 | msgid "scan in strings for where/what objects are used" 176 | msgstr "" 177 | 178 | #: ../../lib/hyperopts.py:57 179 | msgid "scan short references for where/what objects are used" 180 | msgstr "" 181 | 182 | #: ../../lib/hyperopts.py:46 183 | msgid "set the \"blind offset\" to this number of lines" 184 | msgstr "" 185 | 186 | #: ../../lib/hyperopts.py:81 187 | msgid "size of the font to use for the graphs (e.g. 10 or 8.5)" 188 | msgstr "" 189 | 190 | #: ../../lib/hyperopts.py:87 191 | msgid "space between the levels (for the dot processor)" 192 | msgstr "" 193 | 194 | #: ../../lib/hyperopts.py:88 195 | msgid "space between the levels (for the twopi processor)" 196 | msgstr "" 197 | 198 | #: ../../lib/hyperopts.py:66 199 | msgid "" 200 | "suppress all non-error output to STDOUT. This is equivalent to --noprogress " 201 | "--screen-loglevel ERROR and, as the name suggests, intended to be used for " 202 | "automated runs via a scheduler" 203 | msgstr "" 204 | 205 | #: ../../lib/hyperopts.py:71 206 | msgid "" 207 | "suppress all output to STDOUT. This is equivalent to --noprogress --screen-" 208 | "loglevel NONE" 209 | msgstr "" 210 | 211 | #: ../../lib/hyperopts.py:39 212 | msgid "turn the cache off" 213 | msgstr "" 214 | 215 | #: ../../lib/hyperopts.py:38 216 | msgid "turn the cache on" 217 | msgstr "" 218 | 219 | #: ../../lib/hyperopts.py:68 220 | msgid "use the specified file to write our log into" 221 | msgstr "" 222 | 223 | #: ../../lib/hyperopts.py:83 224 | msgid "which graphviz module to use" 225 | msgstr "" 226 | 227 | #: ../../lib/hyperopts.py:69 228 | msgid "write progress information to STDOUT" 229 | msgstr "" 230 | -------------------------------------------------------------------------------- /lang/tool/pot/makepot: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Generate the POT files for this project 3 | ARGS="-s -L Python --foreign-user" 4 | 5 | [ ! -f /etc/SuSE-release ] && { # SuSE does not accept this parameter 6 | hsql=' --package-name=hypersql' 7 | jdoc=' --package-name=hyperjdoc' 8 | graf=' --package-name=depgraph' 9 | hopt=' --package-name=hyperopts' 10 | } 11 | 12 | # Make sure we are in the correct directory 13 | cd ${0%%/*} 14 | 15 | # Generate the POT files 16 | [ ../../../HyperSQL.py -nt hypersql.pot \ 17 | -o ../../../lib/hypercore/config.py -nt hypersql.pot \ 18 | -o ../../../lib/generator/commonhtml.py -nt hypersql.pot \ 19 | -o ../../../lib/generator/sqlstats.py -nt hypersql.pot \ 20 | -o ../../../lib/generator/db_html.py -nt hypersql.pot \ 21 | -o ../../../lib/parsers/sqlfinder.py -nt hypersql.pot \ 22 | -o ../../../lib/hypercore/helpers.py -nt hypersql.pot \ 23 | ] && xgettext -o hypersql.pot $ARGS $hsql ../../../HyperSQL.py ../../../lib/hypercore/config.py ../../../lib/generator/commonhtml.py ../../../lib/generator/sqlstats.py ../../../lib/generator/db_html.py ../../../lib/parsers/sqlfinder.py ../../../lib/hypercore/helpers.py 24 | [ ../../../lib/hyperjdoc.py -nt hyperjdoc.pot ] && xgettext -o hyperjdoc.pot $ARGS $jdoc ../../../lib/hyperjdoc.py 25 | [ ../../../lib/depgraph.py -nt depgraph.pot ] && xgettext -o depgraph.pot $ARGS $graf ../../../lib/depgraph.py 26 | [ ../../../lib/hyperopts.py -nt hyperopts.pot ] && xgettext -o hyperopts.pot $ARGS $hopt ../../../lib/hyperopts.py 27 | 28 | # Get back to where we came from 29 | cd - 30 | 31 | -------------------------------------------------------------------------------- /lib/depgraph.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Dependency graph 5 | $Id$ 6 | 7 | Example usage: 8 | 9 | g = depgraph() 10 | if g.deps_ok: 11 | g.set_graph('a -> b\nb -> c') 12 | #g.set_graph(['a -> b','b -> c']) 13 | g.make_graph('ab.png','png','Vera') 14 | """ 15 | 16 | #====================================================[ Imports and Presets ]=== 17 | from iz_tools.typecheck import * 18 | from iz_tools.system import * 19 | from hypercore.gettext_init import langpath, langs 20 | from os import sep as os_sep, path as os_path, access as os_access, unlink as os_unlink 21 | from tempfile import NamedTemporaryFile 22 | from hypercore.logger import logg 23 | logger = logg.getLogger('DepGraph') 24 | 25 | # Setup gettext support 26 | import gettext 27 | gettext.bindtextdomain('depgraph', langpath) 28 | gettext.textdomain('depgraph') 29 | lang = gettext.translation('depgraph', langpath, languages=langs, fallback=True) 30 | _ = lang.ugettext 31 | 32 | 33 | #=========================================================[ DepGraph class ]=== 34 | class depgraph(object): 35 | """ 36 | Generate dependency graphs using graphviz 37 | This requires the graphviz application to be installed 38 | """ 39 | 40 | def __init__(self,mod='dot',charset='utf-8',deltmp=True): 41 | """ 42 | Setup required dependencies and create the instance 43 | @param self 44 | @param optional string mod graphviz module to use. Defaults to 'dot' 45 | @param optional string charset charset to use (see set_charset). Default: 'utf-8' 46 | @param optional boolean deltmp Whether to delete the temporary command file. Default: True 47 | """ 48 | self.bin = '' # the binary/executable 49 | self.mod = '' # just the name w/o path 50 | self.charset = '' 51 | self.graph = '' # graph definition text 52 | self.name = 'G' # name of the generated graph 53 | self.fontname = '' # font to use with graphviz 54 | self.fontsize = '' # font size to use with graphviz 55 | self.size = '' # image size ('x-inch,y-inch') 56 | self.ranksep_dot = '' # rank separator for dot 57 | self.ranksep_twopi = '' # rank separator for twopi 58 | self.len_neato = '' # 'rank separator' for neato 59 | self.len_fdp = '' # 'rank separator' for fdp 60 | self.mindist_circo = '' # 'rank separator' for circo 61 | self.deltmp = deltmp 62 | self.set_mod(mod) 63 | self.set_charset(charset) 64 | 65 | def set_mod(self,mod='dot'): 66 | """ 67 | Set the graphviz module to use 68 | @param self 69 | @param optional string mod name of the module. This can be a full path, file.ext or file. Default: 'dot' 70 | @throws TypeError if the passed argument is neither string nor dict 71 | @example depgraph.set_mod('/usr/bin/dot') # this will be bound to *nix systems 72 | @example depgraph.set_mod('dot') # this will find dot (*nix) or dot.exe (Win+OS/2) in the PATH 73 | """ 74 | if not is_str(mod): 75 | logger.error(_('%(func)s was called with wrong parameter type: required: [%(req)s], given: [%(got)s]'), {'func':'depgraph.set_mod','req':'str','got':','.join(is_what(mod))}) 76 | raise TypeError 77 | binmod = mod 78 | if mod.find(os_sep)==-1: 79 | binmod = which(mod) # check for the binary in PATH environment 80 | if binmod==None: 81 | self.bin = '' 82 | self.mod = '' 83 | elif os_path.isfile(binmod) and os_access(binmod, os.X_OK): 84 | self.bin = binmod 85 | self.mod = mod 86 | else: 87 | self.bin = '' 88 | self.mod = '' 89 | 90 | def deps_ok(self): 91 | """ 92 | Check whether depgraph can operate (i.e. it found a suitable executable) 93 | @return boolean 94 | """ 95 | if self.mod != '': return True 96 | return False 97 | 98 | def set_graph(self,graph): 99 | """ 100 | Setup the graph definition 101 | @param self 102 | @param mixed graph either array of strings (multiple lines of defs) or string 103 | @throws TypeError if the passed argument is neither string nor dict 104 | @example depgraph.set_graph('a -> b\nb -> c') # using string input 105 | @example depgraph.set_graph(['a -> b','b -> c']) # using array input 106 | """ 107 | if is_str(graph): self.graph = graph 108 | elif is_list(graph): self.graph = '\n'.join(graph) 109 | else: 110 | logger.error(_('%(func)s was called with wrong parameter type: required: [%(req)s], given: [%(got)s]'), {'func':'depgraph.set_graph','req':'str','got':','.join(is_what(graph))}) 111 | raise TypeError 112 | 113 | def set_name(self,name='G'): 114 | """ 115 | Set the name for the graph 116 | @param self 117 | @param optional string name name of the graph (defaults to a simple 'G') 118 | """ 119 | if not is_str(name): 120 | logger.error(_('%(func)s was called with wrong parameter type: required: [%(req)s], given: [%(got)s]'), {'func':'depgraph.set_name','req':'str','got':','.join(is_what(name))}) 121 | return 122 | if name=='': 123 | logger.error(_('parameter %(parm)s to %(func)s must not be empty!'), {'parm':'name','func':'depgraph.set_name'}) 124 | return 125 | self.name = name 126 | 127 | def set_charset(self,name='utf-8'): 128 | """ 129 | Set the character set used in your graph definition. Supported charsets 130 | are 'utf-8' and 'iso-8859-1' (aka 'latin-1') currently, so all others 131 | will provoke an error from Graphviz and fallback to utf-8, until the 132 | Graphviz team supports them. 133 | @param self 134 | @param optional string name name of the charset (defaults to 'utf-8'). 135 | Pass an empty string to use the defaults configured with graphviz, 136 | if unsure - and then investigate the error message shown, which 137 | usually suggests you the correct one to use 138 | @example depgraph.set_charset('iso-8859-1') 139 | """ 140 | if not is_str(name): 141 | logger.error(_('%(func)s was called with wrong parameter type: required: [%(req)s], given: [%(got)s]'), {'func':'depgraph.set_charset','req':'str','got':','.join(is_what(name))}) 142 | return 143 | name = name.lower() 144 | if name=='iso-8859-15': name='iso-8859-1' 145 | self.charset = name 146 | 147 | def set_fontname(self,font): 148 | """ 149 | Set a different default font 150 | Without that, the graphviz default font (usually "Times") is used. 151 | If you set this, it is simply passed to graphviz - without making sure the font is available 152 | @param self 153 | @param string font Font name - or empty string to reset 154 | """ 155 | if not is_str(font): 156 | logger.error(_('%(func)s was called with wrong parameter type: required: [%(req)s], given: [%(got)s]'), {'func':'depgraph.set_fontname','req':'str','got':','.join(is_what(font))}) 157 | return 158 | self.fontname = font 159 | 160 | def set_fontsize(self,size): 161 | """ 162 | Set a different default font size 163 | Without that, the graphviz default font size is used. 164 | @param self 165 | @param string font size (in points) - or empty string to reset 166 | """ 167 | if not is_numeric(size) and size!='': 168 | logger.error(_('%(func)s was called with wrong parameter type: required: [%(req)s], given: [%(got)s]'), {'func':'depgraph.set_fontsize','req':'numeric','got':','.join(is_what(size))}) 169 | return 170 | self.fontsize = size 171 | 172 | def set_ranksep(self,size,mod): 173 | """ 174 | Set a different rank separator (valid for dot only) 175 | Without that, the graphviz default font size is used. 176 | @param self 177 | @param string ranksep ranksep value (distance, numeric) or empty string to reset 178 | @param string mod Graphviz module to apply to (one of fdp, neato, circo, dot, twopi) 179 | """ 180 | if not is_numeric(size) and size!='': 181 | logger.error(_('%(func)s was called with wrong parameter type: required: [%(req)s], given: [%(got)s]'), {'func':'depgraph.set_ranksep','req':'numeric','got':','.join(is_what(size))}) 182 | return 183 | if not is_str(mod): 184 | logger.error(_('%(func)s was called with wrong parameter type: required: [%(req)s], given: [%(got)s]'), {'func':'depgraph.set_ranksep','req':'string','got':','.join(is_what(mod))}) 185 | return 186 | if mod == 'fdp': 187 | self.len_fdp = size 188 | elif mod == 'neato': 189 | self.len_neato = size 190 | elif mod == 'circo': 191 | self.mindist_circo = size 192 | elif mod == 'dot': 193 | self.ranksep_dot = size 194 | elif mod == 'twopi': 195 | self.ranksep_twopi = size 196 | else: 197 | logger.error(_('unsupported Graphviz module "%s"'), mod) 198 | return 199 | 200 | def set_size(self,x,y): 201 | """ 202 | Limit resulting image size 203 | Without this set, we leave the decision to graphviz. Use x=0 or y=0 to reset. 204 | @param self 205 | @param int x width in inches (sorry, but that's what graphviz expects) 206 | @param int y height in inches 207 | """ 208 | if not is_numeric(x) or not is_numeric(y): 209 | logger.error(_('%(func)s was called with wrong parameter type: required: [%(req)s], given: [%(got)s]'), {'func':'depgraph.set_size','req':'numeric','got':','.join(is_what(size))}) 210 | return 211 | if x==0 or y==0: self.size = '' 212 | else: self.size = `x`+','+`y` 213 | 214 | def make_graph(self,fname,ftype='png'): 215 | """ 216 | Create the dependency graph as a file named fname of the type ftype 217 | @param self 218 | @param string fname name of the graphics file to create. If no path is specified, 219 | the current directory is used. If a path is specified, it should already exist! 220 | @param string ftype graphics type. Must be supported by the used graphviz module! Defaults to 'png'. 221 | @return string error stderr from graphviz (if any - otherwise empty string) 222 | """ 223 | if not is_str(ftype): 224 | logger.error(_('%(func)s was called with wrong parameter type: required: [%(req)s], given: [%(got)s]'), {'func':'depgraph.make_graph','req':'str','got':','.join(is_what(ftype))}) 225 | return 226 | if not is_str(fname): 227 | logger.error(_('%(func)s was called with wrong parameter type: required: [%(req)s], given: [%(got)s]'), {'func':'depgraph.make_graph','req':'str','got':','.join(is_what(fname))}) 228 | return 229 | if self.graph == '': 230 | logger.error(_('make_graph() called on an empty graph!')) 231 | return 232 | # Write graph information to a temporary file 233 | tmpname = fname + '.tmp' 234 | outfile = fopen(tmpname,'w') 235 | outfile.write( 'digraph ' + self.name + '{\n' + self.graph +'\n}\n' ) 236 | outfile.close() 237 | # Call graphviz to generate the image 238 | props = ' -T'+ftype+' -Nstyle=filled' 239 | parms = ' -o '+fname+' '+tmpname 240 | if self.fontname!='': props += ' -Nfontname="'+self.fontname+'"' 241 | if self.fontsize!='': props += ' -Nfontsize="'+self.fontsize+'"' 242 | if self.size!='': props += ' -Gsize="'+self.size+'"' 243 | if self.mod == 'fdp' and self.len_fdp != '': props += ' -Elen='+self.len_fdp 244 | elif self.mod == 'neato' and self.len_neato != '': props += ' -Elen='+self.len_neato 245 | elif self.mod == 'dot' and self.ranksep_dot != '': props += ' -Granksep='+self.ranksep_dot 246 | elif self.mod == 'twopi' and self.ranksep_twopi != '': props += ' -Granksep='+self.ranksep_twopi 247 | elif self.mod == 'circo' and self.mindist_circo != '': props += ' -Gmindist='+self.mindist_twopi 248 | if self.charset!='': props += ' -Gcharset="'+self.charset+'"' 249 | out,err = popen( self.bin + props + parms ) 250 | logger.debug('calling "'+self.bin + props + parms +'"') 251 | if self.deltmp: os_unlink(tmpname) 252 | return err 253 | -------------------------------------------------------------------------------- /lib/generator/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IzzySoft/HyperSQL/7d59a7e69a99b2ed2938a5c1e0f80e9a914b9121/lib/generator/__init__.py -------------------------------------------------------------------------------- /lib/hypercore/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IzzySoft/HyperSQL/7d59a7e69a99b2ed2938a5c1e0f80e9a914b9121/lib/hypercore/__init__.py -------------------------------------------------------------------------------- /lib/hypercore/cache.py: -------------------------------------------------------------------------------- 1 | """ 2 | $Id$ 3 | HyperSQL simple Cache 4 | Copyright 2010 Itzchak Rehberg & IzzySoft 5 | """ 6 | 7 | import os 8 | import cPickle 9 | from iz_tools.system import fopen 10 | 11 | class cache(object): 12 | """ A simple caching mechanism """ 13 | 14 | def __init__(self,dirname): 15 | """ 16 | Setup the object 17 | @param self 18 | @param string dirname name of the cache directory 19 | """ 20 | try: self.encoding = encoding 21 | except: self.encoding = 'utf-8' 22 | self.dirname = dirname 23 | if not os.path.isdir(dirname): 24 | splitted = dirname.split(os.sep) 25 | temp = "" 26 | for path_element in splitted: # loop through path components, making directories as needed 27 | temp += path_element + os.sep 28 | if os.access(temp, os.F_OK) == 1: 29 | continue 30 | else: 31 | os.mkdir(temp) 32 | 33 | def makename(self,fname,ctype): 34 | """ 35 | Setup cache file name 36 | @param self 37 | @param string fname name of the original file 38 | @param string ctype type of the cached part 39 | @return string cname cache file name 40 | """ 41 | return os.path.join( self.dirname, fname.replace(os.sep,'%2f') + '.' + ctype ) 42 | 43 | def getOName(self,cname,ctype): 44 | """ 45 | Get the name of the original file a cache file belongs to (counter-part to makename) 46 | @param self 47 | @param strinc cname filename of the cache file 48 | @return string fname filename of the original file 49 | """ 50 | #return cname[len(self.dirname):-len(ctype)-1].replace('%2f',os.sep) 51 | return cname[0:-len(ctype)-1].replace('%2f',os.sep) 52 | 53 | def check(self,fname,ctype,ftim=0): 54 | """ 55 | Check whether the copy in cache is up-to-date 56 | @param self 57 | @param string fname name of the original file 58 | @param string ctype type of the cached part 59 | @param optional float ftim time to check the cache against. If 0 (default), 60 | check runs against the file specified by fname. Otherwise, the fname 61 | file itself will be ignored, and cache checked using ftim. So ftim 62 | should correspond to what os.path.getmtime() would have returned. 63 | @return boolean up2date 64 | """ 65 | if ftim==0 and not os.path.isfile(fname): return False # no origin 66 | if not os.path.isdir(self.dirname): return False # no cache dir 67 | cname = self.makename(fname,ctype) 68 | if not os.path.isfile(cname): return False # no cache 69 | if os.path.getsize(cname) == 0: return False # no content 70 | if ftim==0: ftim = os.path.getmtime(fname) 71 | if ftim > os.path.getmtime(cname): # expired 72 | os.unlink(cname) 73 | return False 74 | return True 75 | 76 | def removeObsolete(self,basedir=''): 77 | """ 78 | Cleanup files from cache which do no longer exist in the original location 79 | (i.e. which have been deleted/moved, so they would no longer match) 80 | @param self 81 | @param optional string basedir base directory of original codebase 82 | @return int removed how many files have been removed 83 | """ 84 | if not os.path.isdir(self.dirname): return 0 # no cache dir 85 | names=os.listdir(self.dirname) 86 | dc = 0 87 | for i in names: 88 | splitted = i.split('.') 89 | ctype = splitted[len(splitted)-1] 90 | if not ctype in ['code','formcode']: continue 91 | if not os.path.isfile(self.getOName(i,ctype)): 92 | os.unlink( os.path.join(self.dirname, i) ) 93 | dc += 1 94 | return dc 95 | 96 | 97 | def get(self,fname,ctype): 98 | """ 99 | Get the string from cache content for a given file 100 | @param self 101 | @param string fname name of the original file 102 | @param string ctype type of the cached part 103 | @return string content (empty string if none) 104 | """ 105 | cname = self.makename(fname,ctype) 106 | if not os.path.isfile(cname): return '' # no cache 107 | cfile = fopen(cname,'r','zip') 108 | cont = cfile.read().decode(self.encoding) 109 | cfile.close() 110 | return cont 111 | 112 | def getObj(self,fname,ctype,ftim): 113 | """ 114 | Get the object from cache content for a given file. Uses cPickle 115 | @param self 116 | @param string fname name of the original file 117 | @param string ctype type of the cached part 118 | @return obj content or False if not found in cache 119 | """ 120 | cname = self.makename(fname,ctype) 121 | if not os.path.isfile(cname): return False # no cache 122 | cfile = open(cname,'r') 123 | cont = cPickle.load(cfile) 124 | cfile.close() 125 | return cont 126 | 127 | def put(self,fname,ctype,content): 128 | """ 129 | Save content to cache 130 | @param self 131 | @param string fname name of the original file 132 | @param string ctype type of the cached part 133 | @param string content 134 | """ 135 | cname = self.makename(fname,ctype) 136 | cfile = fopen(cname,'w','zip') 137 | cont = content.encode(self.encoding) 138 | cfile.write( cont ) 139 | cfile.close() 140 | 141 | def putObj(self,fname,ctype,obj): 142 | """ 143 | Save object to cache using cPickle 144 | @param self 145 | @param string fname name of the original file 146 | @param string ctype type of the cached part 147 | @param object obj 148 | """ 149 | cname = self.makename(fname,ctype) 150 | cfile = open(cname,'w') 151 | cPickle.dump(obj,cfile,cPickle.HIGHEST_PROTOCOL) 152 | cfile.close() 153 | 154 | def clear(self,ctype='all'): 155 | """ 156 | Remove cached content 157 | @param self 158 | @param optional ctype type (extension) of cache to remove (default: 'all') 159 | """ 160 | if ctype=='all': 161 | for fname in os.listdir(self.dirname): os.unlink(fname) 162 | else: 163 | ext = '.'+ctype 164 | pos = len(ext) 165 | for fname in os.listdir(self.dirname): 166 | if fname[len(fname)-pos:]==ext: os.unlink(os.path.join(self.dirname,fname)) 167 | 168 | -------------------------------------------------------------------------------- /lib/hypercore/charts.py: -------------------------------------------------------------------------------- 1 | """ 2 | $Id$ 3 | HyperCharts - JavaScript Charts generator using LTDiagram 4 | (requires diagram.js from LTDiagram to be included with your pages JavaScript) 5 | Copyright 2010 Itzchak Rehberg & IzzySoft 6 | 7 | Example usage: 8 | 9 | pie = PieChart('Pie',0,0,10,50) 10 | pie.addPiece(10,'10%') 11 | pie.addPiece(40,'40%') 12 | pie.addPiece(50,'50%') 13 | js = pie.generate() 14 | 15 | bar = ChartLegend('Pie',120,0,80,15,5) 16 | bar.addBar('10%','Give the tenth') 17 | bar.addBar('40%','Forty of hundred years') 18 | bar.addBar('50%','Fifty-Fifty') 19 | js += bar.generate() 20 | 21 | print '' 22 | """ 23 | 24 | class Chart(object): 25 | """ Base class for all the chart classes """ 26 | def __init__(self,name,x,y,offset,cols=[]): 27 | """ 28 | Initialize base values 29 | @param self 30 | @param name name of the object (must be suitable for use as JavaScript variable name) 31 | @param int x x-position 32 | @param int y y-position 33 | @param int offset margin to surrounding elements 34 | @param optional list cols list of HTML color codes to use in the given order 35 | """ 36 | self.name = name 37 | self.x = x 38 | self.y = y 39 | self.offset = offset 40 | self.cols = cols 41 | if len(cols)==0: 42 | self.cols.append('#cc3333') 43 | self.cols.append('#3366ff') 44 | self.cols.append('#dddddd') 45 | self.cols.append('#ff9933') 46 | self.cols.append('#33ff00') 47 | self.vals = [] 48 | self.seq = -1 49 | 50 | def nextVal(self): 51 | """ Get the sequence id for the next piece """ 52 | self.seq += 1 53 | return self.seq 54 | 55 | 56 | class PieChart(Chart): 57 | """ 58 | PieChart generates Pie Charts using LTDiagram 59 | """ 60 | 61 | def __init__(self,name,x,y,offset,rad,cols=[]): 62 | """ 63 | Initialize the pie with base values 64 | @param self 65 | @param string name name of the pie (to be used as JavaScript variable) 66 | @param int x x-position 67 | @param int y y-position 68 | @param int offset margin to surrounding elements 69 | @param int rad radius of the pie 70 | @param optional list cols list of HTML color codes to use in the given order 71 | """ 72 | Chart.__init__(self,name,x,y,offset,cols) 73 | self.rad = rad 74 | 75 | def addPiece(self,val,tooltip=''): 76 | """ 77 | Add the data for a piece 78 | @param self 79 | @param list piece float percentage for the piece, string tooltip 80 | """ 81 | self.vals.append([val,tooltip]) 82 | 83 | def makePiece(self,num,start,stop,tooltip=''): 84 | """ 85 | Create a new piece 86 | @param self 87 | @param int num number (sequential) number of the piece 88 | @param float start start position in 1/100 of the entire pie (equals end position of previous piece or 0 if it's the first) 89 | @param float end end position in 1/100 of the entire pie 90 | @param optional string tooltip tooltip text (if any) 91 | @return string js JavaScript code 92 | """ 93 | js = self.name +'[' + `num` +']=new Pie(' + `self.x` + ',' + `self.y` + ',' + `self.offset` \ 94 | + ',' + `self.rad` + ',' + `start` + '*3.6,' + `stop` + '*3.6,"' + self.cols[num] 95 | if tooltip != '': 96 | js += '","' + tooltip + '");\n' 97 | else: 98 | js += '");\n' 99 | return js 100 | 101 | def generate(self): 102 | """ 103 | Generate a pie chart for the given vals 104 | @param self 105 | @return string js JavaScript code 106 | """ 107 | js = 'var ' + self.name + ' = new Array();\ndocument.open();\n' 108 | sum = 0 109 | for val in self.vals: 110 | js += self.makePiece(self.nextVal(), sum, sum+val[0], val[1]) 111 | sum += val[0] 112 | js += 'function MouseOver' + self.name + '(i) { ' + self.name + '[i].MoveTo("","",10); }\n' 113 | js += 'function MouseOut' + self.name + '(i) { ' + self.name + '[i].MoveTo("","",0); }\n' 114 | js += 'document.close();\n' 115 | return js 116 | 117 | 118 | class ChartLegend(Chart): 119 | """ 120 | ChartLegend generates a group of Bar Charts using LTDiagram as legend for a Pie Chart 121 | """ 122 | 123 | def __init__(self,pie,x,y,wid,hei,offset,cols=[],tcols=[]): 124 | """ 125 | Initialize the pie with base values 126 | @param self 127 | @param string pie name of the pie this legend is for 128 | @param int x x-position 129 | @param int y y-position 130 | @param int wid width of the bars 131 | @param int hei height of the bars 132 | @param int offset space between the bars 133 | @param optional list cols list of HTML color codes to use for the background in the given order 134 | @param optional list tcols list of HTML color codes to use for the text in the given order 135 | """ 136 | Chart.__init__(self,pie,x,y,offset,cols) 137 | self.wid = wid 138 | self.hei = hei 139 | self.tcols = tcols 140 | if len(tcols)==0: 141 | self.tcols.append('#ffffff') 142 | self.tcols.append('#ffffff') 143 | self.tcols.append('#000000') 144 | self.tcols.append('#000000') 145 | self.tcols.append('#000000') 146 | 147 | def addBar(self,text,tooltip=''): 148 | """ 149 | Add the data for a bar item 150 | @param self 151 | @param string text what to write on the bar 152 | """ 153 | self.vals.append([text,tooltip]) 154 | 155 | def makeBar(self,num): 156 | """ 157 | Create a new bar 158 | @param int rownum number of the bar 159 | """ 160 | top = self.y + num * (self.hei + self.offset) 161 | bottom = top + self.hei 162 | js = 'new Bar(' + `self.x` + ',' + `top` + ',' + `self.x + self.wid` + ',' + `bottom` \ 163 | + ',"' + self.cols[num] + '","' + self.vals[num][0] + '","' + self.tcols[num] \ 164 | + '","' + self.vals[num][1] + '","void(0)","MouseOver' + self.name + '(' + `num` +')",' \ 165 | + '"MouseOut' + self.name + '(' + `num` + ')");\n' 166 | return js 167 | 168 | def generate(self): 169 | """ 170 | Generate the legend 171 | """ 172 | js = 'document.open();\n' 173 | for i in range(len(self.vals)): 174 | js += self.makeBar(i) 175 | js += 'document.close();\n' 176 | return js 177 | 178 | -------------------------------------------------------------------------------- /lib/hypercore/codeformatter.py: -------------------------------------------------------------------------------- 1 | """ 2 | $Id$ 3 | HyperSQL Code Formatter 4 | Copyright 2010 Itzchak Rehberg & IzzySoft 5 | """ 6 | 7 | from cgi import escape # for htmlspecialchars 8 | from iz_tools.typecheck import is_numeric 9 | import re 10 | 11 | def hypercode(line_list,keywords,types,cssclass='sql'): 12 | """ 13 | Format (SQL) code passed by the line_list parameter. Nothing is prepended 14 | or appended (so no opening CODE tag or the like). 15 | As the lists of keywords and types are passed to this function, all kind 16 | of code could be highlighted passing the corresponding lists. 17 | @param list line_list List of code lines 18 | @param list keywords keywords to highlight 19 | @param list types types to highlight 20 | @param string cssclass prefix for the CSS-classes to use. Defaults to 'sql'. 21 | Used classes (taking the SQL as example) are: 'sqlcomment' for comments, 22 | 'sqlbrace' for opening parenthesis, 'sqlkeyword' for keywords, and 23 | 'sqltype' for types. 24 | Returns: html_string HTML formatted code 25 | """ 26 | 27 | # we need leading zeroes for the line numbers 28 | line_number_width = len(`len(line_list)`) # number of chars in "number of lines of text" 29 | 30 | html = '' 31 | commentmode = 0 # 0 no comment, 1 '--', 2 '/*', 3 in_singlequote_string 32 | splitter = re.compile('([\'\s,\.;\:%\(\)\}\{\|\<\>])') 33 | for line_number in range(len(line_list)): 34 | line = escape(line_list[line_number]).replace('<','<').replace('>','>') 35 | if line.strip()[0:2]=='--': 36 | text = '' + line + '' 37 | else: 38 | text = '' 39 | if commentmode==2: 40 | text += '' 41 | oldelem = '' 42 | tokens = splitter.split(line) 43 | for idx in range(len(tokens)): 44 | elem = tokens[idx] 45 | if commentmode==0: 46 | if elem[0:2]=='--': 47 | text += '' + elem 48 | commentmode = 1 49 | elif elem[0:2]=='/*': 50 | text += '' + elem 51 | commentmode = 2 52 | elif elem=="'": 53 | text += '\'' 54 | commentmode = 3 55 | elif elem[0:1]=="'": 56 | text += '\'' + elem[1:len(elem)-1] 57 | if elem[len(elem)-1:]=="'": 58 | text += '\'' 59 | else: 60 | text += elem[len(elem)-1:] 61 | commentmode = 3 62 | elif elem in [',', ':', '=', '(', ')', '[', ']', '{', '}'] \ 63 | or (elem==';' and (len(oldelem)==0 or oldelem[0]!='&')): # skip html entities for ; 64 | text += '' + elem + '' 65 | elif elem in ['<','>']: 66 | text += '' + escape(elem) + '' 67 | elif is_numeric(elem): 68 | text += '' + elem + '' 69 | elif elem in keywords: 70 | text += '' + elem + '' 71 | elif elem in types: 72 | text += '' + elem + '' 73 | else: text += elem 74 | elif commentmode==2: 75 | if elem[len(elem)-2:]=='*/': 76 | text += escape(elem) + '' 77 | commentmode = 0 # clear at comment end 78 | else: text += escape(elem) 79 | elif commentmode==3: 80 | if elem=="'": 81 | if not ( idx>0 and tokens[idx-1]=="'" ) or ( len(tokens)>idx and tokens[idx+1]=="'" ): 82 | text += '\'' 83 | commentmode = 0 84 | else: text += escape(elem) 85 | else: # 1 for now 86 | text += escape(elem) 87 | oldelem = elem # remember for back-check 88 | if commentmode==1: 89 | text += '' 90 | commentmode = 0 # clear at line end 91 | elif commentmode==2: 92 | text += '' 93 | #if text[len(text)-1:] != '\n': 94 | # text += "\n" 95 | text = text.replace('\n\n','\n') 96 | zeroes = (1 + line_number_width - len(`line_number+1`)) * "0" # leading zeroes for line numbers (+1 since we start with 0) 97 | html += "" # hyperlink target 98 | html += zeroes + `line_number+1` + ": " + text #text 99 | return html 100 | -------------------------------------------------------------------------------- /lib/hypercore/config.py: -------------------------------------------------------------------------------- 1 | """ 2 | $Id$ 3 | HyperSQL Configuration Class 4 | Copyright 2010 Itzchak Rehberg & IzzySoft 5 | """ 6 | 7 | from iz_tools.IniParser import IniParser 8 | from locale import getdefaultlocale 9 | from os import environ, path as ospath, sep as ossep 10 | from sys import argv as sysargv 11 | import gettext 12 | 13 | # Setup gettext 14 | langs = [] 15 | lc, encoding = getdefaultlocale() 16 | if (lc): 17 | langs = [lc,lc[:2]] 18 | language = environ.get('LANGUAGE', None) 19 | if (language): 20 | langs += language.split(":") 21 | langs += ['en_US'] 22 | langpath = ospath.split(sysargv[0])[0] + ossep + 'lang' 23 | gettext.bindtextdomain('hypersql', langpath) 24 | gettext.textdomain('hypersql') 25 | lang = gettext.translation('hypersql', langpath, languages=langs, fallback=True) 26 | _ = lang.ugettext 27 | 28 | 29 | 30 | class HyperConf(IniParser): 31 | """ 32 | An extension to ConfigParser, mainly adding a Default parameter to 33 | option retrieval - plus a getList method. 34 | As for the defaults which may be passed to ConfigParser.__init__, 35 | they cannot be assigned to a specific section - so if the same keyword 36 | exists in multiple sections, those defaults are useless. That's why 37 | HyperConf allows to pass defaults to the get methods. 38 | """ 39 | def __init__(self,defaults=None): 40 | """ 41 | Initialize the instance 42 | @param self 43 | @param defaults A dictionary of intrinsic defaults. The keys must be 44 | strings, the values must be appropriate for %()s string 45 | interpolation. Note that `__name__' is always an intrinsic 46 | default; it's value is the section's name. These defaults are 47 | not section specific. 48 | """ 49 | IniParser.__init__(self,defaults) 50 | 51 | def initDefaults(self): 52 | """ 53 | Initialize configuration with HyperSQL default settings 54 | @param self 55 | """ 56 | # Section GENERAL 57 | general = dict( 58 | title_prefix='HyperSQL', 59 | project_info='This is my HyperSQL project.', 60 | project_info_file='', 61 | project_logo='', 62 | project_logo_url='', 63 | ticket_url='', 64 | wiki_url='', 65 | encoding='utf8', 66 | ) 67 | # Section FILENAMES 68 | filenames = dict ( 69 | top_level_directory = '.', 70 | rcsnames = 'RCS CVS .svn', 71 | ignorefile = '.hsqlignore', 72 | sql_file_exts = 'sql pks pkb pkg pls', 73 | cpp_file_exts = 'c cpp h', 74 | htmldir = 'html/', 75 | css_file = 'hypersql.css', 76 | css_url = '', 77 | custom_css_files = '', 78 | unittest_dir = 'unittests/', 79 | file = 'FileNameIndexNoPathnames.html', 80 | filepath = 'FileNameIndexWithPathnames.html', 81 | view = 'ViewIndex.html', 82 | mview = 'MViewIndex.html', 83 | tab = 'TableIndex.html', 84 | trigger = 'TriggerIndex.html', 85 | type = 'TypeIndex.html', 86 | synonym = 'SynonymIndex.html', 87 | sequence = 'SequenceIndex.html', 88 | package = 'PackageIndex.html', 89 | package_full = 'PackagesWithFuncsAndProcsIndex.html', 90 | function = 'FunctionIndex.html', 91 | procedure = 'ProcedureIndex.html', 92 | form = 'FormIndex.html', 93 | form_full = 'FormFullIndex.html', 94 | bug = 'BugIndex.html', 95 | todo = 'TodoIndex.html', 96 | report = 'ReportIndex.html', 97 | stat = 'StatIndex.html', 98 | depgraph = 'DepGraphIndex.html' 99 | ) 100 | # Section PAGENAMES 101 | pagenames = dict ( 102 | file = _('File Name Index'), 103 | filepath = _('File Names by Path Index'), 104 | view = _('View Index'), 105 | mview = _('Materialized View Index'), 106 | tab = _('Table Index'), 107 | trigger = _('Trigger Index'), 108 | type = _('Type Index'), 109 | synonym = _('Synonym Index'), 110 | sequence = _('Sequence Index'), 111 | package = _('Package Index'), 112 | package_full = _('Full Package Listing'), 113 | function = _('Function Index'), 114 | procedure = _('Procedure Index'), 115 | form = _('Form Index'), 116 | form_full = _('Full Forms Listing'), 117 | bug = _('Bug List'), 118 | todo = _('Todo List'), 119 | report = _('Validation Report'), 120 | stat = _('Code Statistics'), 121 | depgraph = _('Dependency Graphs') 122 | ) 123 | # Section PAGES 124 | pages = dict ( 125 | file = '1', 126 | filepath = '1', 127 | view = '0', 128 | mview = '0', 129 | tab = '0', 130 | trigger = '0', 131 | type = '0', 132 | synonym = '0', 133 | sequence = '0', 134 | package = '1', 135 | package_full = '1', 136 | function = '1', 137 | procedure = '1', 138 | form = '0', 139 | form_full = '0', 140 | bug = '1', 141 | todo = '1', 142 | report = '0', 143 | stat = '0', 144 | depgraph = '1' 145 | ) 146 | # Section DISPLAY 147 | display = dict ( 148 | navbar_elems_per_row = '4', 149 | link_urls = '1' 150 | ) 151 | # Section PROCESS 152 | process = dict ( 153 | purge_on_start = '0', 154 | blind_offset = '0', 155 | include_source = '1', 156 | include_source_limit = '0', 157 | javadoc = '1', 158 | export_unittests = '0', 159 | whereused_scan_shortrefs = '0', 160 | whereused_scan_instring = '0', 161 | cache = '1', 162 | link_code_calls = '1' 163 | ) 164 | # Section LOGGING 165 | logg = dict ( 166 | screenlevel = 'ERROR', 167 | filelevel = 'DEBUG', 168 | logfile = 'HyperSQL.log', 169 | progress = '1', 170 | verification = '0', 171 | maxkbytes = '0', 172 | backupcount = '3', 173 | capture_warnings = '0' 174 | ) 175 | # Section VERIFICATION 176 | verification = dict ( 177 | javadoc_shortdesc_mode = 'unit', 178 | javadoc_mandatory = '0', 179 | javadoc_mandatory_objects = 'func proc pkg', 180 | verify_javadoc = '0', 181 | author_in_report = '0', 182 | mandatory_tags = '', 183 | mandatory_code_tags = '', 184 | mandatory_codetag_objects = 'func proc pkg', 185 | stats_javadoc_forms = '0', 186 | verify_forms = '0' 187 | ) 188 | # Section DEPGRAPH 189 | depgraph = dict ( 190 | processor = 'fdp', 191 | fontname = '', 192 | fontsize = '', 193 | ranksep_dot = '', 194 | ranksep_twopi = '', 195 | len_neato = '', 196 | len_fdp = '', 197 | mindist_circo = '', 198 | objects = 'view pkg proc func synonym', 199 | file2file = '1', 200 | file2object = '0', 201 | object2file = '1', 202 | object2object = '1', 203 | deltmp = '1', 204 | ) 205 | # Section COLORS 206 | colors = dict ( 207 | pkg = '#0000ff #ffffff', 208 | proc = '#3366ff #ffffff', 209 | func = '#66aaff #000000', 210 | tab = '#774411 #ffffff', 211 | trigger = '#33ffff #000000', 212 | mview = '#bb6611 #ffffff', 213 | view = '#eeaa55 #000000', 214 | synonym = '#00ff00 #000000', 215 | sequence = '#ffcc00 #000000', 216 | typ = '#ffff33 #000000', 217 | form = '#993366 #ffffff', 218 | bug = '#ff0000 #ffffff', 219 | warn = '#eeaa55 #000000', 220 | todo = '#3366ff #ffffff', 221 | code = '#0000ff #ffffff', 222 | comment = '#bb6611 #ffffff', 223 | mixed = '#eeaa55 #000000', 224 | empty = '#dddddd #000000', 225 | file = '#dddddd #000000', 226 | filebig = '#ff0000 #ffffff', 227 | file100k = '#ff4422 #ffffff', 228 | file50k = '#dd9944 #000000', 229 | file25k = '#ffcc00 #000000', 230 | file10k = '#00ff00 #000000', 231 | file1000l = '#0000ff #ffffff', 232 | file400l = '#ffcc00 #000000' 233 | ) 234 | # Section FORMS 235 | forms = dict ( 236 | pck_mark = 'Package Body', 237 | pcks_mark = 'Package-Spez.', 238 | proc_mark = 'Prozedur', 239 | func_mark = 'Funktion' 240 | ) 241 | # Generate the final dict (dict() allows no nesting) 242 | vals = {} 243 | vals['General'] = general 244 | vals['FileNames'] = filenames 245 | vals['PageNames'] = pagenames 246 | vals['Pages'] = pages 247 | vals['Process'] = process 248 | vals['Logging'] = logg 249 | vals['Verification'] = verification 250 | vals['DepGraph'] = depgraph 251 | vals['Colors'] = colors 252 | vals['Forms'] = forms 253 | self.setVals( vals ) 254 | -------------------------------------------------------------------------------- /lib/hypercore/elements.py: -------------------------------------------------------------------------------- 1 | """ 2 | $Id$ 3 | HyperSQL Core elements 4 | Copyright 2001 El Paso Energy, Inc. All Rights Reserved 5 | Copyright 2010 Itzchak Rehberg & IzzySoft 6 | """ 7 | from __future__ import division ### temporary to verify Python v3 compatibility 8 | __revision__ = '$Id$' 9 | 10 | from .javadoc import JavaDoc, PackageTaskList 11 | from iz_tools.typecheck import nullDict 12 | 13 | class ElemInfo(object): 14 | """ Object to hold information about a function, or procedure """ 15 | def __init__(self): 16 | """ Initialize the object with useful defaults """ 17 | self.__dict__['name'] = "" 18 | self.lineNumber = -1 19 | self.whatUsed = {} # file name key, fileInfo and line number list 20 | self.whereUsed = {} # file name key, fileInfo and line number list 21 | self.uniqueNumber = 0 # used to create unique file name for where used list 22 | self.parent = None 23 | self.paramCount = 0 24 | self.javadoc = JavaDoc() 25 | def __setattr__(self, name, val): 26 | """ 27 | Overwrite some setters which require special behavior, as e.g. the HTML 28 | anchor name needs to be implicitly set with the elements name 29 | """ 30 | # the HTML Anchor corresponding to this element depends on the elements 31 | # name, plus it must be unique for the generated HTML document. Hence 32 | # the anchor name is stored in the FileInfo object and set when the name 33 | # of the element is set: 34 | if name=='name': 35 | if self.uniqueNumber == 0: self.uniqueNumber = metaInfo.NextIndex() 36 | master = self 37 | while hasattr(master,'parent') and master.parent: 38 | master = master.parent 39 | if hasattr(master,'anchorNames'): 40 | foo = True 41 | if not val and self.uniqueNumber in master.anchorNames: 42 | del master.anchorNames[self.uniqueNumber] 43 | elif not val in master.anchorNames.values(): 44 | master.anchorNames[self.uniqueNumber] = (val,self) 45 | else: 46 | i = 0 47 | while True: 48 | i += 1 49 | aname = val+str(i) 50 | if aname in master.anchorNames.values(): continue 51 | master.anchorNames[self.uniqueNumber] = (aname,self) 52 | break 53 | break; 54 | self.__dict__[name] = val 55 | def __repr__(self): 56 | """ Basic information for simple debug """ 57 | mytype = type(self).__name__ 58 | if self.lineNumber<0: return 'Empty '+mytype+' object' 59 | if self.name: ret = mytype+' object "' + self.name + '"' 60 | else: ret = 'unnamed '+mytype+' object' 61 | if self.parent: ret += ' with parent ' + repr(self.parent) 62 | else: ret += ' without parent' 63 | return ret + ', attached JavaDoc:\n' + repr(self.javadoc) + '\n' 64 | 65 | class StandAloneElemInfo(ElemInfo): 66 | """ Object to hold information about stand-alone elements (tables, views, etc.) """ 67 | def __init__(self): 68 | """ Initialize the object with useful defaults """ 69 | ElemInfo.__init__(self) 70 | self.bugs = PackageTaskList() 71 | self.todo = PackageTaskList() 72 | self.verification = PackageTaskList() 73 | def __repr__(self): 74 | ret = ElemInfo.__repr__(self)+'\n* Name: '+self.name+'\n' 75 | ret += '* %d known bugs\n' % self.bugs.allItemCount() 76 | ret += '* %d known todos\n' % self.todo.allItemCount() 77 | ret += '* %d known verification errors\n' % self.verification.allItemCount() 78 | return ret 79 | 80 | class PackageInfo(StandAloneElemInfo): 81 | """ Object to hold information about a package """ 82 | def __init__(self): 83 | """ Initialize the object with useful defaults """ 84 | StandAloneElemInfo.__init__(self) 85 | self.functionInfoList = [] 86 | self.procedureInfoList = [] 87 | def __repr__(self): 88 | ret = StandAloneElemInfo.__repr__(self) 89 | ret += '* %d functions\n' % len(self.functionInfoList) 90 | ret += '* %d procedures\n' % len(self.procedureInfoList) 91 | return ret 92 | 93 | class FormInfo(StandAloneElemInfo): 94 | """ Object to hold information about an Oracle Form """ 95 | def __init__(self): 96 | """ Initialize the object with useful defaults """ 97 | StandAloneElemInfo.__init__(self) 98 | self.formType = '' 99 | self.title = '' 100 | self.objects = 0 101 | self.stats = {} 102 | self.codesize = 0 103 | self.packageInfoList = [] 104 | self.triggerInfoList = [] 105 | self.functionInfoList = [] 106 | self.procedureInfoList = [] 107 | def __repr__(self): 108 | """ Basic information for debug """ 109 | if self.formType == '': return 'empty form' 110 | ret = 'Form '+self.formType+' "'+self.name+'":\n' \ 111 | + '* %d objects\n' % self.objects \ 112 | + '* %d packages\n' % len(self.packageInfoList) \ 113 | + '* %d functions\n' % len(self.functionInfoList) \ 114 | + '* %d procedures\n' % len(self.procedureInfoList) \ 115 | + '* %d trigger\n' % len(self.triggerInfoList) \ 116 | + '* Stats: '+repr(self.stats)+'\n' 117 | if self.parent: ret += '* Parent: '+self.parent.fileName 118 | return ret 119 | 120 | class FileInfo(object): 121 | """ Object to hold information about a file """ 122 | def __init__(self): 123 | """ Initialize the object with useful defaults """ 124 | self.fileName = "" 125 | self.fileType = "" # cpp files are only scanned for sql "where used" information 126 | self.anchorNames = {} # HTML Anchor names for the page generated for this file: uniqueID=(name,element) 127 | self.viewInfoList = [] 128 | self.mviewInfoList = [] 129 | self.tabInfoList = [] 130 | self.synInfoList = [] 131 | self.seqInfoList = [] 132 | self.packageInfoList = [] 133 | self.functionInfoList = [] 134 | self.procedureInfoList = [] 135 | self.triggerInfoList = [] 136 | self.typeInfoList = [] 137 | self.formInfoList = [] 138 | self.uniqueNumber = 0 # used to create unique file name for where used list (old variant) 139 | self.uniqueName = '' # used to create unique file name for where used list (new variant) 140 | self.lines = 0 141 | self.bytes = 0 142 | self.xmlbytes = 0 143 | self.xmlcodebytes = 0 144 | 145 | def __repr__(self): 146 | ret = self.fileType +' file "'+ self.fileName +'":\n ' 147 | if self.fileType.lower() == 'xml': 148 | ret += '%d bytes including %d bytes of code' % (self.xmlbytes, self.xmlcodebytes) 149 | else: 150 | ret += '%d lines with %d bytes' % (self.lines, self.bytes) 151 | return ret+'\n Unique Name: "'+self.uniqueName+'"\n' 152 | 153 | def sortLists(self): 154 | """ Sort all lists alphabetically by object name """ 155 | if len(self.viewInfoList) > 0: self.viewInfoList.sort(key=lambda x: x.name) 156 | if len(self.packageInfoList) > 0: 157 | for p in self.packageInfoList: 158 | if len(p.functionInfoList) > 0: p.functionInfoList.sort(key=lambda x: x.name) 159 | if len(p.procedureInfoList) > 0: p.procedureInfoList.sort(key=lambda x: x.name) 160 | 161 | def getHtmlName(self): 162 | """ Get the name of the corresponding HTML file """ 163 | return self.uniqueName + '.html' 164 | 165 | 166 | class MetaInfo: 167 | """ Object to hold global information (e.g. configuration options) """ 168 | def __init__(self): 169 | """ Initialize the object with useful defaults """ 170 | self.fileInfoList = [] 171 | self.scriptName = "" 172 | self.htmlDir = "" 173 | self.versionString = "" 174 | self.indexForWhereUsedFiles = 0 175 | self.linesOfCode = {} 176 | self.linesOfCode['totals'] = 0 177 | self.linesOfCode['code'] = 0 178 | self.linesOfCode['comment'] = 0 179 | self.linesOfCode['empty'] = 0 180 | self.indexPage = nullDict() # filename 181 | self.indexPageName = nullDict() 182 | self.depGraph = {} 183 | self.depGraph['file2file'] = [] 184 | self.depGraph['file2object'] = [] 185 | self.depGraph['object2file'] = [] 186 | self.depGraph['object2object'] = [] 187 | self.colors = {} 188 | 189 | def NextIndex(self): 190 | """ 191 | Used to generate unique file names for where used indices 192 | @return int unique number 193 | """ 194 | self.indexForWhereUsedFiles += 1 195 | return self.indexForWhereUsedFiles 196 | 197 | def incLoc(self,what,incBy=1): 198 | """ 199 | Increase the number of 'lines of code' for the given type 200 | @param self 201 | @param string type ('totals','code','comment','empty') 202 | @param optional int incBy increment by this value (default: 1) 203 | """ 204 | if what not in ['totals','code','comment','empty']: 205 | return 206 | self.linesOfCode[what] += incBy 207 | 208 | def getLoc(self,what): 209 | """ 210 | Return the number of 'lines of code' for the given type 211 | @param self 212 | @param string type ('totals','code','comment','empty','mixed') 213 | @return int loc lines of code for the given type 214 | """ 215 | if what not in ['totals','code','comment','empty','mixed']: 216 | return 0 217 | if what == 'mixed': 218 | return self.getLoc('totals') - self.getLoc('code') - self.getLoc('comment') - self.getLoc('empty') 219 | return self.linesOfCode[what] 220 | 221 | def getLocPct(self,what,decs=2): 222 | """ 223 | Return the percentage of 'lines of code' for the given type 224 | @param self 225 | @param string type ('totals','code','comment','empty','mixed') 226 | @param optional int decs round the value to how many decimals? Default: 2 227 | @return float loc percentage of lines of code for the given type 228 | """ 229 | if what not in ['totals','code','comment','empty','mixed']: 230 | return 0.0 231 | if self.getLoc('totals') != 0: return round( (float(self.getLoc(what)) / self.getLoc('totals')) * 100, decs) 232 | else: return round(0,decs) 233 | 234 | def getFileStat(self,what): 235 | """ 236 | Return some file statistics 237 | @param self 238 | @param string type ('files','xmlfiles','avg lines','min lines','max lines', 239 | 'sum bytes','avg bytes','min bytes','max bytes') 240 | @return number stat_value value for the requested stat. Depending on its 241 | type, this may be either an integer or a float 242 | """ 243 | if what not in ['files','xmlfiles','avg lines','min lines','max lines','sum bytes','avg bytes','min bytes','max bytes']: 244 | return 0 245 | fileCount = len(self.fileInfoList) 246 | if what in ['sum bytes','avg bytes','min bytes','max bytes']: 247 | sumBytes = 0 248 | if len(self.fileInfoList) > 0: 249 | minBytes = self.fileInfoList[0].bytes 250 | maxBytes = self.fileInfoList[0].bytes 251 | else: 252 | minBytes = 0 253 | maxBytes = 0 254 | for file in self.fileInfoList: 255 | sumBytes += file.bytes 256 | if file.bytes < minBytes: 257 | minBytes = file.bytes 258 | elif file.bytes > maxBytes: 259 | maxBytes = file.bytes 260 | if what in ['min lines','max lines']: 261 | if len(self.fileInfoList) > 0: 262 | minLines = self.fileInfoList[0].lines 263 | maxLines = self.fileInfoList[0].lines 264 | else: 265 | minLines = 0 266 | maxLines = 0 267 | for file in self.fileInfoList: 268 | if file.lines < minLines: 269 | minLines = file.lines 270 | elif file.lines > maxLines: 271 | maxLines = file.lines 272 | if what == 'files': 273 | return fileCount 274 | elif what == 'xmlfiles': 275 | sumfiles = 0 276 | for file in self.fileInfoList: 277 | if file.fileType == 'xml': sumfiles += 1 278 | return sumfiles 279 | elif what == 'avg lines': 280 | return self.getLoc('totals') / fileCount 281 | elif what == 'min lines': 282 | return minLines 283 | elif what == 'max lines': 284 | return maxLines 285 | elif what == 'sum bytes': 286 | return sumBytes 287 | elif what == 'avg bytes': 288 | return float(sumBytes/fileCount) 289 | elif what == 'min bytes': 290 | return minBytes 291 | elif what == 'max bytes': 292 | return maxBytes 293 | 294 | def getFileSizeStat(self,boundary): 295 | """ 296 | Obtain some size statistics 297 | @param self 298 | @param list boundary size groups you want to split the stats into 299 | @return dict stats 300 | """ 301 | sumBytes = self.getFileStat('sum bytes') 302 | fileCount = len(self.fileInfoList) 303 | boundary.sort() 304 | stat = {} 305 | for limit in boundary: 306 | stat[limit] = 0 307 | for file in self.fileInfoList: 308 | for limit in boundary: 309 | if file.bytes < limit: 310 | stat[limit] += 1 311 | break 312 | return stat 313 | 314 | def getFileLineStat(self,boundary): 315 | """ 316 | Obtain some line statistics 317 | @param self 318 | @param list boundary size groups you want to split the stats into 319 | @return dict stats 320 | """ 321 | sumLines = self.getLoc('totals') 322 | fileCount = len(self.fileInfoList) 323 | boundary.sort() 324 | stat = {} 325 | for limit in boundary: 326 | stat[limit] = 0 327 | for file in self.fileInfoList: 328 | for limit in boundary: 329 | if file.lines < limit: 330 | stat[limit] += 1 331 | break 332 | return stat 333 | 334 | metaInfo = MetaInfo() # This is needed by different modules, so the instance is created here for import issues 335 | 336 | -------------------------------------------------------------------------------- /lib/hypercore/gettext_init.py: -------------------------------------------------------------------------------- 1 | """ 2 | $Id$ 3 | HyperSQL gettext basics 4 | Copyright 2010 Itzchak Rehberg & IzzySoft 5 | 6 | This evaluates the basic settings required for gettext 7 | """ 8 | 9 | # Setup gettext support 10 | import gettext 11 | from locale import getdefaultlocale 12 | from sys import argv as pargs 13 | from os import environ as os_environ, path as os_path, sep as os_sep 14 | langs = [] 15 | lc, encoding = getdefaultlocale() 16 | if (lc): 17 | langs = [lc,lc[:2]] 18 | language = os_environ.get('LANGUAGE', None) 19 | if (language): 20 | langs += language.split(":") 21 | langs += ['en_US'] 22 | langpath = os_path.split(pargs[0])[0] + os_sep + 'lang' 23 | 24 | """ 25 | # Example for what has to be done in a module afterwards: 26 | 27 | from gettext_init import langpath, langs 28 | import gettext 29 | 30 | gettext.bindtextdomain('module_name', langpath) 31 | gettext.textdomain('module_name') 32 | lang = gettext.translation('module_name', langpath, languages=langs, fallback=True) 33 | _ = lang.ugettext 34 | """ -------------------------------------------------------------------------------- /lib/hypercore/helpers.py: -------------------------------------------------------------------------------- 1 | """ 2 | HyperSQL Core helper functions 3 | Copyright 2001 El Paso Energy, Inc. All Rights Reserved 4 | Copyright 2010 Itzchak Rehberg & IzzySoft 5 | """ 6 | from __future__ import division ### temporary to verify Python v3 compatibility 7 | __revision__ = '$Id$' 8 | 9 | from locale import format as loc_format, setlocale, LC_NUMERIC 10 | from iz_tools.text import * # includes import re # for eatStrings, countEmptyLines, cleanSQL 11 | from iz_tools.system import getCallingModule # this module shall not be included in log entries ;) 12 | from hypercore.logger import logg 13 | logger = logg.getLogger() 14 | 15 | # Setup gettext support 16 | import gettext 17 | from .gettext_init import langpath, langs 18 | gettext.bindtextdomain('hypersql', langpath) 19 | gettext.textdomain('hypersql') 20 | lang = gettext.translation('hypersql', langpath, languages=langs, fallback=True) 21 | _ = lang.ugettext 22 | 23 | 24 | try: 25 | setlocale(LC_NUMERIC, '') 26 | except: 27 | None 28 | 29 | def num_format(num, places=0): 30 | """ 31 | Format a number as a string 32 | @param number Number to format 33 | @param int places 34 | @return string formatted_number 35 | """ 36 | return loc_format("%.*f", (places, num), True) 37 | 38 | def size_format(size,decs=2): 39 | """ 40 | Format file size as a string. Depending on the size, use the best fitting 41 | unit (B/K/M/G/T), and call num_format to care for the resulting number. 42 | Example: "size_format(2048,1)" would return "2.0K" on US locale ("2,0K" on German) 43 | @param int size Size in bytes 44 | @param optional int decs Decimals to use (Default: 2) 45 | @return string formatted_size 46 | """ 47 | suffixes = [("B",2**10), ("K",2**20), ("M",2**30), ("G",2**40), ("T",2**50)] 48 | for suf, lim in suffixes: 49 | if size > lim: 50 | continue 51 | else: 52 | return num_format( round(size/float(lim/2**10),decs), decs )+suf 53 | 54 | 55 | def getWordLineNr(text,word): 56 | """ 57 | Wrapper to getWordLineNr from iz_tools.text catching possible errors 58 | @param string text Text to search IN 59 | @param string word WORD to search FOR 60 | @return list res 61 | """ 62 | try: 63 | res = getWordLineNo(text,word) 64 | except: 65 | logger.error(_('RegExp error searching for "%s"'), word) 66 | res = [] 67 | return res 68 | 69 | 70 | def eatStrings(text): 71 | """ 72 | eat (single-quoted) string contents and return remaining text. 73 | Keeps line count intact (multi-lined strings will be replaced by empty lines) 74 | @param string text text to parse 75 | @return string text text with strings removed 76 | @return boolean matched_string whether any strings where encountered 77 | """ 78 | def repl(m): 79 | ret = '\n'*m.group(0).count('\n') 80 | return '\'%s\'' % ret 81 | strpatt = re.compile("('[^']*')+") # String-Regexp 82 | text, matches = re.subn(strpatt,repl,text) 83 | return text, matches>0 84 | 85 | def countEmptyLines(text): 86 | """ 87 | Count lines consisting only of spaces, tabs, and formfeeds. 88 | @param string text Text to investigate 89 | @return int hits Number of empty lines (according to above specification) 90 | """ 91 | patt = re.compile("(^[ \t\f\v]*$)",re.M) 92 | return len(patt.findall(text)) 93 | 94 | def cleanSQL(text,strings=False): 95 | """ 96 | Remove comments (and optionally strings) from text 97 | @param mixed text Text to purge (either as string or list of strings aka lines) 98 | @param boolean strings Whether to remove (single-quoted) strings as well 99 | @return mixed text Purged text (same type as input) 100 | @return dict stat Some line stats: int (all,empty,comment,mixed,code), boolean matched_string 101 | @raise TypeError when text neither str nor list 102 | """ 103 | # define some regExp patterns: 104 | pattIComm = re.compile('[ \t\f\v]*--.*',re.M) # inline comment 105 | pattMComm = re.compile(r'\S[ \t\f\v]*--.*',re.M)# inline comment with preceding code 106 | pattBComm = re.compile('/\\*.*?\\*/',re.M|re.S) # block comment 107 | pattEnd = re.compile('\s*\n$') # text ending with LF 108 | 109 | # check input, make sure we have 'str' to process 110 | inputType = type(text).__name__ 111 | if inputType == 'list': text = ''.join(text) 112 | elif inputType == 'str' : pass 113 | else: raise TypeError('First parameter to cleanSQL must be either str or list - %s given' % inputType) 114 | 115 | # stats: linecount, empty, and mixed lines 116 | all = text.count('\n') 117 | empty = countEmptyLines(text) 118 | mixed = len(pattMComm.findall(text)) 119 | 120 | # we need this to fix-up stats based on '\n' 121 | if len(pattEnd.findall(text))>0: lf_end = True 122 | else: lf_end = False 123 | 124 | # Remove comments (and update corresponding stats) 125 | text = re.sub(pattIComm,'',text) # inline comments 126 | for hit in pattBComm.findall(text): # Block comments 127 | nlc = hit.count('\n') 128 | text = text.replace(hit,'\n'*nlc) 129 | comment = countEmptyLines(text) - empty 130 | code = text.count('\n') +1 - mixed - empty - comment 131 | 132 | # remove strings (if advised to do so) 133 | if strings: 134 | text, matched_string = eatStrings(text) 135 | else: 136 | matched_string = False 137 | 138 | # fixup stats, and make sure to return the text using the correct type 139 | if lf_end: empty -= 1 140 | else: all += 1 141 | if inputType == 'list': text = text.split('\n') 142 | return text, {'all':all, 'empty':empty, 'comment':comment, 'mixed':mixed, 'code':code, 'matched_string':matched_string} 143 | 144 | -------------------------------------------------------------------------------- /lib/hypercore/logger.py: -------------------------------------------------------------------------------- 1 | """ 2 | Provide logging for all modules 3 | Automatically creates an instance of our Logger class - so basically only 4 | logg needs to be imported from here. Of course, the first time the configuration 5 | has to take place (logg.setScreenLog() and logg.setFileLog()) - afterwards only 6 | logg.getLogger() will be needed when a logger shall be used. 7 | """ 8 | __revision__ = '$Id$' 9 | 10 | import logging 11 | 12 | class Logger(object): 13 | """ 14 | Handles Logger stuff for the entire app 15 | """ 16 | def __init__(self): 17 | """ 18 | Very basic initialization of a root logger 19 | """ 20 | self.logger = logging.getLogger(); 21 | self.logger.setLevel(logging.DEBUG) 22 | logging.addLevelName(99,'NONE') 23 | self.ch = logging.StreamHandler() # screen logging handler 24 | self.fh = None # file logging handler 25 | #logging.captureWarnings = False # introduced with Python 2.7, False is already default 26 | 27 | def captureWarnings(self,capture=False): 28 | """ 29 | Enable/Disable capture of Python warnings to the logger. As this feature 30 | was introduced with Python v2.7, this method will do nothing if a lower 31 | version of Python is calling it. 32 | @param optional boolean capture (default: False) 33 | """ 34 | if sys.hexversion > 0x02070000: 35 | logging.captureWarnings(captureWarnings) 36 | 37 | def setScreenLog(self,level): 38 | """ 39 | Setup screen logging. This adds the corresponding logging channel, and 40 | sets its log level and formatting. 41 | @param string level Defines the verbosity. Accepts the levels defined 42 | by the logging package, plus 'NONE' to switch it off. If an 43 | invalid level was specified, it falls back to 'ERROR'. 44 | This is case insensitive (will be converted to upper()) 45 | """ 46 | #ch.setFormatter( logging.Formatter("* %(name)s %(levelname)s %(message)s") ) 47 | self.ch.setFormatter( logging.Formatter("* %(name)-12s %(levelname)-8s %(message)s") ) 48 | try: 49 | self.ch.setLevel( logging.__getattribute__(level.upper()) ) 50 | except AttributeError: 51 | self.ch.setLevel(logging.ERROR) 52 | self.logger.addHandler(self.ch) 53 | 54 | def setFileLog(self,level,fname,encoding='ascii',maxbytes=0,backupCount=3): 55 | """ 56 | Setup file logging. This adds the corresponding logging channel, and 57 | sets its log level, formatting, etc. 58 | @param string level Defines the verbosity (see setScreenLog for details) 59 | @param string fname Name of the log file (w/ path) 60 | @param optional string encoding Encoding to use. Defaults to 'ascii' 61 | @param optional integer maxbytes If this is != 0, it enables automatic 62 | log rotation to take place at the given size 63 | @param optional integer backupCount How many copies to keep on log 64 | rotation (default: 3). Has no effect with maxbytes=0 (obviously). 65 | """ 66 | if maxbytes==0: 67 | self.fh = logging.FileHandler( fname, 'a', encoding ) 68 | else: 69 | from logging.handlers import RotatingFileHandler 70 | self.fh = RotatingFileHandler( 71 | fname, 'a', 72 | maxbytes, backupCount, 73 | encoding 74 | ) 75 | #fh.setFormatter( logging.Formatter("%(asctime)s %(name)s %(levelname)s %(message)s") ) 76 | self.fh.setFormatter( logging.Formatter("%(asctime)s %(name)-10s %(levelname)-8s %(message)s") ) 77 | try: 78 | self.fh.setLevel( logging.__getattribute__(level.upper()) ) 79 | except AttributeError: 80 | self.fh.setLevel(logging.WARNING) 81 | self.logger.addHandler(self.fh) 82 | 83 | def getLogger(self,lname='HyperSQL'): 84 | """ 85 | Obtain a logger instance 86 | @param optional string lname Name of the logger instance to return (Default: 'HyperSQL') 87 | @return object logger Instance of logging.Logger 88 | """ 89 | return logging.getLogger(lname) 90 | 91 | logg = Logger() 92 | -------------------------------------------------------------------------------- /lib/hypercore/options.py: -------------------------------------------------------------------------------- 1 | """ 2 | $Id$ 3 | HyperSQL Command Line Options 4 | Copyright 2010 Itzchak Rehberg & IzzySoft 5 | """ 6 | 7 | from optparse import OptionParser, OptionGroup 8 | from .gettext_init import langpath, langs 9 | import gettext 10 | 11 | gettext.bindtextdomain('hyperopts', langpath) 12 | gettext.textdomain('hyperopts') 13 | lang = gettext.translation('hyperopts', langpath, languages=langs, fallback=True) 14 | _ = lang.ugettext 15 | 16 | class hyperopts(object): 17 | """ 18 | HyperSQL command line parser. 19 | Makes use of Pythons optparse module 20 | """ 21 | def __init__(self,progname=None,ver=None): 22 | """ 23 | Initialize the class and setup OptionParser 24 | @param self 25 | @param optional string progname name of the program (default: argv[0]) 26 | """ 27 | self.parser = OptionParser(usage=_('Syntax: %prog [options] [project]'),description=_('Options can be used to override configured values.'),version=ver,prog=progname) 28 | self.optAdd() 29 | (self.options, self.args) = self.parser.parse_args() 30 | 31 | def optAdd(self): 32 | """ add our options """ 33 | self.parser.add_option('-c','--config',dest='config',help=_('config file to use')) 34 | self.parser.add_option('-i','--input',dest='sourceDir',help=_('directory to parse for source files')) 35 | self.parser.add_option('-o','--output',dest='htmlDir',help=_('directory the generated HTML files should be written to')) 36 | # Cache handling options 37 | cache = OptionGroup(self.parser,_('Cache Options')) 38 | cache.add_option('--cache',dest='cache',action='store_true',help=_('turn the cache on')) 39 | cache.add_option('--nocache',dest='cache',action='store_false',help=_('turn the cache off')) 40 | cache.add_option('--cache-dir',dest='cacheDir',help=_('override the cache dir location')) 41 | cache.add_option('--purge-cache',dest='purge_cache',choices=['all','code','depdata'],action='append', \ 42 | help=_('purge the specified cache at the very start. Possible values are: all, code, depdata. Multiple definitions are possible.')) 43 | self.parser.add_option_group(cache) 44 | # Processing options 45 | proc = OptionGroup(self.parser,_('Processing Options')) 46 | proc.add_option('--blind-offset',type='int',dest='blind_offset',help=_('set the "blind offset" to this number of lines')) 47 | proc.add_option('--javadoc',dest='javadoc',action='store_true',help=_('process javadoc')) 48 | proc.add_option('--nojavadoc',dest='javadoc',action='store_false',help=_('do not process javadoc')) 49 | proc.add_option('--link-calls',dest='linkCalls',action='store_true',help=_('link to targets in code calls')) 50 | proc.add_option('--nolink-calls',dest='linkCalls',action='store_false',help=_('do not link to targets in code calls')) 51 | proc.add_option('-p','--page',dest='pages',action='append',help=_('process this page. Multiple definitions (for multiple pages) are possible.')) 52 | proc.add_option('-P','--nopage',dest='nopages',action='append',help=_('do not process this page. Multiple definitions (for multiple pages) are possible.')) 53 | proc.add_option('--purge-html',dest='purgeHTML',action='store_true',help=_('purge old HTML files before creating the new ones')) 54 | proc.add_option('--nopurge-html',dest='purgeHTML',action='store_false',help=_('do not purge old HTML files before creating the new ones')) 55 | proc.add_option('--scan-instring',dest='scanInString',action='store_true',help=_('scan in strings for where/what objects are used')) 56 | proc.add_option('--noscan-instring',dest='scanInString',action='store_false',help=_('do not scan in strings for where/what objects are used')) 57 | proc.add_option('--scan-shortrefs',dest='scanShortrefs',action='store_true',help=_('scan short references for where/what objects are used')) 58 | proc.add_option('--noscan-shortrefs',dest='scanShortrefs',action='store_false',help=_('do not scan short references for where/what objects are used')) 59 | proc.add_option('--source',dest='source',action='store_true',help=_('include (and link to) highlighted source')) 60 | proc.add_option('--nosource',dest='source',action='store_false',help=_('do not include (and link to) highlighted source')) 61 | proc.add_option('--verify-javadoc',dest='verifyJavadoc',action='store_true',help=_('check for Javadoc errors and write the corresponding report')) 62 | proc.add_option('--noverify-javadoc',dest='verifyJavadoc',action='store_false',help=_('do not check for Javadoc errors and do not write the corresponding report')) 63 | self.parser.add_option_group(proc) 64 | # Logging related options 65 | log = OptionGroup(self.parser,_('Logging Options')) 66 | log.add_option('--cron',dest='cron',action='store_true',help=_('suppress all non-error output to STDOUT. This is equivalent to --noprogress --screen-loglevel ERROR and, as the name suggests, intended to be used for automated runs via a scheduler')) 67 | log.add_option('--file-loglevel',dest='fileLogLevel',choices=['DEBUG','INFO','WARNING','ERROR','CRITICAL','NONE'],help=_('log level to use for the log file')) 68 | log.add_option('--logfile',dest='logfile',help=_('use the specified file to write our log into')) 69 | log.add_option('--progress',dest='progress',action='store_true',help=_('write progress information to STDOUT')) 70 | log.add_option('--noprogress',dest='progress',action='store_false',help=_('do not write progress information to STDOUT')) 71 | log.add_option('-q','--quiet',dest='quiet',action='store_true',help=_('suppress all output to STDOUT. This is equivalent to --noprogress --screen-loglevel NONE')) 72 | log.add_option('--screen-loglevel',dest='screenLogLevel',choices=['DEBUG','INFO','WARNING','ERROR','CRITICAL','NONE'],help=_('log level to use for STDOUT')) 73 | log.add_option('--verification-log',dest='verificationLog',action='store_true',help=_('log javadoc verification messages')) 74 | log.add_option('--noverification-log',dest='verificationLog',action='store_false',help=_('do not log javadoc verification messages')) 75 | self.parser.add_option_group(log) 76 | # Dependency graphs 77 | dep = OptionGroup(self.parser,_('Dependency Graph Options')) 78 | dep.add_option('--graph',dest='graph',choices=['file2file','file2object','object2file','object2object'],action='append',help=_('draw the specified graph (multiple definitions allowed)')) 79 | dep.add_option('--nograph',dest='nograph',choices=['file2file','file2object','object2file','object2object'],action='append',help=_('do not draw the specified graph (multiple definitions allowed)')) 80 | dep.add_option('--graphviz-font',dest='graphvizFont',help=_('name of the font to use for the graphs (e.g. Arial)')) 81 | dep.add_option('--graphviz-fontsize',dest='graphvizFontSize',type='float',help=_('size of the font to use for the graphs (e.g. 10 or 8.5)')) 82 | dep.add_option('--depobjects',dest='depObjects',choices=['view','pkg','func','proc'],action='append',help=_('objects to include with the dependency graphs. Multiple specifications (one per required object) are possible.')) 83 | dep.add_option('--graphviz-processor',dest='graphvizProc',choices=['dot','fdp','neato','circo'],help=_('which graphviz module to use')) 84 | dep.add_option('--len-fdp',dest='len_fdp',type='float',help=_('len parameter for the fdp processor')) 85 | dep.add_option('--len-neato',dest='len_neato',type='float',help=_('len parameter for the neato processor')) 86 | dep.add_option('--mindist-circo',dest='mindist_circo',type='float',help=_('mindist parameter for the circo processor')) 87 | dep.add_option('--ranksep-dot',dest='ranksep_dot',type='float',help=_('space between the levels (for the dot processor)')) 88 | dep.add_option('--ranksep-twopi',dest='ranksep_twopi',type='float',help=_('space between the levels (for the twopi processor)')) 89 | self.parser.add_option_group(dep) 90 | 91 | def getOpts(self): 92 | """ 93 | Obtain all options 94 | @return object options { object.name = value} 95 | """ 96 | return self.options 97 | 98 | def getArgs(self): 99 | """ 100 | Obtain all non-option positional arguments 101 | (those following the options on the command line) 102 | @return list params 103 | """ 104 | return self.args 105 | 106 | def setVer(self,version): 107 | self.parser.version = version 108 | 109 | """ 110 | opts = hyperopts(ver='1.2.3') 111 | print opts.getOpts() 112 | print opts.getArgs() 113 | """ 114 | -------------------------------------------------------------------------------- /lib/hypercore/unittest.py: -------------------------------------------------------------------------------- 1 | """ 2 | $Id$ 3 | HyperSQL UnitTest 4 | Copyright 2010 Itzchak Rehberg & IzzySoft 5 | 6 | This module contains all neccessary functions to extract testcode information 7 | from the @testcase Javadoc tag and produce the corresponding XML code. 8 | 9 | The Javadoc element is defined as: 10 | @testcase 11 | 12 | can spread over multiple lines, and contains one or more of the following elements: 13 | name { word }; # name of the unit -- ONE WORD only. 14 | param { word text }; # var val (assignment) -- the first WORD is the name of the parameter 15 | # to pass, everything following it is the value 16 | basetype { word word }; # base data type for the given parameter -- first word is the 17 | # parameter name, second the base type. Useful if the original 18 | # parameter was specified with something like TABLE.COL%TYPE 19 | # but you want to tell your JUnit creator it's basically a VARCHAR 20 | check_param { word OP text }; # var operator value (test OUT) -- OUT param to test: 21 | # first WORD is the name of the param, second the operator, 22 | # everything following the value. OP uses only <>!= 23 | check_return { OP text }; # operator value (test return value of a function) 24 | # as above, just no name 25 | message { text }; # text returned/displayed on failure. May contain placeholders etc. 26 | comment { text }; # a comment on this unittest for closer description 27 | pre_sql { sql }; # SQL to run immediately before the test itself ("setup") 28 | post_sql { sql }; # SQL to run immediately after the test itself ("teardown") 29 | check_sql { sql }; # SQL to verify successful execution. Must return something to 30 | # be evaluated to Boolean (e.g. SELECT COUNT() or SELECT 1) 31 | 32 | One short example: 33 | name { foobar_one }; 34 | param { foo 123 }; 35 | check_return { > 0 }; 36 | message { foo returned a negative value }; 37 | comment { Does foobar give positive results? }; 38 | 39 | With the other information extracted from the hopefully complete Javadoc of our 40 | foobar function, we now can setup the XML: 41 | 42 | from unittest import * 43 | # foreach function/procedure: 44 | # foreach testcase: We can have multiple of them, and then just need to concat the results 45 | case = testcase(block) # "block" is our above block 46 | sig = signature('foobar',[{'name':'foo','type':'in','datatype':'number'}]) # function foobar(foo IN NUMBER) 47 | xo = xobject('function','foobar',sig,case) 48 | suite= testsuite('function','foobar',xo) # we could compile multiple suits 49 | print unittest(suite) # outputs the XML 50 | """ 51 | 52 | from cgi import escape # for htmlspecialchars 53 | from iz_tools.typecheck import is_numeric 54 | import re 55 | 56 | def testcase_split(block): 57 | """ 58 | Takes a @testcase block and splits up its data, returning them as structured dictionary 59 | @param string block 60 | @return dict testcase[ 61 | str name, 62 | str comment, 63 | str message, 64 | list params[ dict(str var,str val) ], 65 | list check [ dict(str var,str op,str val) ], 66 | dict ret [str op,str val] | None 67 | ] 68 | """ 69 | # Regular expressions used to extract the information 70 | regElem = re.compile('(\w+)\s*\{(.+?)\};',re.M|re.S) # BlockElems: 'name { def };' 71 | regParam = re.compile('(\w+)\s*(.+)',re.M|re.S) # param : 'var val' 72 | regCheck = re.compile('(\w+)\s*([\=\!\<\>]+)\s*(.+)',re.M|re.S) # checkParam: 'var OP val' 73 | retCheck = re.compile('([\=\!\<\>]+)\s*(.+)',re.M|re.S) # return: : 'OP val' 74 | 75 | # Presets 76 | xml = '' 77 | params = [] 78 | check = [] 79 | ret = [] 80 | basetype= [] 81 | tc = {} 82 | tc['name'] = '' 83 | tc['params'] = [] 84 | tc['check'] = [] 85 | tc['ret'] = None 86 | tc['message'] = '' 87 | tc['comment'] = '' 88 | tc['presql'] = None 89 | tc['postsql'] = None 90 | tc['checksql'] = None 91 | tc['basetypes'] = [] 92 | 93 | # First get the elements 94 | elems = regElem.findall(block) # collect all elements in (name, value) tuples 95 | for i in range(len(elems)): # interprete the elements collected 96 | #print elems[i] 97 | ename = elems[i][0].lower() 98 | if ename == 'name' : tc['name'] = elems[i][1].strip() 99 | elif ename == 'param': params.append(regParam.findall(elems[i][1])) 100 | elif ename in ['check','check-param','check_param','checkparam'] : check.append(regCheck.findall(elems[i][1])) 101 | elif ename in ['return','check-return','check_return','checkreturn']: ret = retCheck.findall(elems[i][1]) 102 | elif ename == 'message': tc['message'] = elems[i][1].strip() 103 | elif ename == 'comment': tc['comment'] = elems[i][1].strip() 104 | elif ename in ['pre','pre_sql','presql']: tc['presql'] = elems[i][1].strip() 105 | elif ename in ['post','post_sql','postsql']: tc['postsql'] = elems[i][1].strip() 106 | elif ename == 'basetype': basetype.append(regParam.findall(elems[i][1])) 107 | elif ename in ['checksql','check_sql']: tc['checksql'] = elems[i][1].strip() 108 | for par in params: 109 | if len(par)!=1 or len(par[0])!=2: continue # must be [('var','val')] 110 | tc['params'].append( dict(var=par[0][0].strip(),val=par[0][1].strip()) ) 111 | for chk in check: 112 | if len(chk)!=1 or len(chk[0])!=3: continue # must be [('var','op','val')] 113 | tc['check'].append( dict(var=chk[0][0].strip(),op=chk[0][1].strip(),val=chk[0][2].strip()) ) 114 | for par in basetype: 115 | if len(par)!=1 or len(par[0])!=2: continue # must be [('var','val')] 116 | tc['basetypes'].append( dict(var=par[0][0].strip(),val=par[0][1].strip()) ) 117 | if len(ret)>0: # just if we have (at least) one, take the first 118 | if len(ret[0])==2: # must be 'op val' 119 | tc['ret'] = dict(op=ret[0][0].strip(),val=ret[0][1].strip()) 120 | return tc 121 | 122 | 123 | def testcase(block): 124 | """ 125 | @param string block 126 | @return string xml 127 | Takes a @testcase block and converts it to XML 128 | """ 129 | tc = testcase_split(block) # split up the testcase block 130 | 131 | if tc['ret'] is not None or len(tc['check'])>0: # if there's nothing to test we need no testunit 132 | xml = ' \n'; 133 | if tc['comment'] != '': xml += ' \n' 134 | if tc['message'] != '': xml += ' \n' 135 | for par in tc['params']: 136 | xml += ' \n' 137 | for par in tc['basetypes']: 138 | xml += ' \n' 139 | for par in tc['check']: 140 | xml += ' \n' 141 | if tc['ret'] is not None: 142 | xml += ' \n' 143 | if tc['presql'] is not None: 144 | xml += ' \n' 145 | if tc['postsql'] is not None: 146 | xml += ' \n' 147 | if tc['checksql'] is not None: 148 | xml += ' \n \n \n' 149 | xml += ' \n' 150 | return xml 151 | 152 | 153 | def signature(name,params,retval=None): 154 | """ 155 | Create the XML SIGNATURE block for a function/procedure 156 | @param string name 157 | @param list params list of dict[str name,str type,str datatype,bool optional] 158 | @param optional string retval datatype returned by the function 159 | @return string xml 160 | """ 161 | xml = ' \n' 162 | xml += ' '+name+'\n' 163 | for i in range(len(params)): 164 | xml += ' \n' 168 | if retval is not None: 169 | xml += ' '+retval+'\n' 170 | xml += ' \n' 171 | return xml 172 | 173 | 174 | def xobject(otype,oname,osig,ocase): 175 | """ 176 | Glue the elements of the function/procedure together 177 | @param string otype object type (either 'procedure' or 'function') 178 | @param string oname object name 179 | @param string osig objects signature (result of the signature() function) 180 | @param string ocase objects testcase (result of the testcase() function). 181 | If there are multiple testcases, glue them together beforehand. 182 | """ 183 | xml = ' \n' \ 184 | + osig + ocase \ 185 | + ' \n' 186 | return xml 187 | 188 | 189 | def testsuite(ttype,tname,txml): 190 | """ 191 | Glue the elements of a testsuite together 192 | @param string ttype what the testsuite is for ('package','function','procedure') 193 | @param string tname Name of the testsuite. This is the name of the package/function/procedure 194 | @param string txml the "inner XML" of the testsuite (result of xobject(); 195 | if multiple objects are concerned, glue them together beforehand) 196 | """ 197 | xml = ' \n'\ 198 | + txml \ 199 | + ' \n' 200 | return xml 201 | 202 | 203 | def unittest(uxml): 204 | """ 205 | Glue together the complete UnitTest XML 206 | @param string uxml the "inner XML" (result of testsuite()). 207 | If there are multiple testsuites concerned, glue them together beforehand. 208 | """ 209 | return '\n'+uxml+'\n' 210 | 211 | -------------------------------------------------------------------------------- /lib/hypercore/xml_forms.py: -------------------------------------------------------------------------------- 1 | """ 2 | $Id$ 3 | Oracle Forms Parser 4 | Copyright 2010 Itzchak Rehberg & IzzySoft 5 | 6 | Requires the Oracle Forms modules to be converted to XML using frmf2xml 7 | 8 | You may want to have a look at the test() function to get started. 9 | """ 10 | 11 | from xml.sax import saxutils, make_parser 12 | from xml.sax.handler import feature_namespaces, ContentHandler 13 | 14 | 15 | class FindUnits(ContentHandler): 16 | """ 17 | Content handler for Oracle Forms parsing 18 | Requires the Oracle Forms modules to be converted to XML using frmf2xml 19 | """ 20 | def __init__(self): 21 | self.libinfo = {} 22 | self.modinfo = {} 23 | self.units = [] 24 | self.trigger = [] 25 | self.stats = {'Alert':0, 'Block':0, 'Canvas':0, 'LOV':0, 'Menu':0, 'ModuleParameter':0, 26 | 'PropertyClass':0, 'RecordGroup':0, 'VisualAttribute':0, 'Window':0} 27 | 28 | def error(self, exception): 29 | """Internal: Skip over recoverable (non-fatal) errors""" 30 | import sys 31 | sys.stderr.write("\%s\n" % exception) 32 | 33 | def startElement(self, name, attrs): 34 | """Internal: Process opening tag""" 35 | uname = attrs.get('Name', None) 36 | if name == 'ObjectLibrary': # only present for OLB files 37 | libobjects = attrs.get('ObjectCount', None) 38 | if libobjects: libobjects = int(libobjects) 39 | items = attrs.items() 40 | self.libinfo = {'name':uname, 'objects':libobjects, 'items':items} 41 | elif name == 'FormModule': # only FMB: RealName of the module 42 | title = attrs.get('Title', None) 43 | mmod = attrs.get('MenuModule', None) 44 | items = attrs.items() 45 | self.modinfo = {'name':uname, 'title':title, 'menumodule':mmod, 'items':items} 46 | elif name == 'ProgramUnit': # code in OLB and FMB files 47 | utype = attrs.get('ProgramUnitType', None) 48 | ucode = attrs.get('ProgramUnitText', None) 49 | if ucode: ucode = ucode.replace(' ','\n') 50 | self.units.append({'name':uname, 'type':utype, 'code':ucode}) 51 | elif name == 'Trigger': # trigger code in OLB and FMB files 52 | ucode = attrs.get('TriggerText', None) 53 | if ucode: ucode = ucode.replace(' ','\n') 54 | self.trigger.append({'name':uname, 'code':ucode}) 55 | elif name in self.stats.keys(): 56 | self.stats[name] += 1 57 | 58 | class OraForm: 59 | """ 60 | Oracle Form Analyzer 61 | Requires the Oracle Forms modules to be converted to XML using frmf2xml 62 | Example usage: 63 | form = OraForm('sample_fmb.xml') 64 | for unit in form.getUnits(): print unit['code'] 65 | Alternative, for processing multiple files: 66 | form = OraForm() 67 | for filename in filenames: form.setFileName(filename) 68 | for unit in form.getUnits(): print unit['code'] 69 | """ 70 | def __init__(self, filename=''): 71 | """ Initialize the class, optionally pass it the name of the file to process """ 72 | if filename: self.setFileName(filename) 73 | 74 | def reset(self): 75 | """ Reset all contents for processing of a new file. If not called in between, content will be merged. """ 76 | self.fileName = '' 77 | self.units = [] 78 | self.trigger = [] 79 | self.libinfo = {} 80 | self.modinfo = {} 81 | self.stats = {} 82 | 83 | def setFileName(self,filename): 84 | """ Specify the name of the XML Form to process """ 85 | self.reset() 86 | self.fileName = filename 87 | self.parse() 88 | 89 | def parse(self): 90 | """ 91 | Parse the XML file and evaluate its contents. Automatically called by setFileName() 92 | """ 93 | if not self.fileName: return [] # nothing to parse 94 | 95 | parser = make_parser() # Create a parser 96 | parser.setFeature(feature_namespaces, 0) # Tell the parser we are not interested in XML namespaces 97 | dh = FindUnits() # Create the handler 98 | parser.setContentHandler(dh) # Tell the parser to use our handler 99 | parser.parse(self.fileName) # Parse the input 100 | self.units = dh.units 101 | self.trigger = dh.trigger 102 | self.libinfo = dh.libinfo 103 | self.modinfo = dh.modinfo 104 | self.stats = dh.stats 105 | 106 | def getUnits(self): 107 | """ 108 | Return the ProgramUnits details of the processed form 109 | @return list units list of dicts (name, type, code) 110 | """ 111 | return self.units 112 | 113 | def getModuleName(self): 114 | """ 115 | Return the name of the module. This is either the "FormModule" name (for 116 | FMB), or the object library name (for OLB) 117 | @return string name 118 | """ 119 | if len(self.modinfo): return self.modinfo['name'] 120 | elif len(self.libinfo): return self.libinfo['name'] 121 | else: return None 122 | 123 | def getModuleInfo(self): 124 | """ 125 | Return general info about the module (for FMB files, otherwise empty) 126 | @return dict modinfo (str name, str title, str menumodule, list items (tuple str name, str val)) 127 | """ 128 | return self.modinfo 129 | 130 | def getLibraryName(self): 131 | """ alias for getModuleName """ 132 | return self.getModuleName() 133 | 134 | def getLibraryInfo(self): 135 | """ 136 | Return general info about the library (for OLB files, otherwise empty) 137 | @return dict libinfo (name, objects, list items (tuple str name, str val)) - 138 | where objects is the object count 139 | """ 140 | return self.libinfo 141 | 142 | def getTrigger(self): 143 | """ 144 | Return the Trigger details of the processed form 145 | @return list trigger list of dicts (name, code) 146 | """ 147 | return self.trigger 148 | 149 | def getStats(self): 150 | """ 151 | Return stats for the no-code objects of the form 152 | @return dict stats 153 | """ 154 | return self.stats 155 | 156 | def test(filename,printcode=False): 157 | """ 158 | Simple test unit to a) test if everything works and/or b) show what kind of 159 | information is extracted (to get you started) 160 | @param string filename name of the XML file representing the form to process 161 | @param optional boolean printcode Whether to printout code contents (may get very verbose!). Default: False 162 | """ 163 | form = OraForm(filename) 164 | units = form.getUnits() 165 | trigger = form.getTrigger() 166 | libinfo = form.getLibraryInfo() 167 | modinfo = form.getModuleInfo() 168 | if (modinfo): 169 | print 'Module ' + modinfo['name'] 170 | print '=' * len('Module ' + modinfo['name']) 171 | print 'ModuleInfo: ' + `modinfo` 172 | if (libinfo): 173 | print 'Library ' + libinfo['name'] 174 | print '=' * len('Library ' + libinfo['name']) 175 | print 'LibraryInfo: ' + `libinfo` 176 | print `len(units)` + ' code units identified:' 177 | for i in range(len(units)): 178 | utype = units[i]['type'] or '' 179 | uname = units[i]['name'] or '' 180 | print '* ' + utype + ' ' + uname 181 | if printcode: 182 | code = units[i]['code'] or '' 183 | print '-' * len('* ' + utype + ' ' + uname) 184 | print code 185 | print '' 186 | print `len(trigger)` + ' trigger units identified:' 187 | for i in range(len(trigger)): 188 | uname = trigger[i]['name'] or '' 189 | print '* ' + uname 190 | if printcode: 191 | ucode = trigger[i]['code'] or '' 192 | print '-' * len('* ' + uname) 193 | print ucode 194 | print '' 195 | print '* Stats: ' + `form.stats` 196 | -------------------------------------------------------------------------------- /lib/iz_tools/IniParser.py: -------------------------------------------------------------------------------- 1 | # $Id$ 2 | """ 3 | IniParser - an extention to ConfigParser 4 | Copyright 2010 Itzchak Rehberg & IzzySoft 5 | """ 6 | 7 | from ConfigParser import ConfigParser 8 | from sys import stderr 9 | 10 | class IniParser(ConfigParser): 11 | """ 12 | An extension to ConfigParser, adding a getList() method to the class - 13 | plus a Default parameter to option retrieval. Using the latter, it also 14 | tries to (silently) bypass ValueError exceptions (see logMode). 15 | As for the defaults which may be passed to ConfigParser.__init__, 16 | they cannot be assigned to a specific section - so if the same keyword 17 | exists in multiple sections, those defaults are useless. To bypass this 18 | limit, you can either pass above mentioned defaults for option retrieval - 19 | or specify section specific defaults using the IniParser.setVals() method. 20 | """ 21 | def __init__(self,defaults=None): 22 | """ 23 | Initialize the instance 24 | @param self 25 | @param defaults A dictionary of intrinsic defaults. The keys must be 26 | strings, the values must be appropriate for %()s string 27 | interpolation. Note that `__name__' is always an intrinsic 28 | default; it's value is the section's name. These defaults are 29 | not section specific. 30 | """ 31 | ConfigParser.__init__(self,defaults) 32 | self.logMode = stderr 33 | 34 | def setVals(self,vals): 35 | """ 36 | Setting multiple configuration values from a passed dictionary. 37 | This can either be used to initialize the configuration with useful 38 | defaults (section specific - not global as the constructor does) - 39 | or to overwrite settings at a later point (e.g. after parsing additional 40 | command line options). 41 | @param self 42 | @param defaults dictionary with the structure defaults[section][option]=string 43 | ATTENTION: Keep in mind: Already existing options will be overwritten by 44 | values from the passed dict! 45 | """ 46 | if type(vals).__name__ == 'dict': 47 | for sect in vals.iterkeys(): 48 | if not self.has_section(sect): 49 | self.add_section(sect) 50 | for opt in vals[sect].iterkeys(): 51 | self.set(sect,opt,vals[sect][opt]) 52 | 53 | def setLogMode(self,mode): 54 | """ 55 | If some errors occur (e.g. due to invalid values specified), IniParser 56 | tries to silently fix this. For example, if you try to retrieve the value 57 | 'dummy' as integer, this normally would rise an exeption - so if you 58 | passed a default value to getInt, IniParser this and only raises an 59 | exeption otherwise. Though, you might want to inform the user - which will 60 | be done if you set the logMode correspondingly 61 | @param self 62 | @param mode logMode to set: None to keep quite, 'stderr' for error output (default) 63 | """ 64 | if mode in ['None','stderr']: 65 | self.logMode = mode 66 | 67 | def log(self,msg): 68 | """ 69 | Print an error message to the output specified by setLogMode() 70 | @param self 71 | @param msg message to print 72 | """ 73 | if self.logMode != 'None': 74 | print >>stderr, '! '+msg 75 | 76 | def get(self,sect,opt,default=None): 77 | """ 78 | Get an option from the config as string 79 | @param self 80 | @param string section name 81 | @param string option name 82 | @param optional string default value (default: None) 83 | @return string value 84 | """ 85 | try: 86 | if self.has_option(sect,opt): 87 | return ConfigParser.get(self,sect,opt) 88 | else: 89 | return default 90 | except ValueError: 91 | if default != None: 92 | self.log('An invalid value was specified for '+sect+'.'+opt) 93 | return default 94 | else: 95 | raise ValueError('An invalid value was specified for '+sect+'.'+opt) 96 | 97 | def getList(self,sect,opt,default=None): 98 | """ 99 | Get an option from the config as list 100 | @param self 101 | @param string section name 102 | @param string option name 103 | @param optional list default value (default: None) 104 | @return list value 105 | """ 106 | if self.has_option(sect,opt): 107 | return ConfigParser.get(self,sect,opt).split(' ') 108 | else: 109 | return default 110 | 111 | def getBool(self,sect,opt,default=None): 112 | """ 113 | Get an option from the config as boolean value 114 | @param self 115 | @param string section name 116 | @param string option name 117 | @param optional boolean default value (default: None) 118 | @return boolean value 119 | """ 120 | try: 121 | if self.has_option(sect,opt): 122 | return self.getboolean(sect,opt) 123 | else: 124 | return default 125 | except ValueError: 126 | msg = 'invalid value for '+sect+'.'+opt+' - "'+self.get(sect,opt)+'" cannot be translated into a boolean.' 127 | if default != None: 128 | self.log(msg) 129 | return default 130 | else: 131 | raise ValueError(msg) 132 | 133 | def getInt(self,sect,opt,default=None): 134 | """ 135 | Get an option from the config as integer value 136 | @param self 137 | @param string section name 138 | @param string option name 139 | @param optional int default value (default: None) 140 | @return int value 141 | """ 142 | try: 143 | if self.has_option(sect,opt): 144 | return self.getint(sect,opt) 145 | else: 146 | return default 147 | except ValueError: 148 | msg = 'invalid value for '+sect+'.'+opt+' - "'+self.get(sect,opt)+'" cannot be translated into an integer.' 149 | if default != None: 150 | self.log(msg) 151 | return default 152 | else: 153 | raise ValueError(msg) 154 | 155 | def getFloat(self,sect,opt,default=None): 156 | """ 157 | Get an option from the config as float value 158 | @param self 159 | @param string section name 160 | @param string option name 161 | @param optional float default value (default: None) 162 | @return float value 163 | """ 164 | try: 165 | if self.has_option(sect,opt): 166 | return self.getfloat(sect,opt) 167 | else: 168 | return default 169 | except ValueError: 170 | msg = 'invalid value for '+sect+'.'+opt+' - "'+self.get(sect,opt)+'" cannot be translated into a float.' 171 | if default != None: 172 | self.log(msg) 173 | return default 174 | else: 175 | raise ValueError(msg) 176 | -------------------------------------------------------------------------------- /lib/iz_tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IzzySoft/HyperSQL/7d59a7e69a99b2ed2938a5c1e0f80e9a914b9121/lib/iz_tools/__init__.py -------------------------------------------------------------------------------- /lib/iz_tools/progressbar.py: -------------------------------------------------------------------------------- 1 | """ 2 | Progress bar 3 | Original Source: http://code.activestate.com/recipes/168639-progress-bar-class/ 4 | Modified by: Izzy 5 | """ 6 | __revision__ = '$Id$' 7 | 8 | from sys import stdout 9 | from locale import getdefaultlocale 10 | lc, encoding = getdefaultlocale() 11 | if not encoding: encoding = 'utf-8' 12 | 13 | class progressBar: 14 | """ 15 | This is a simple text mode progress bar to show the percentage of completion. 16 | It is intended to take a string explaining the task running, which is 17 | displayed together with the actual progress bar. 18 | """ 19 | def __init__(self, prefix='', minValue = 0, maxValue = 100, totalWidth=12, padLen=60): 20 | """ 21 | Initialize the progress bar 22 | @param self 23 | @param string prefix Task running. This string should be no longer than padLen. 24 | Leaving it empty (default) will cause the bar starting at pos 0 (begin 25 | of the line). Otherwise, prefix will be right-padded by spaces, and 26 | the bar appended to its end. 27 | @param int minValue Start value (absolute number, usually 0=default) 28 | @param int maxValue End value (absolute number corresponding to 100%, default=100) 29 | @param int totalWidth Width of the *bar* (without the prefix) in characters 30 | (default: 12) 31 | @param int padLen To how many chars the prefix (if specified) should be padded 32 | """ 33 | if len(prefix)>0: 34 | prefix = prefix.ljust(60) 35 | self.prefixLen = len(prefix) 36 | self.mask = prefix + '[%s]' 37 | self.pbar = self.mask # This holds the progress bar string 38 | self._old_pbar = self.pbar # for draw() 39 | self.min = minValue 40 | self.max = maxValue 41 | self.span = maxValue - minValue 42 | self.width = totalWidth 43 | self.amount = 0 # When amount == max, we are 100% done 44 | self.update(0) # Build progress bar string 45 | 46 | def update(self, newAmount = 0): 47 | """ 48 | Update the actual value and re-draw the progress bar (if necessary). 49 | This updates the "current value" and calls progressbar.draw(). The value 50 | passed may be greater or less than the recent value - or even the same. 51 | @param self 52 | @param int curVal 53 | """ 54 | drawMe = (newAmount != 0) 55 | if newAmount < self.min: newAmount = self.min 56 | if newAmount > self.max: newAmount = self.max 57 | self.amount = newAmount 58 | 59 | # Figure out the new percent done, round to an integer 60 | diffFromMin = float(self.amount - self.min) 61 | if self.span!=0: percentDone = (diffFromMin / float(self.span)) * 100.0 62 | else: percentDone = 0 63 | percentDone = round(percentDone) 64 | percentDone = int(percentDone) 65 | 66 | # Figure out how many hash bars the percentage should be 67 | allFull = self.width - 2 68 | numHashes = (percentDone / 100.0) * allFull 69 | numHashes = int(round(numHashes)) 70 | 71 | # build a progress bar with hashes and spaces 72 | bar = '='*numHashes + ' '*(allFull-numHashes) 73 | self.pbar = self.mask % bar 74 | 75 | # figure out where to put the percentage, roughly centered 76 | percentPlace = self.prefixLen + 1 + (self.width / 2) - len(str(percentDone)) 77 | percentString = str(percentDone) + "%" 78 | 79 | # slice the percentage into the bar 80 | self.pbar = self.pbar[0:int(percentPlace)] + percentString + self.pbar[int(percentPlace)+len(percentString):] 81 | 82 | # call draw() to update screen if necessary 83 | if drawMe: self.draw() 84 | 85 | def __str__(self): 86 | """ Returns the current string of the bar (incl. prefix) """ 87 | return self.pbar.encode(encoding) 88 | 89 | def draw(self): 90 | """ draw progress bar - but only if it has changed """ 91 | if self.pbar != self._old_pbar: 92 | self._old_pbar = self.pbar 93 | stdout.write(self.__str__() + '\r') 94 | stdout.flush() 95 | 96 | -------------------------------------------------------------------------------- /lib/iz_tools/system.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # $Id$ 4 | """ 5 | Some useful system functions which mostly mimic PHP (or Shell) equivalents 6 | """ 7 | 8 | #====================================================[ Imports and Presets ]=== 9 | import os # for which() and getCallingModule() 10 | import sys # for which() 11 | from subprocess import Popen,PIPE # for popen() 12 | from .typecheck import is_string, is_list # for file_put_contents (local module typecheck) 13 | from traceback import extract_stack # for getCaller() 14 | 15 | # prepare for fopen (encoding fallback) 16 | from locale import getdefaultlocale 17 | lc, encoding = getdefaultlocale() 18 | encoding = encoding or 'UTF-8' 19 | try: 20 | import codecs 21 | except: 22 | codecs = None 23 | 24 | #==============================================================[ Functions ]=== 25 | #------------------------------------------------------------------[ which ]--- 26 | def which(executable, path=None): 27 | """ 28 | Try to find 'executable' in the directories listed in 'path' (a 29 | string listing directories separated by 'os.pathsep'; defaults to 30 | os.environ['PATH']). Mimics the shell command "which". 31 | Returns the complete filename or None if not found 32 | Original Source: http://snippets.dzone.com/posts/show/6313 33 | @param string executable to look for 34 | @param optional string path to look in 35 | @return string path/to/executable or None 36 | """ 37 | if path is None: 38 | path = os.environ['PATH'] 39 | paths = path.split(os.pathsep) 40 | extlist = [''] 41 | if os.name == 'os2': 42 | (base, ext) = os.path.splitext(executable) 43 | # executable files on OS/2 can have an arbitrary extension, but 44 | # .exe is automatically appended if no dot is present in the name 45 | if not ext: 46 | executable = executable + ".exe" 47 | elif sys.platform == 'win32': 48 | pathext = os.environ['PATHEXT'].lower().split(os.pathsep) 49 | (base, ext) = os.path.splitext(executable) 50 | if ext.lower() not in pathext: 51 | extlist = pathext 52 | for ext in extlist: 53 | execname = executable + ext 54 | if os.path.isfile(execname): 55 | return execname 56 | else: 57 | for p in paths: 58 | f = os.path.join(p, execname) 59 | if os.path.isfile(f): 60 | return f 61 | else: 62 | return None 63 | 64 | #------------------------------------------------------------------[ popen ]--- 65 | def popen(command): 66 | """ 67 | Run a command and return its output as string. Mimics he PHP function 68 | "shell_exec" - with the difference of returning a touple, so stderr is 69 | also available to evaluation. 70 | Example call: mylist, myerr = run('ls -l') 71 | @param string command 72 | @return string stdout, string stderr 73 | """ 74 | p = Popen(command, shell=True,stdout=PIPE,stderr=PIPE) 75 | out = ''.join(p.stdout.readlines() ) 76 | outerr = ''.join(p.stderr.readlines() ) 77 | return out, outerr 78 | 79 | #-------------------------------------------------------------[ shell_exec ]--- 80 | def shell_exec(command): 81 | """ 82 | Run a command and return its output as string. Mimics he PHP function 83 | "shell_exec". 84 | Example call: mylist = run('ls -l') 85 | @param string command 86 | @return string stdout 87 | """ 88 | out, err = popen(command) 89 | return out 90 | 91 | #------------------------------------------------------------------[ fopen ]--- 92 | def fopen(filename,mode,enc=None): 93 | """ 94 | Wrapper to open a file either via codecs (if possible), or simply with open() 95 | (if codecs==None). If the third parameter is not set, it tries to read the 96 | global variable "encoding" instead. If that's not set either, fallback to 97 | open() 98 | This rawly mimics the PHP function fopen() up to the mandatory parameters, 99 | but differs with the optionals. 100 | @param string filename 101 | @param string mode 102 | @param optional string encoding 103 | @return filehandle 104 | """ 105 | if enc is None: 106 | try: 107 | enc = encoding 108 | except: 109 | enc = None 110 | if codecs is None: 111 | enc = None 112 | if enc is None: 113 | return open(filename,mode) 114 | else: 115 | return codecs.open(filename,mode,enc) 116 | 117 | #------------------------------------------------------[ file_get_contents ]--- 118 | def file_get_contents(filename,enc=None): 119 | """ 120 | Get the content of the specified file and return it as string. Mimics the 121 | PHP function with the same name up to the mandatory parameter - but differs 122 | when it comes to the optionals. 123 | @param string filename name of the file to read 124 | @param optional string enc encoding of the file (defaults to system standard 125 | evaluated via locale settings) 126 | @return string text 127 | """ 128 | infile = fopen(filename,'rb',enc) 129 | text = infile.read() 130 | infile.close() 131 | return text 132 | 133 | #---------------------------------------------------------[ file_get_lines ]--- 134 | def file_get_lines(filename,enc=None): 135 | """ 136 | Get the content of the specified file and return it as list. To be used 137 | like the PHP function file() - except for the optional parameter(s). 138 | @param string filename name of the file to read 139 | @param optional string enc encoding of the file (defaults to system standard 140 | evaluated via locale settings) 141 | @return list text 142 | """ 143 | infile = fopen(filename,'rb',enc) 144 | list = infile.readlines() 145 | infile.close() 146 | return list 147 | 148 | #------------------------------------------------------[ file_put_contents ]--- 149 | def file_put_contents(filename,content,enc=None,append=False): 150 | """ 151 | Write the content to the specified file. To be used like the PHP function 152 | with the same name - except for the optional parameters. 153 | @param string filename name of the file to be written 154 | @param mixed content what should be written to the file. This can be either 155 | a string or a list 156 | @param optional string enc encoding of the file (defaults to system standard 157 | evaluated via locale settings) 158 | @param optional boolean append whether content shall be appended if the file 159 | already exists. By default, an existing file will be simply replaced. 160 | """ 161 | if is_string(content): pass 162 | elif is_list(content): content = '\n'.join(content) 163 | else: 164 | raise TypeError, 'Second argument to file_put_contents must be either str or list, %s given' % is_what(content) 165 | if append: mode = 'ab' 166 | else: mode = 'wb' 167 | outfile = fopen(filename,mode) 168 | outfile.write(content) 169 | bytes = outfile.tell() 170 | outfile.close() 171 | return bytes 172 | 173 | #---------------------------------------------------------------[ makeRDir ]--- 174 | def makeRDir(pathname): 175 | """ 176 | Create recursive directory structur, if it not exists already 177 | (similar to 'mkdir -p' on *nix) 178 | @param string pathname path/to/create 179 | """ 180 | splitted = pathname.split(os.sep) 181 | temp = "" 182 | for path_element in splitted: # loop through path components, making directories as needed 183 | temp += path_element + os.sep 184 | if os.access(temp, os.F_OK) == 1: 185 | continue 186 | else: 187 | os.mkdir(temp) 188 | 189 | #--------------------------------------------------[ Caller identification ]--- 190 | def getCaller(level=3): 191 | """ 192 | Find out who called the holding function 193 | @param optional integer level 1 = self, 2 = caller of GetCaller, 3 = who called 2, etc. 194 | @return tuple caller (filename, line number, function name, text) 195 | """ 196 | stack = extract_stack() 197 | return stack[len(stack)-level] 198 | 199 | def getCallingModule(level=4,basename=True): 200 | """ 201 | Obtain the name of the calling module 202 | @param optional integer level 1 = self, 2 = caller of GetCaller, 3 = caller of getCallingModule, 4 = who called 3 (default), etc. 203 | @param optional boolean basename whether to cut-off the path (default: True) 204 | @return string name of the module (i.e. filename w/o ext) 205 | """ 206 | return os.path.splitext(os.path.basename(getCaller(level)[0]))[0] 207 | -------------------------------------------------------------------------------- /lib/iz_tools/text.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # $Id$ 4 | """ 5 | Some useful functions for string / text processing 6 | """ 7 | 8 | #====================================================[ Imports and Presets ]=== 9 | import re # for getWordLineNo 10 | 11 | #==============================================================[ Functions ]=== 12 | #--------------------------------------[ Finding lineNo with matching text ]--- 13 | def getWordLineNo(text,pattern): 14 | """ 15 | Finding lineNo with matching text 16 | example: 17 | getWordLineNo(text,'

([^<]+)') 18 | Adapted from: http://snippets.dzone.com/posts/show/1638 19 | By: Izzy 20 | @param string text to parse 21 | @param string pattern RegExp pattern to find 22 | @return list of tuples (lineno, offset, word) 23 | """ 24 | res = [] 25 | for m in re.finditer(pattern, text, re.I): 26 | start = m.start() 27 | lineno = text.count('\n', 0, start) + 1 28 | offset = start - text.rfind('\n', 0, start) 29 | word = m.group(0) 30 | res.append((lineno, offset, word)) 31 | return res 32 | -------------------------------------------------------------------------------- /lib/iz_tools/typecheck.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # $Id$ 4 | """ 5 | Some useful functions around types, imitating the PHP style type checking 6 | functions. Of course, adapted to the types available in Python. 7 | """ 8 | 9 | #====================================================[ Imports and Presets ]=== 10 | from types import * 11 | 12 | #==============================================================[ Own Types ]=== 13 | class nullDict(dict): 14 | """ A dictionary without KeyErrors (returning None instead) """ 15 | def __missing__(self,key): 16 | return None 17 | 18 | #==============================================================[ Functions ]=== 19 | #----------------------------------------------------------[ Type checking ]--- 20 | """ 21 | Type checking functions have been taken from: 22 | http://code.activestate.com/recipes/305888-a-way-to-deal-with-checking-for-types/ 23 | """ 24 | def check_type(obj,atts=[],callables=[]): 25 | """ 26 | Helper for is_mapping(), is_list(), is_str() and is_file() 27 | @param object object to check 28 | @param optional list atts attributes the object must have (default: empty list) 29 | @param optional list callables callables the object must have (default: empty list) 30 | """ 31 | got_atts=True 32 | for att in atts: 33 | if not hasattr(obj,att): 34 | got_atts=False;break 35 | got_callables=True 36 | for call in callables: 37 | if not hasattr(obj,call): 38 | got_callables=False;break 39 | the_attr=getattr(obj,call) 40 | if not callable(the_attr): 41 | got_callables=False;break 42 | if got_atts and got_callables: return -1 43 | return 0 44 | 45 | def is_iter(obj): 46 | """ 47 | Check whether the object is iterable 48 | @param object object to check 49 | @return int 1 if True, 0 if False, -1 if iterable but neither list, tuple, dict or file 50 | """ 51 | if isinstance(obj,ListType): return 1 52 | if isinstance(obj,TupleType): return 1 53 | if isinstance(obj,DictType): return 1 54 | if isinstance(obj,FileType): return 1 55 | if hasattr(obj,'__iter__') : return -1 56 | return 0 57 | 58 | def is_gen(obj): 59 | """ 60 | Is the object a generator? 61 | @param object object to check 62 | @return int 1 if True, 0 if False 63 | """ 64 | if isinstance(obj,GeneratorType): return 1 65 | return 0 66 | 67 | def is_seq(obj): 68 | """ 69 | Is the object a sequence? 70 | @param object object to check 71 | @return int 1 if True, 0 if False, -1 if obj[0:0] works but it's neither list nor tuple (but e.g. str) 72 | """ 73 | if isinstance(obj,ListType): return 1 74 | if isinstance(obj,TupleType): return 1 75 | if is_iter(obj): 76 | try: 77 | obj[0:0] 78 | return -1 79 | except TypeError: 80 | pass 81 | return 0 82 | 83 | def is_mapping(obj): 84 | """ 85 | Is the object a mapping type (e.g. dictionary)? 86 | @param object object to check 87 | @return int 1 if True, 0 if False, -1 if it's not a dict but has callables 88 | """ 89 | if isinstance(obj,DictType): return 1 90 | if is_iter(obj): 91 | return check_type(obj,callables=['iteritems','has_key']) 92 | return 0 93 | 94 | def is_dict(obj): 95 | """ 96 | Is it a dictionary? 97 | @param object object to check 98 | @return int 1 if True, 0 if False, -1 if it's not a dict but has callables 99 | """ 100 | return is_mapping(obj) 101 | 102 | def is_list(obj): 103 | """ 104 | Is the object a list? 105 | @param object object to check 106 | @return int 1 if True, 0 if False, -1 if it's not a list, but has callables append, extend, and pop 107 | """ 108 | if isinstance(obj,ListType): return 1 109 | if is_seq(obj): 110 | if check_type(obj,callables=['append','extend','pop']): return -1 111 | return 0 112 | 113 | def is_str(obj): 114 | """ 115 | Is the object a string? 116 | @param object object to check 117 | @return int 1 if True, 0 if False, -1 not str but has callables index, count, and replace 118 | """ 119 | if isinstance(obj, basestring): return 1 120 | if is_iter(obj): 121 | if check_type(obj,callables=['index','count','replace']): return -1 122 | return 0 123 | 124 | def is_string(obj): 125 | """ alias for is_str """ 126 | return is_str(obj) 127 | 128 | def is_int(obj): 129 | """ 130 | Is it an integer? 131 | @param object object to check 132 | @return int 1 if True, 0 if False, -1 not str but has callables index, count, and replace 133 | """ 134 | if isinstance(obj, int) : return 1 135 | return 0 136 | 137 | def is_numeric(obj): 138 | """ 139 | Is it a number - i.e. an integer or float? 140 | @param object object to check 141 | @return int 1 if True, 0 if False, -1 not str but has callables index, count, and replace 142 | """ 143 | try: 144 | float(obj) 145 | return 1 146 | except ValueError: 147 | pass 148 | return 0 149 | 150 | def is_file(obj): 151 | """ 152 | Is the object a file? 153 | @param object object to check 154 | @return int 1 if True, 0 if False, -1 if it's not FileType but has callables read and close 155 | """ 156 | if isinstance(obj,FileType): return 1 157 | if check_type(obj,callables=['read','close']): return -1 158 | return 0 159 | 160 | def is_what(obj): 161 | """ 162 | Get the type of the passed object 163 | @param object object to check 164 | @return mixed string category (if we have a direct match) or list of 0/1 [iter,gen,seq,list,str,dict,file] 165 | """ 166 | try: 167 | if obj.__class__.__name__: return obj.__class__.__name__ 168 | except: 169 | return [ str(i) for i in (is_iter(obj),is_gen(obj),is_seq(obj),is_list(obj),is_str(obj),is_mapping(obj),is_file(obj))] 170 | 171 | -------------------------------------------------------------------------------- /lib/parsers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IzzySoft/HyperSQL/7d59a7e69a99b2ed2938a5c1e0f80e9a914b9121/lib/parsers/__init__.py -------------------------------------------------------------------------------- /lib/parsers/filefinder.py: -------------------------------------------------------------------------------- 1 | """ 2 | Parsing the file system 3 | """ 4 | __revision__ = '$Id$' 5 | 6 | import os 7 | from hypercore.elements import FileInfo 8 | 9 | def getFileList(sdir, fileExts, skipDirs=[], ignorefile='.hsqlignore'): 10 | """ 11 | Recursively scans the source directory specified for relevant files according 12 | to the file extensions passed by the second parameter, while excluding files/ 13 | directories given with the third (useful to exclude '.svn' and the like) and 14 | directories containing an ignore flag file (usually '.hsqlignore') 15 | Information for matching files will be returned as a list of FileInfo objects. 16 | @param string dir directory to scan 17 | @param list fileExts file extensions to consider. Each element must be a tuple 18 | (str fileType, list extensions) 19 | @param list skipDirs files/directories to skip 20 | @return list fileInfoList list of FileInfo objects 21 | """ 22 | if fileExts is None or len(fileExts)<1: return [] 23 | 24 | # get a list of this directory's contents 25 | # these items are relative and not absolute 26 | names = os.listdir(sdir) 27 | fileInfoList = [] 28 | 29 | # setup supported file extensions 30 | exts = [] 31 | for ext in fileExts: exts += ext[1] 32 | 33 | # iterate through the file list 34 | for i in names: 35 | 36 | if i in skipDirs: # do not look in RCS/CVS/SVN/... special dirs 37 | continue 38 | if os.path.isfile( os.path.join(sdir, i, ignorefile) ): 39 | continue 40 | 41 | # convert from relative to absolute addressing 42 | # to allow recursive calls 43 | f1=os.path.join(sdir, i) 44 | 45 | # if this item is also a directory, recurse it too 46 | if os.path.isdir(f1): 47 | fileInfoList += getFileList(f1, fileExts, skipDirs) 48 | 49 | else: # file found, only add specific file extensions to the list 50 | fspl = f1.split('.') 51 | ext = fspl[len(fspl)-1] 52 | if ext in exts: 53 | temp = FileInfo() 54 | temp.fileName = f1 55 | for ftype in fileExts: 56 | if ext in ftype[1]: 57 | temp.fileType = ftype[0] 58 | break 59 | fileInfoList.append(temp) 60 | return fileInfoList 61 | 62 | -------------------------------------------------------------------------------- /lib/progress.py: -------------------------------------------------------------------------------- 1 | """ 2 | Progressbar handlers 3 | 4 | $Id$ 5 | """ 6 | from iz_tools.progressbar import * 7 | from hypercore.elements import metaInfo 8 | from hypercore.logger import logg 9 | pbar = progressBar() # make it global 10 | 11 | def pbarInit(prefix,start,end,logname=''): 12 | """ 13 | Initialize ProgressBar 14 | @param string prefix the progress message to pass 15 | @param int start start value (usually 0) 16 | @param int end max value 17 | """ 18 | logg.getLogger(logname).debug(prefix) 19 | if metaInfo.printProgress: 20 | pbar.__init__(prefix,start,end) 21 | pbar.draw() 22 | 23 | def pbarUpdate(newVal): 24 | """ 25 | Update the ProgressBar 26 | @param int newVal new value (current state) 27 | """ 28 | if metaInfo.printProgress: 29 | pbar.update(newVal) 30 | 31 | def pbarClose(): 32 | """ At end of processing, we need a newline """ 33 | if metaInfo.printProgress: print 34 | 35 | 36 | #------------------------------------------------------------------------------ 37 | def printProgress(msg,logname=''): 38 | """ 39 | If config(Logging.progress) evaluates to True, print which step we are performing 40 | @param string msg what to print out 41 | """ 42 | logg.getLogger(logname).debug(msg) 43 | if metaInfo.printProgress: 44 | print msg 45 | 46 | 47 | -------------------------------------------------------------------------------- /sql.keywords: -------------------------------------------------------------------------------- 1 | ABORT 2 | ABSOLUTE 3 | ACCEPT 4 | ACCESS 5 | ACTION 6 | ADA 7 | ADD 8 | ALL 9 | ALLOCATE 10 | ALTER 11 | ANALYZE 12 | AND 13 | ANY 14 | ARCHIVE 15 | ARCHIVELOG 16 | ARE 17 | ARRAY 18 | ARRAYLEN 19 | AS 20 | ASC 21 | ASSERT 22 | ASSERTION 23 | ASSIGN 24 | AT 25 | AUDIT 26 | AUTHORIZATION 27 | AUTO_INCREMENT 28 | AVG 29 | BACKUP 30 | BASE_TABLE 31 | BECOME 32 | BEGIN 33 | BETWEEN 34 | BIT 35 | BIT_LENGTH 36 | BLOB 37 | BLOCK 38 | BODY 39 | BOTH 40 | BY 41 | CACHE 42 | CANCEL 43 | CASCADE 44 | CASCADED 45 | CASE 46 | CAST 47 | CATALOG 48 | CHANGE 49 | CHAR_BASE 50 | CHARACTER_LENGTH 51 | CHAR_LENGTH 52 | CHECK 53 | CHECKPOINT 54 | CLOSE 55 | CLUSTER 56 | CLUSTERS 57 | COALESCE 58 | COBOL 59 | COLAUTH 60 | COLLATE 61 | COLLATION 62 | COLUMN 63 | COMMENT 64 | COMMIT 65 | COMPILE 66 | COMPRESS 67 | CONNECT 68 | CONNECTION 69 | CONSTANT 70 | CONSTRAINT 71 | CONSTRAINTS 72 | CONTENTS 73 | CONTINUE 74 | CONTROLFILE 75 | COPY 76 | CORRESPONDING 77 | COUNT 78 | CRASH 79 | CREATE 80 | CROSS 81 | CURRENT 82 | CURRENT_DATE 83 | CURRENT_TIME 84 | CURRENT_TIMESTAMP 85 | CURRENT_USER 86 | CURRVAL 87 | CURSOR 88 | CYCLE 89 | DATA_BASE 90 | DATABASE 91 | DATAFILE 92 | DAY 93 | DBA 94 | DEALLOCATE 95 | DEBUGOFF 96 | DEBUGON 97 | DECLARE 98 | DECODE 99 | DEFAULT 100 | DEFERRABLE 101 | DEFERRED 102 | DEFINITION 103 | DELAY 104 | DELETE 105 | DELTA 106 | DESC 107 | DESCRIBE 108 | DESCRIPTOR 109 | DIAGNOSTICS 110 | DIGITS 111 | DISABLE 112 | DISCONNECT 113 | DISMOUNT 114 | DISPOSE 115 | DISTINCT 116 | DO 117 | DOMAIN 118 | DOUBLE 119 | DROP 120 | DUMP 121 | EACH 122 | EDITIONABLE 123 | ELSE 124 | ELSIF 125 | ENABLE 126 | ENCODING 127 | END 128 | END-EXEC 129 | ENUM 130 | ENTRY 131 | ERRORS 132 | ESCAPE 133 | EVENTS 134 | EXCEPT 135 | EXCEPTION 136 | EXCEPTION_INIT 137 | EXCLUSIVE 138 | EXEC 139 | EXECUTE 140 | EXISTS 141 | EXIT 142 | EXPLAIN 143 | EXTENT 144 | EXTERNAL 145 | EXTERNALLY 146 | EXTRACT 147 | FALSE 148 | FETCH 149 | FILE 150 | FIRST 151 | FLUSH 152 | FOR 153 | FORALL 154 | FORCE 155 | FOREIGN 156 | FORM 157 | FORTRAN 158 | FOUND 159 | FREELIST 160 | FREELISTS 161 | FROM 162 | FULL 163 | FUNCTION 164 | GENERIC 165 | GET 166 | GLOBAL 167 | GO 168 | GOTO 169 | GRANT 170 | GROUP 171 | HAVING 172 | HOUR 173 | IDENTIFIED 174 | IDENTITY 175 | IF 176 | IMMEDIATE 177 | IN 178 | INCLUDE 179 | INCLUDING 180 | INCREMENTAL 181 | INDEX 182 | INDEXES 183 | INDICATOR 184 | INITIAL 185 | INITIALLY 186 | INITRANS 187 | INNER 188 | INPUT 189 | INSENSITIVE 190 | INSERT 191 | INSTANCE 192 | INTERSECT 193 | INTERVAL 194 | INTO 195 | IS 196 | ISOLATION 197 | ISOPEN 198 | JOIN 199 | KEY 200 | LANGUAGE 201 | LAST 202 | LAYER 203 | LEADING 204 | LEFT 205 | LEVEL 206 | LIKE 207 | LIMITED 208 | LINK 209 | LISTS 210 | LOCAL 211 | LOGFILE 212 | LOCK 213 | LOOP 214 | LOWER 215 | MANAGE 216 | MANUAL 217 | MATCH 218 | MAX 219 | MAXDATAFILES 220 | MAXINSTANCES 221 | MAXLOGFILES 222 | MAXLOGHISTORY 223 | MAXLOGMEMBERS 224 | MAXEXTENTS 225 | MAXTRANS 226 | MAXVALUE 227 | MIN 228 | MINEXTENTS 229 | MINUS 230 | MINUTE 231 | MINVALUE 232 | MLSLABEL 233 | MOD 234 | MODE 235 | MODIFY 236 | MODULE 237 | MONTH 238 | MOUNT 239 | NAMES 240 | NATIONAL 241 | NATURAL 242 | NEW 243 | NEXT 244 | NEXTVAL 245 | NO 246 | NOARCHIVE 247 | NOAUDIT 248 | NOCACHE 249 | NOCOMPRESS 250 | NOCYCLE 251 | NOMAXVALUE 252 | NOMINVALUE 253 | NONE 254 | NOORDER 255 | NORESETLOGS 256 | NORMAL 257 | NOSORT 258 | NOT 259 | NOTFOUND 260 | NOWAIT 261 | NULL 262 | NULLIF 263 | NUMBER_BASE 264 | NVL 265 | OCTET_LENGTH 266 | OF 267 | OFF 268 | OFFLINE 269 | OLD 270 | ON 271 | ONLINE 272 | ONLY 273 | OPEN 274 | OPTIMAL 275 | OPTION 276 | OR 277 | ORDER 278 | OTHERS 279 | OUT 280 | OUTER 281 | OUTPUT 282 | OVERLAPS 283 | OWN 284 | PACKAGE 285 | PAD 286 | PARALLEL 287 | PARTIAL 288 | PARTITION 289 | PASCAL 290 | PCTFREE 291 | PCTINCREASE 292 | PCTUSED 293 | PLAN 294 | PLI 295 | POSITION 296 | POSITIVE 297 | PRAGMA 298 | PRECISION 299 | PREPARE 300 | PRESERVE 301 | PRIMARY 302 | PRIOR 303 | PRIVATE 304 | PRIVILEGES 305 | PROCEDURE 306 | PROFILE 307 | PROMPT 308 | PUBLIC 309 | QUOTA 310 | RAISE 311 | RANGE 312 | RAW 313 | READ 314 | REAL 315 | RECORD 316 | RECOVER 317 | REFERENCES 318 | REFERENCING 319 | RELATIVE 320 | RELEASE 321 | REMR 322 | RENAME 323 | REPLACE 324 | RESETLOGS 325 | RESOURCE 326 | RESTRICT 327 | RESTRICTED 328 | RETURN 329 | REUSE 330 | REVERSE 331 | REVOKE 332 | RIGHT 333 | ROLE 334 | ROLES 335 | ROLLBACK 336 | ROW 337 | ROWID 338 | ROWLABEL 339 | ROWNUM 340 | ROWS 341 | ROWTYPE 342 | RUN 343 | SAVEPOINT 344 | SCHEMA 345 | SCN 346 | SCROLL 347 | SECOND 348 | SECTION 349 | SEGMENT 350 | SELECT 351 | SEPARATE 352 | SEQUENCE 353 | SESSION 354 | SESSION_USER 355 | SET 356 | SHOW 357 | SHARE 358 | SHARED 359 | SIZE 360 | SNAPSHOT 361 | SOME 362 | SORT 363 | SPACE 364 | SQL 365 | SQLBUF 366 | SQLCA 367 | SQLCODE 368 | SQLERRM 369 | SQLERROR 370 | SQLSTATE 371 | SQLWARNING 372 | START 373 | STATEMENT 374 | STATEMENT_ID 375 | STATISTICS 376 | STDDEV 377 | STOP 378 | STORAGE 379 | SUBSTR 380 | SUBSTRING 381 | SUBTYPE 382 | SUCCESSFUL 383 | SUM 384 | SWITCH 385 | SYNONYME 386 | SYSDATE 387 | SYSTEM 388 | SYSTEM_USER 389 | TABAUTH 390 | TABLE 391 | TABLES 392 | TABLESPACE 393 | TASK 394 | TEMPLATE 395 | TEMPORARY 396 | TERMINATE 397 | THEN 398 | THREAD 399 | TIME 400 | TIMEZONE_HOUR 401 | TIMEZONE_MINUTE 402 | TO 403 | TRACING 404 | TRAILING 405 | TRANSACTION 406 | TRANSLATION 407 | TRIGGER 408 | TRIGGERS 409 | TRIM 410 | TRUE 411 | TRUNCATE 412 | TYPE 413 | UID 414 | UNDER 415 | UNION 416 | UNIQUE 417 | UNKNOWN 418 | UNLIMITED 419 | UNSIGNED 420 | UNTIL 421 | UPDATE 422 | UPPER 423 | USAGE 424 | USE 425 | USER 426 | USING 427 | VALIDATE 428 | VALUE 429 | VALUES 430 | VARIANCE 431 | VARYING 432 | VIEW 433 | VIEWS 434 | WARNINGS 435 | WHEN 436 | WHENEVER 437 | WHERE 438 | WHILE 439 | WITH 440 | WORK 441 | WRITE 442 | WORK 443 | XOR 444 | YEAR 445 | ZONE 446 | -------------------------------------------------------------------------------- /sql.types: -------------------------------------------------------------------------------- 1 | BIGINT 2 | BINARY_INTEGER 3 | BLOB 4 | BOOLEAN 5 | CHAR 6 | CHARACTER 7 | CLOB 8 | DATE 9 | DATETIME 10 | DEC 11 | DECIMAL 12 | DOUBLE 13 | FLOAT 14 | INT 15 | INTEGER 16 | LONG 17 | LONGBLOB 18 | LONGTEXT 19 | MEDIUMBLOB 20 | MEDIUMINT 21 | MEDIUMTEXT 22 | NCHAR 23 | NCLOB 24 | NUMBER 25 | NUMERIC 26 | NVARCHAR 27 | REAL 28 | SMALLINT 29 | TEXT 30 | TIMESTAMP 31 | TINYBLOB 32 | TINYINT 33 | TINYTEXT 34 | VARCHAR 35 | VARCHAR2 36 | -------------------------------------------------------------------------------- /tools/gen_sequences_scripts.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- there are no comments on sequences, so we simply extract the CREATE statements 3 | -- 4 | 5 | SET ECHO OFF 6 | SET FEEDBACK OFF 7 | SET SERVEROUT ON 8 | SET SQLBL ON 9 | SET TERMOUT ON 10 | SET PAGES 0 11 | SET LINES 200 12 | SET SERVEROUT ON 13 | 14 | SPOOL sequences.sql 15 | SELECT 'CREATE SEQUENCE '||i.sequence_name||' START WITH '||i.min_value||' INCREMENT BY '||i.increment_by 16 | ||' MAX VALUE '||i.max_value||i.caches||i.cycles||i.orders||';' AS line 17 | FROM ( 18 | SELECT sequence_name,min_value,increment_by,max_value, 19 | (CASE WHEN cache_size=0 THEN ' NOCACHE' ELSE ' CACHE '||cache_size END) AS caches, 20 | (CASE WHEN cycle_flag='Y' THEN ' CYCLE' ELSE ' NOCYCLE' END) AS cycles, 21 | (CASE WHEN order_flag='Y' THEN ' ORDER' ELSE ' NOORDER' END) AS orders 22 | FROM user_sequences 23 | ) i; 24 | SPOOL OFF 25 | 26 | EXIT; 27 | -------------------------------------------------------------------------------- /tools/gen_table_scripts.sql: -------------------------------------------------------------------------------- 1 | /** 2 | * Extract table definitions from data dictionary 3 | * As preparation, you will need an Oracle DIRECTORY to place the created 4 | * scripts into: 5 | * DROP DIRECTORY UTLFILEDIR; 6 | * CREATE OR REPLACE DIRECTORY UTLFILEDIR AS ''; 7 | * GRANT READ, WRITE ON DIRECTORY UTLFILEDIR TO ; 8 | * Replace and to match your needs. If you change the name 9 | * of the directory, you will need to do so in below script as well. 10 | */ 11 | 12 | SET ECHO OFF 13 | SET FEEDBACK OFF 14 | SET SERVEROUT ON 15 | SET SQLBL ON 16 | SET TERMOUT ON 17 | SET PAGES 0 18 | SET LINES 200 19 | 20 | DECLARE 21 | cnt NUMBER; -- in case we want a range only 22 | fh UTL_FILE.FILE_TYPE; 23 | fname VARCHAR2(255); 24 | CURSOR c_tab IS 25 | SELECT table_name 26 | FROM user_tables; 27 | CURSOR c_tabcomment(tname IN VARCHAR2) IS 28 | SELECT '/** '||comments AS line 29 | FROM user_tab_comments 30 | WHERE table_name = tname; 31 | CURSOR c_colcomment(tname IN VARCHAR2) IS 32 | SELECT ' * @col '||t.data_type||' '||t.column_name||' '||c.comments AS line 33 | FROM user_tab_columns t LEFT JOIN user_col_comments c ON (t.table_name=c.table_name AND t.column_name=c.column_name) 34 | WHERE t.table_name=tname; 35 | CURSOR c_grant(tname IN VARCHAR2) IS 36 | SELECT (CASE WHEN grantable='NO' THEN 'GRANT '||privilege||' ON '||tname||' TO '||grantee||';' 37 | ELSE 'GRANT '||privilege||' ON '||tname||' TO '||grantee||' WITH GRANT OPTION;' END) AS line 38 | FROM user_tab_privs 39 | WHERE table_name=tname; 40 | BEGIN 41 | dbms_metadata.set_transform_param(dbms_metadata.session_transform,'EMIT_SCHEMA',false); -- undocumented: remove schema 42 | dbms_metadata.set_transform_param(dbms_metadata.session_transform,'CONSTRAINTS_AS_ALTER',true); -- let's have them separate 43 | dbms_metadata.set_transform_param (dbms_metadata.session_transform, 'SEGMENT_ATTRIBUTES', false); -- skip nasty defaults 44 | dbms_metadata.set_transform_param (dbms_metadata.session_transform, 'SQLTERMINATOR', true); -- end each statement with ';' 45 | dbms_metadata.set_transform_param (dbms_metadata.session_transform, 'PRETTY', true); -- not sure what gets prettier here 46 | cnt := 0; 47 | FOR rec IN c_tab LOOP 48 | cnt := cnt +1; 49 | IF cnt < 1 THEN 50 | CONTINUE; 51 | END IF; 52 | fname := lower(rec.table_name)||'.sql'; 53 | fh := utl_file.fopen('UTLFILEDIR',fname,'W',32767); 54 | FOR r1 IN c_tabcomment(rec.table_name) LOOP 55 | utl_file.put_line(fh,r1.line); 56 | END LOOP; 57 | utl_file.put_line(fh,' * @table '||rec.table_name); 58 | FOR r1 IN c_colcomment(rec.table_name) LOOP 59 | utl_file.put_line(fh,r1.line); 60 | END LOOP; 61 | utl_file.put_line(fh,' */'); 62 | utl_file.putf(fh,dbms_metadata.get_ddl( object_type => 'TABLE' , name => rec.table_name)||'\n'); 63 | BEGIN 64 | utl_file.putf(fh,dbms_metadata.get_dependent_ddl('COMMENT',rec.table_name)||'\n'); 65 | EXCEPTION 66 | WHEN OTHERS THEN NULL; -- no comments found 67 | END; 68 | FOR r1 IN c_grant(rec.table_name) LOOP 69 | utl_file.put_line(fh,r1.line); 70 | END LOOP; 71 | utl_file.fclose(fh); 72 | -- exit; 73 | END LOOP; 74 | EXCEPTION 75 | WHEN utl_file.invalid_path THEN raise_application_error(-20000, 'ERROR: Invalid PATH FOR file.'); 76 | END; 77 | / 78 | 79 | EXIT; 80 | -------------------------------------------------------------------------------- /tools/gen_view_scripts.sql: -------------------------------------------------------------------------------- 1 | /** 2 | * Extract view definitions from data dictionary 3 | * As preparation, you will need an Oracle DIRECTORY to place the created 4 | * scripts into: 5 | * DROP DIRECTORY UTLFILEDIR; 6 | * CREATE OR REPLACE DIRECTORY UTLFILEDIR AS ''; 7 | * GRANT READ, WRITE ON DIRECTORY UTLFILEDIR TO ; 8 | * Replace and to match your needs. If you change the name 9 | * of the directory, you will need to do so in below script as well. 10 | */ 11 | 12 | SET ECHO OFF 13 | SET FEEDBACK OFF 14 | SET SERVEROUT ON 15 | SET SQLBL ON 16 | SET TERMOUT ON 17 | SET PAGES 0 18 | SET LINES 200 19 | 20 | DECLARE 21 | cnt NUMBER; -- in case we want a range only 22 | fh UTL_FILE.FILE_TYPE; 23 | fname VARCHAR2(255); 24 | CURSOR c_tab IS 25 | SELECT view_name as table_name 26 | FROM user_views; 27 | CURSOR c_tabcomment(tname IN VARCHAR2) IS 28 | SELECT '/** '||comments AS line 29 | FROM user_tab_comments 30 | WHERE table_name = tname; 31 | CURSOR c_colcomment(tname IN VARCHAR2) IS 32 | SELECT ' * @col '||t.data_type||' '||t.column_name||' '||c.comments AS line 33 | FROM user_tab_columns t LEFT JOIN user_col_comments c ON (t.table_name=c.table_name AND t.column_name=c.column_name) 34 | WHERE t.table_name=tname; 35 | CURSOR c_grant(tname IN VARCHAR2) IS 36 | SELECT (CASE WHEN grantable='NO' THEN 'GRANT '||privilege||' ON '||tname||' TO '||grantee||';' 37 | ELSE 'GRANT '||privilege||' ON '||tname||' TO '||grantee||' WITH GRANT OPTION;' END) AS line 38 | FROM user_tab_privs 39 | WHERE table_name='EOX_ARBEITSTAGE'; 40 | BEGIN 41 | dbms_metadata.set_transform_param(dbms_metadata.session_transform,'EMIT_SCHEMA',false); -- undocumented: remove schema 42 | dbms_metadata.set_transform_param(dbms_metadata.session_transform,'CONSTRAINTS_AS_ALTER',true); -- let's have them separate 43 | dbms_metadata.set_transform_param (dbms_metadata.session_transform, 'SEGMENT_ATTRIBUTES', false); -- skip nasty defaults 44 | dbms_metadata.set_transform_param (dbms_metadata.session_transform, 'SQLTERMINATOR', true); -- end each statement with ';' 45 | dbms_metadata.set_transform_param (dbms_metadata.session_transform, 'PRETTY', true); -- not sure what gets prettier here 46 | cnt := 0; 47 | FOR rec IN c_tab LOOP 48 | cnt := cnt +1; 49 | IF cnt < 1 THEN 50 | CONTINUE; 51 | END IF; 52 | fname := lower(rec.table_name)||'.sql'; 53 | fh := utl_file.fopen('UTLFILEDIR',fname,'W',32767); 54 | FOR r1 IN c_tabcomment(rec.table_name) LOOP 55 | utl_file.put_line(fh,r1.line); 56 | END LOOP; 57 | utl_file.putf(fh,' * @view '||rec.table_name||'\n'); 58 | FOR r1 IN c_colcomment(rec.table_name) LOOP 59 | utl_file.put_line(fh,r1.line); 60 | END LOOP; 61 | utl_file.put_line(fh,' */'); 62 | utl_file.putf(fh,dbms_metadata.get_ddl( object_type => 'VIEW' , name => rec.table_name)||'\n'); 63 | BEGIN 64 | utl_file.putf(fh,dbms_metadata.get_dependent_ddl('COMMENT',rec.table_name)||'\n'); 65 | EXCEPTION 66 | WHEN OTHERS THEN NULL; -- no comments found 67 | END; 68 | FOR r1 IN c_grant(rec.table_name) LOOP 69 | utl_file.put_line(fh,r1.line); 70 | END LOOP; 71 | utl_file.fclose(fh); 72 | -- exit; 73 | END LOOP; 74 | EXCEPTION 75 | WHEN utl_file.invalid_path THEN raise_application_error(-20000, 'ERROR: Invalid PATH FOR file.'); 76 | END; 77 | / 78 | 79 | EXIT; 80 | --------------------------------------------------------------------------------