|
@@ -1,281 +0,0 @@
|
|
|
-$Date$
|
|
|
-
|
|
|
-NOTE: Please improve this list!
|
|
|
-
|
|
|
-Dear (new) GRASS Developer,
|
|
|
-
|
|
|
-When submitting TCL and TK SCRIPTS to GRASS SVN repository,
|
|
|
-please take care of following rules:
|
|
|
-
|
|
|
-[ see SUBMITTING for C code hints ]
|
|
|
-[ see SUBMITTING_SCRIPTS for shell script hints ]
|
|
|
-[ see SUBMITTING_DOCS for documentation ]
|
|
|
-[ see SUBMITTING_PYTHON for Python code hints ]
|
|
|
-
|
|
|
-
|
|
|
-1. Use the directory structure to place your program appropriately into
|
|
|
- the source tree
|
|
|
- - general grass tcl/tk libraries and reusable code go into lib/gtcltk
|
|
|
- - user interfaces go in gui/tcltk
|
|
|
- - scripts go in scripts/
|
|
|
- Programs here must have a proper Makefile and description.html
|
|
|
-
|
|
|
-
|
|
|
-2. Add a header section to the script you submit and make sure you include
|
|
|
- the copyright. The purpose section is meant to contain a general
|
|
|
- overview of the code in the file to assist other programmers that will
|
|
|
- need to make changes to your code.
|
|
|
-
|
|
|
- Example (fictitious header for a script called r.myscript) :
|
|
|
-
|
|
|
-############################################################################
|
|
|
-#
|
|
|
-# MODULE: r.myscript
|
|
|
-# AUTHOR(S): Me <email AT some domain>
|
|
|
-# PURPOSE: Calculates univariate statistics from a GRASS raster map
|
|
|
-# COPYRIGHT: (C) 2005 by the GRASS Development Team
|
|
|
-#
|
|
|
-# This program is free software under the GNU General Public
|
|
|
-# License (>=v2). Read the file COPYING that comes with GRASS
|
|
|
-# for details.
|
|
|
-#
|
|
|
-#############################################################################
|
|
|
-
|
|
|
- The copyright protects your rights according to GNU General Public
|
|
|
- License (www.gnu.org).
|
|
|
-
|
|
|
-
|
|
|
-3. PLEASE take the time to add comments throughout your code explaining what
|
|
|
- the code is doing. It will save a HUGE amount of time and frustration for
|
|
|
- other programmers that need to change or understand your code in the future.
|
|
|
- Many of the programmers working on grass are not heavily invested in tcl
|
|
|
- and tk, so extra documentation and explanation are greatly appreciated.
|
|
|
-
|
|
|
-
|
|
|
-4. Test your program with both tcl/tk 8.3 and tcl/tk 8.4.
|
|
|
-
|
|
|
-
|
|
|
-5. Always use the gettext macros with [G_msg "..."] for user messages.
|
|
|
- The string must be quoted using quotation marks, not braces, for
|
|
|
- xgettext to find it. The string cannot include variable ($) or
|
|
|
- command ([...]) substitutions. If you need substitutions use
|
|
|
- [format ...].
|
|
|
-
|
|
|
- Examples:
|
|
|
- button .ok -text [G_msg "Ok"]
|
|
|
-
|
|
|
- set statusbartext [format [G_msg "Monitor %d running"] $monitor_number]]
|
|
|
-
|
|
|
- Use positional parameters if substitutions might be rearranged in another language:
|
|
|
-
|
|
|
- format [G_msg "We produced %1\$d units in location %2\$s"] $num $city
|
|
|
- format [G_msg "In location %2\$s we produced %1\$d units"] $num $city
|
|
|
-
|
|
|
-
|
|
|
-6. Use "GRASS_TCLSH" and "GRASS_WISH" environment variables instead of
|
|
|
- "tclsh" and "wish" at the start of Tcl/Tk scripts. This allows users to
|
|
|
- override the default names, so that developers don't need worry about the
|
|
|
- shell names.
|
|
|
-
|
|
|
- Tcl script:
|
|
|
-
|
|
|
- #!/bin/sh
|
|
|
- # the next line restarts using tclsh. Note the backslash: \
|
|
|
- exec $GRASS_TCLSH "$0" "$@"
|
|
|
-
|
|
|
-
|
|
|
- Tk script:
|
|
|
-
|
|
|
- #!/bin/sh
|
|
|
- # the next line restarts using wish. Note the backslash: \
|
|
|
- exec $GRASS_WISH "$0" "$@"
|
|
|
-
|
|
|
-
|
|
|
-7. Do not source files that have already been sourced.
|
|
|
-
|
|
|
- gui.tcl sources:
|
|
|
- options.tcl
|
|
|
- select.tcl
|
|
|
- gronsole.tcl
|
|
|
-
|
|
|
- If your code requires something to be sourced before it note so
|
|
|
- in a comment at the top of the file.
|
|
|
-
|
|
|
-
|
|
|
-8. Set tabstops in your editor to 8 spaces.
|
|
|
- When modifying files use the indentation style that is already present.
|
|
|
- Please use consistent indentation style in your new code. Whether you use
|
|
|
- tabs or spaces to indent please be consistent. Where tabs and spaces are
|
|
|
- mixed please remember that a tab is 8 spaces.
|
|
|
-
|
|
|
-
|
|
|
-9. Use the tk options database to control the appearance of your user interface.
|
|
|
- In general do not set options on tk widgets unless that option is truly
|
|
|
- specific to that widget. It makes them harder to customize.
|
|
|
-
|
|
|
- Example: Don't set options like -foreground or -background or -font
|
|
|
- when creating widgets, unless there's a really _really_ specific reason to
|
|
|
- have it that color (like it's demonstrating that color).
|
|
|
-
|
|
|
- If you want something like a label to look different than everything else
|
|
|
- of that class (other labels) give it a distinctive name, like
|
|
|
- .moduletitlelabel . If you have a bunch of them give them all the same
|
|
|
- distinctive name. This allows them to have their options controlled by the
|
|
|
- options database.
|
|
|
-
|
|
|
- You can put your options at the start of your script (before creating any
|
|
|
- widgets) like this:
|
|
|
- option add *modultitlelabel.background red
|
|
|
- More examples are in lib/gtcltk/options.tcl
|
|
|
-
|
|
|
- Many common options, like font, background and foreground colors,
|
|
|
- highlighting, scrollbar colors, and help bubble appearance are controlled
|
|
|
- by options.tcl. You can include it at the start of your script with:
|
|
|
- source $env(GISBASE)/etc/gtcltk/options.tcl
|
|
|
-
|
|
|
-
|
|
|
-10. Avoid using global variables. Thay are a frequent source of bugs, make code
|
|
|
- harder to understand, and make your program difficult to reuse. Additionally,
|
|
|
- putting code into procs usually makes it run faster (it gets compiled).
|
|
|
-
|
|
|
-
|
|
|
-11. For consistency, use README rather than README.txt for any README files.
|
|
|
-
|
|
|
-
|
|
|
-12. Use of GRASS commands in shell wrapper.
|
|
|
-
|
|
|
- Any GRASS program run in an xterm (those which do interactive query) needs
|
|
|
- to use grass-run.sh, e.g.:
|
|
|
-
|
|
|
- exec -- $env(GISBASE)/etc/grass-xterm-wrapper -e $env(GISBASE)/etc/grass-run.sh g.proj ...
|
|
|
-
|
|
|
- You should probably also use "-T g.proj -n g.proj" to set the title
|
|
|
- back (otherwise it will be "grass-run.sh", which isn't particularly
|
|
|
- informative).
|
|
|
-
|
|
|
- The xterm will close as soon as the command completes (whether it
|
|
|
- succeeds or fails). You can use the -hold switch to retain the xterm
|
|
|
- window after the command completes, but you should only do that for
|
|
|
- debugging; having to manually close the xterm window each time would
|
|
|
- be annoying in normal use. Alternatively, redirect stdout/stderr to a
|
|
|
- file, to catch any error messages.
|
|
|
-
|
|
|
-
|
|
|
-13. Be sure to develop on top of the LATEST GRASS code (which is in
|
|
|
- SVN repository). You can re-check before submission with 'svn
|
|
|
- diff':
|
|
|
-
|
|
|
- Be sure to create unified ("diff -u") format. "Plain"
|
|
|
- diffs (the default format) are risky, because they will apply without
|
|
|
- warning to code which has been substantially changed; they are also
|
|
|
- harder to read than unified.
|
|
|
-
|
|
|
- Such diffs should be made from the top-level directory, e.g.
|
|
|
- "cvs diff display/d.vect/main.c"; that way, the diff will
|
|
|
- include the pathname rather than just "main.c".
|
|
|
-
|
|
|
-
|
|
|
-14. Tell the other developers about the new code using the following e-mail:
|
|
|
- grass-dev@lists.osgeo.org
|
|
|
-
|
|
|
- To subscribe to this mailing list, see
|
|
|
- http://lists.osgeo.org/mailman/listinfo/grass-dev
|
|
|
-
|
|
|
-
|
|
|
-15. In case of questions feel free to contact the developers at the above
|
|
|
- mailing list.
|
|
|
- http://www.grass-gis.org/devel/index.php#submission
|
|
|
-
|
|
|
-
|
|
|
-16. Try to evaluate things only once. Tcl compiles the program to bytecode which
|
|
|
- can be interpreted fairly quickly. If there are strings that must still be
|
|
|
- evaluated tcl must parse and either compile or interpret them
|
|
|
- each time they are encountered. In general this means put braces around
|
|
|
- expressions and especially regular expressions (Tcl also compiles regular
|
|
|
- expressions). Multiple evaluation can also lead to bugs.
|
|
|
-
|
|
|
- Expressions via expr command:
|
|
|
- Slow:
|
|
|
- set y [expr $a * $x + $b]
|
|
|
- Fast:
|
|
|
- set y [expr {$a * $x + $b}]
|
|
|
-
|
|
|
- Expressions in conditions:
|
|
|
- Slow:
|
|
|
- if [...] {...
|
|
|
- Fast:
|
|
|
- if {[...]} {...
|
|
|
-
|
|
|
- Regular expressions:
|
|
|
- Very slow:
|
|
|
- regex "x(\[0-9\]+).*not" $string trash number
|
|
|
- Fast:
|
|
|
- regex {x([0-9]+).*not} $string trash number
|
|
|
-
|
|
|
- If you really want speed:
|
|
|
- If a regular expression needs to be constructed from variables but used
|
|
|
- multiple times store it in a variable that will not be destroyed or
|
|
|
- changed between reuse. Tcl stores the compiled regex with the variable.
|
|
|
-
|
|
|
-
|
|
|
-17. You might want to decompose lists in a somewhat easy way:
|
|
|
-
|
|
|
- Difficult and slow:
|
|
|
- # Make x1 y1 x2 y2 the first four things in the list
|
|
|
- set list [commandMakesList]
|
|
|
- set x1 [lindex $list 0]
|
|
|
- set y1 [lindex $list 1]
|
|
|
- set x2 [lindex $list 2]
|
|
|
- set y2 [lindex $list 3]
|
|
|
-
|
|
|
- Easier and faster:
|
|
|
- # Make x1 y1 x2 y2 the first four things in the list
|
|
|
- foreach {x1 y1 x2 y2} [commandMakesList] {break}
|
|
|
-
|
|
|
- Be sure to include a comment as to what you are doing.
|
|
|
-
|
|
|
-
|
|
|
-18. Use the Tcl list functions (list, lappend etc) for manipulating lists.
|
|
|
-
|
|
|
- For example, use:
|
|
|
-
|
|
|
- set vals [list $foo $bar]
|
|
|
-
|
|
|
- rather than:
|
|
|
-
|
|
|
- set vals "$foo $bar"
|
|
|
-
|
|
|
- The former will always create a list with two elements, adding braces
|
|
|
- if necessary, while the latter will split $foo and $bar into multiple
|
|
|
- elements if they contain spaces. Additionally the first is faster
|
|
|
- because tcl is not internally converting between strings and lists.
|
|
|
-
|
|
|
- A related issue is to remember that command lines (as used by exec and
|
|
|
- open "|...") are lists. exec behaves like execl(), spawnl() etc, and
|
|
|
- not like system().
|
|
|
-
|
|
|
- Overlooking either of these points is likely to result in code which
|
|
|
- fails when a command argument contains a space.
|
|
|
-
|
|
|
-
|
|
|
-19. Tcl C library:
|
|
|
- Memory allocated with Tcl_Alloc (such as the result of Tcl_Merge)
|
|
|
- must be freed with Tcl_Free. This means that the ->freeProc of
|
|
|
- an interpreter when returning a string using Tcl_Merge should be
|
|
|
- TCL_DYNAMIC. Incorrectly freeing memory with glibc free will
|
|
|
- cause segfaults in Tcl 8.4 and later.
|
|
|
-
|
|
|
-
|
|
|
-20. When submitting new files to the repository set SVN properties,
|
|
|
- e.g.
|
|
|
-
|
|
|
- svn:executable : *
|
|
|
- svn:mime-type : text/x-tcl
|
|
|
- svn:keywords : Author Date Id
|
|
|
- svn:eol-style : native
|
|
|
-
|
|
|
- See
|
|
|
- http://svnbook.red-bean.com/en/1.4/svn.advanced.props.html
|
|
|
-
|
|
|
-...
|
|
|
-[please add further hints if required]
|