Difference between revisions of "Little Helpers"
(→mkd: enable parallel dmake) |
|||
(29 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
Here are some '''Little Helpers''' for the enthusiastic developer, such as | Here are some '''Little Helpers''' for the enthusiastic developer, such as | ||
− | + | small scripts that help to tame the OOo code base. | |
Line 15: | Line 15: | ||
[http://jroller.com/page/erAck?entry=gnu_id_utils this blog entry]. | [http://jroller.com/page/erAck?entry=gnu_id_utils this blog entry]. | ||
− | The ID-utils come with an<br> | + | The ID-utils come with an <br> |
− | '';;; id-utils.el -- emacs interface to `lid -R grep', a.k.a. `gid' ''<br> | + | '';;; id-utils.el -- emacs interface to `lid -R grep', a.k.a. `gid' '' <br> |
− | For how to interface with the ''vim'' editor see [[#Vim_and_the_GNU_ID-utils | | + | For how to interface with the ''vim'' editor see the |
+ | [[Editor_Vim#Vim_and_the_GNU_ID-utils | Vim editor's GNU ID-utils]] section. | ||
Generally, the editor invoking functionality of ID-utils uses the shell | Generally, the editor invoking functionality of ID-utils uses the shell | ||
variables ''VISUAL'' or ''EDITOR'', ''EIDARG'', ''EIDLDEL'' and ''EIDRDEL'', so | variables ''VISUAL'' or ''EDITOR'', ''EIDARG'', ''EIDLDEL'' and ''EIDRDEL'', so | ||
Line 55: | Line 56: | ||
# Treat OOo/SO resource header files as C files | # Treat OOo/SO resource header files as C files | ||
*.hrc C | *.hrc C | ||
+ | # Treat OOo/SO header files generated from *.idl as C++ files | ||
+ | *.hdl C++ | ||
+ | # Treat OOo IDL files as C++ files, not exactly a header file, but ... | ||
+ | *.idl C++ | ||
# Treat OOo/SO resource files as C files | # Treat OOo/SO resource files as C files | ||
*.src C | *.src C | ||
Line 66: | Line 71: | ||
Then the script below may be invoked either | Then the script below may be invoked either | ||
* In a module's directory without parameters, creating an ID database for just the single module. | * In a module's directory without parameters, creating an ID database for just the single module. | ||
− | * In the ''$SRC_ROOT'' directory for all modules: <code>mkid-script '*'</code><br> Note the literal '*' asterisk that is not to be expanded by the shell | + | * In the ''$SRC_ROOT'' directory for all modules: <code>mkid-script '*'</code> <br> Note the literal '*' asterisk that is not to be expanded by the shell. <br> The file size of the generated ''ID'' file using this method currently (m223) is 31MB. |
− | * In the ''$SRC_ROOT'' directory for specified modules: <code>mkid-script '{module1,module2,solver}'</code><br> Again, note the literal argument enclosed in single quotes for the file name expansion, which is done by the script. If the argument was not passed literally, only the first module would be included, and other strange things may happen.. Wildcards may be used as usual.<br> It is a good idea to include the ''solver'' module to gather identifiers from delivered header files.<br> Ignore messages like<br> ''mkid: can't lstat `unxlngi4.pro' from `.../SRC680/src.m180/solver' '' or<br> ''mkid: can't lstat `build' from `.../SRC680/src.m180/module1/unxlngi4.pro/misc' ''<br> They result from the INPATH relevant arguments passed for each module and don't harm. | + | * In the ''$SRC_ROOT'' directory for specified modules: <br> <code>mkid-script '{module1,module2,solver}'</code> <br> Again, note the literal argument enclosed in single quotes for the file name expansion, which is done by the script. If the argument was not passed literally, only the first module would be included, and other strange things may happen.. Wildcards may be used as usual. <br> It is a good idea to include the ''solver'' module to gather identifiers from delivered header files. <br> Ignore messages like <br> ''mkid: can't lstat `unxlngi4.pro' from `.../SRC680/src.m180/solver' '' or <br> ''mkid: can't lstat `build' from `.../SRC680/src.m180/module1/unxlngi4.pro/misc' '' <br> They result from the INPATH relevant arguments passed for each module and don't harm. |
You may also manually invoke ''mkid'' in the ''$SRC_ROOT'' directory for all | You may also manually invoke ''mkid'' in the ''$SRC_ROOT'' directory for all | ||
modules, this is a safe bet but may include more than you want if you have | modules, this is a safe bet but may include more than you want if you have | ||
output directories for multiple platforms, all identifiers present there will | output directories for multiple platforms, all identifiers present there will | ||
− | get duplicated, triplicated, ... the command line for this is<br> | + | get duplicated, triplicated, ... the command line for this is <br> |
<code>mkid --lang-map=$HOME/devbase/id-lang.map --statistics</code> | <code>mkid --lang-map=$HOME/devbase/id-lang.map --statistics</code> | ||
Line 85: | Line 90: | ||
# specified as literal '*' unexpanded. Will be expanded here. | # specified as literal '*' unexpanded. Will be expanded here. | ||
# Instead of '*' _any_ shell wildcard should be possible, e.g. '{.,bf_*}'. | # Instead of '*' _any_ shell wildcard should be possible, e.g. '{.,bf_*}'. | ||
+ | # Output directories except $INPATH/inc and $INPATH/misc/build are skipped in | ||
+ | # these cases. | ||
+ | # A simple ALL generator, not ignoring any directory, is the parameter 'all'. | ||
+ | # Warning, that may create a huge database and massively duplicated entries if | ||
+ | # more than one platform's output directory exists. | ||
if ( { ( which mkid >> /dev/null ) } ) then | if ( { ( which mkid >> /dev/null ) } ) then | ||
echo generating IDs | echo generating IDs | ||
+ | if ( "$1" == "-o" ) then | ||
+ | set output="--output=$2" | ||
+ | shift | ||
+ | shift | ||
+ | else | ||
+ | set output="" | ||
+ | endif | ||
if ( "$1" == "" ) then | if ( "$1" == "" ) then | ||
set module="." | set module="." | ||
#set exclude=./{common,unxlngi6,unxsols4,wntmsci10}{,.pro} | #set exclude=./{common,unxlngi6,unxsols4,wntmsci10}{,.pro} | ||
− | # | + | # Wildcards not only make updates unnecessary but also suppress "no |
− | set exclude=./{common*,unxlng*,unxsol*,wntmsc*} | + | # match" error messages. The CVS* and .svn* directories are included |
− | else if ( "$1" == "*" ) then | + | # for the case of a freshly checked out source that does not have any |
+ | # output directories yet. Otherwise that would still lead to a "no | ||
+ | # match" error if no wildcarded names matched. | ||
+ | set exclude=./{CVS*,.svn*,common*,*unxlng*,*unxsol*,*unxmac*,*wntmsc*} | ||
+ | else if ( "`basename '$1'`" == "*" ) then | ||
set module="$1" | set module="$1" | ||
echo module: $module | echo module: $module | ||
# prevent command line overflow with a full exclude | # prevent command line overflow with a full exclude | ||
set exclude="x" | set exclude="x" | ||
+ | echo exclude: $exclude | ||
+ | else if ( "$1" == "all" ) then | ||
+ | set module="$1" | ||
+ | echo module: $module | ||
+ | set exclude="nothing" | ||
echo exclude: $exclude | echo exclude: $exclude | ||
else | else | ||
set module="$1" | set module="$1" | ||
echo module: $module | echo module: $module | ||
− | set exclude=$1/{common*,unxlng*,unxsol*,wntmsc*} | + | set exclude=$1/{CVS*,.svn*,common*,*unxlng*,*unxsol*,*unxmac*,*wntmsc*} |
echo exclude: $exclude | echo exclude: $exclude | ||
endif | endif | ||
− | if ( "$1" == "*" ) then | + | if ( "`basename '$1'`" == "*" ) then |
− | # | + | # test for ls overrun |
− | set | + | set dcommand="ls -d $module/*" |
+ | if ( ! { ( $dcommand >> /dev/null ) } ) then | ||
+ | echo "$0 : ls overrun, trying find $module -mindepth 1 -maxdepth 1" | ||
+ | # test for find mindepth/maxdepth availability | ||
+ | set dcommand="find $module -mindepth 1 -maxdepth 1" | ||
+ | if ( ! { ( $dcommand >> /dev/null ) } ) then | ||
+ | echo "$0 : find doesn't know options -mindepth -maxdepth" | ||
+ | echo "$0 : too bad, giving up." | ||
+ | exit 1 | ||
+ | endif | ||
+ | endif | ||
+ | # Only positive list of module subdirectories and files, | ||
+ | # excluding output directories except $INPATH/{inc,misc/build} | ||
+ | set dirs="$module/$INPATH/inc $module/$INPATH/misc/build `$dcommand | sed -e '/\(\/\(CVS\|common\|.*unxlng\|.*unxsol\|.*unxmac\|.*wntmsc\|Jamfile\|cscope\.\|tags\|ID\)\)\|^solver\//d'`" | ||
echo dirs: $dirs | echo dirs: $dirs | ||
− | mkid --lang-map=$HOME/devbase/id-lang.map --statistics $dirs | + | echo Creating output: $output |
+ | mkid --lang-map=$HOME/devbase/id-lang.map --include='C C++ asm perl java make' $output --statistics $dirs | ||
+ | else if ( "$1" == "all" ) then | ||
+ | echo Creating output: $output | ||
+ | mkid --lang-map=$HOME/devbase/id-lang.map --include='C C++ asm perl java make' $output --statistics | ||
else | else | ||
# all but negative list plus INPATH relevants | # all but negative list plus INPATH relevants | ||
− | mkid --lang-map=$HOME/devbase/id-lang.map --statistics --prune="$exclude" $module $module/$INPATH/inc $module/$INPATH/misc/build | + | echo Creating output: $output |
+ | mkid --lang-map=$HOME/devbase/id-lang.map --include='C C++ asm perl java make' $output --statistics --prune="$exclude" $module $module/$INPATH/inc $module/$INPATH/misc/build | ||
endif | endif | ||
− | |||
− | |||
− | |||
else | else | ||
Line 154: | Line 195: | ||
# no positive dirs list was used. | # no positive dirs list was used. | ||
− | if ( { ( which | + | if ( "$?MYCTAGS" == "0" ) then |
+ | set MYCTAGS="ctags" | ||
+ | endif | ||
+ | |||
+ | if ( { ( which "$MYCTAGS" >> /dev/null ) } ) then | ||
echo generating ctags | echo generating ctags | ||
# Options necessary for the Vim OmniCppComplete plugin, | # Options necessary for the Vim OmniCppComplete plugin, | ||
Line 166: | Line 211: | ||
if ( "$1" == "--global" ) then | if ( "$1" == "--global" ) then | ||
if ( ! $?UPDMINOREXT ) set UPDMINOREXT="" | if ( ! $?UPDMINOREXT ) set UPDMINOREXT="" | ||
− | + | "$MYCTAGS" -h "+.hdl.hrc" --langmap=c:+.hdl.hrc.src $omnicppoptions -R $SOLARVERSION/$INPATH/inc$UPDMINOREXT | |
else | else | ||
if ( "$1" == "" ) then | if ( "$1" == "" ) then | ||
Line 174: | Line 219: | ||
echo module: $module | echo module: $module | ||
endif | endif | ||
− | set | + | # test for ls overrun |
− | + | set dcommand="ls -d $module/*" | |
+ | if ( ! { ( $dcommand >> /dev/null ) } ) then | ||
+ | echo "$0 : ls overrun, trying find $module -mindepth 1 -maxdepth 1" | ||
+ | # test for find mindepth/maxdepth availability | ||
+ | set dcommand="find $module -mindepth 1 -maxdepth 1" | ||
+ | if ( ! { ( $dcommand >> /dev/null ) } ) then | ||
+ | echo "$0 : find doesn't know options -mindepth -maxdepth" | ||
+ | echo "$0 : too bad, giving up." | ||
+ | exit 1 | ||
+ | endif | ||
+ | endif | ||
+ | # Only positive list of module subdirectories and files, | ||
+ | # excluding output directories except $INPATH/{inc,misc/build} | ||
+ | set dirs="$module/$INPATH/inc $module/$INPATH/misc/build `$dcommand | sed -e '/\(\/\(CVS\|\.svn\|common\|.*unxlng\|.*unxsol\|.*unxmac\|.*wntmsc\|Jamfile\|cscope\.\|tags\|ID\)\)\|^solver\//d'`" | ||
+ | echo dirs: $dirs | ||
+ | "$MYCTAGS" -h "+.hdl.hrc" --langmap=c:+.hdl.hrc.src $omnicppoptions -R $dirs | ||
endif | endif | ||
else | else | ||
Line 183: | Line 243: | ||
Ignore messages like<br> | Ignore messages like<br> | ||
− | ''ctags: Warning: cannot open source file "./ | + | ''ctags: Warning: cannot open source file "./unxlngi6.pro/misc/build" : No such file or directory''<br> |
or consider them purely informational. | or consider them purely informational. | ||
Line 195: | Line 255: | ||
script without parameters, then <code>cd $SRC_ROOT</code> and invoke | script without parameters, then <code>cd $SRC_ROOT</code> and invoke | ||
<code>scriptname --global</code> to produce a tags file for the ''solver''. | <code>scriptname --global</code> to produce a tags file for the ''solver''. | ||
+ | |||
+ | A final <tt>ctags</tt> note: In some cases, you might have more than one version of <tt>ctags</tt> on your system. E.g., there is a version that ships with Emacs (and is often in <tt>/usr/local/bin</tt>) that doesn't support the same arguments as Exhuberant <tt>ctags</tt>; if this is the case (you'll see an error message from the script like "<tt>unrecognized option `--langmap=c:+.hdl.hrc.src'</tt>") then you can set the MYCTAGS variable, e.g., from a <tt>bash</tt> shell: | ||
+ | <pre> | ||
+ | MYCTAGS=/usr/bin/ctags $HOME/devbase/ctags-script --global | ||
+ | MYCTAGS=/usr/bin/ctags CTAGS=-e $HOME/devbase/ctags-script --global # generate TAGS for Emacs | ||
+ | </pre> | ||
+ | If all you have is the Emacs version, you will want to rewrite the script (or provide a better solution here). | ||
=== Cscope === | === Cscope === | ||
Line 231: | Line 298: | ||
echo module: $module | echo module: $module | ||
endif | endif | ||
− | set | + | # test for ls overrun |
+ | set dcommand="ls -d $module/*" | ||
+ | if ( ! { ( $dcommand >> /dev/null ) } ) then | ||
+ | echo "$0 : ls overrun, trying find $module -mindepth 1 -maxdepth 1" | ||
+ | # test for find mindepth/maxdepth availability | ||
+ | set dcommand="find $module -mindepth 1 -maxdepth 1" | ||
+ | if ( ! { ( $dcommand >> /dev/null ) } ) then | ||
+ | echo "$0 : find doesn't know options -mindepth -maxdepth" | ||
+ | echo "$0 : too bad, giving up." | ||
+ | exit 1 | ||
+ | endif | ||
+ | endif | ||
+ | # Only positive list of module subdirectories and files, | ||
+ | # excluding output directories except $INPATH/{inc,misc/build} | ||
+ | set dirs="$module/$INPATH/inc $module/$INPATH/misc/build `$dcommand | sed -e '/\(\/\(CVS\|\.svn\|common\|.*unxlng\|.*unxsol\|.*unxmac\|.*wntmsc\|Jamfile\|cscope\.\|tags\|ID\)\)\|^solver\//d'`" | ||
+ | echo dirs: $dirs | ||
( find $dirs -name '*.[hc]' -o -name '*.[hc]xx' -o -name '*.[hc]pp' -o -name '*.[hs]rc' >cscope.files ) >>& /dev/null | ( find $dirs -name '*.[hc]' -o -name '*.[hc]xx' -o -name '*.[hc]pp' -o -name '*.[hs]rc' >cscope.files ) >>& /dev/null | ||
if ( `uname` == "SunOS" ) then | if ( `uname` == "SunOS" ) then | ||
Line 244: | Line 326: | ||
Note that the ''find'' command is executed in a subshell with stderr redirected | Note that the ''find'' command is executed in a subshell with stderr redirected | ||
− | to /dev/null to suppress all the ''find: ./ | + | to /dev/null to suppress all the ''find: ./unxlngi6.pro/misc/build: No such file or directory'' |
and the like warning messages. Remove the parentheses and the redirection in | and the like warning messages. Remove the parentheses and the redirection in | ||
case you suspect errors in your environment. | case you suspect errors in your environment. | ||
Line 274: | Line 356: | ||
databases for that single module. | databases for that single module. | ||
+ | == Build selected source code files with debug == | ||
+ | |||
+ | Sometimes only a few files need to be build with debug instead of an entire | ||
+ | module, which significantly saves time. Change into the directory and invoke | ||
+ | the following script with the files of interest passed as arguments, for | ||
+ | example, in <tt>sc/source/core/tool</tt> | ||
− | = | + | <source lang="bash"> |
+ | mkd token.cxx compiler.cxx interpr*.cxx | ||
+ | </source> | ||
− | + | To also link the library in the module's ''util'' directory pass the ''--link'' | |
− | + | or ''-l'' option: | |
− | + | ||
− | + | <source lang="bash"> | |
− | + | mkd -l token.cxx compiler.cxx interpr*.cxx | |
+ | </source> | ||
+ | |||
+ | === mkd === | ||
+ | |||
+ | <source lang="bash"> | ||
+ | #!/bin/bash | ||
+ | |||
+ | # Compile source files (in current directory!) passed as arguments with debug. | ||
+ | # Option --link or -l also links the library in the module's util directory. | ||
+ | |||
+ | # Do parallel build, set to empty if not wanted. | ||
+ | PARALLEL="-P4" | ||
+ | |||
+ | if [ -z "$INPATH" ]; then | ||
+ | echo "No \$INPATH, source environment!" | ||
+ | exit 1 | ||
+ | fi | ||
+ | UTIL="" | ||
+ | if [ "$1" == "--link" -o "$1" == "-l" ]; then | ||
+ | UTIL="Yes" | ||
+ | shift | ||
+ | fi | ||
+ | |||
+ | # Determine the current hierarchy depth by looking upwards for the prj/d.lst | ||
+ | # file, but no more than MAX levels up. | ||
+ | DLST="prj/d.lst" | ||
+ | SUBS="" | ||
+ | MAX=5 | ||
+ | for (( LEVEL=0 ; LEVEL < MAX ; ++LEVEL )); do | ||
+ | if [ -f "${SUBS}${DLST}" ]; then | ||
+ | break | ||
+ | fi | ||
+ | SUBS="../$SUBS" | ||
+ | done | ||
+ | OUTP="${SUBS}${INPATH}/slo" | ||
+ | if [ $LEVEL == $MAX ]; then | ||
+ | echo "No ${SUBS}${DLST} found! (LEVEL $LEVEL)" | ||
+ | exit 1 | ||
+ | fi | ||
+ | |||
+ | ERR=0 | ||
+ | # Force compilation of files passed as arguments. | ||
+ | for x in "$@"; do | ||
+ | FILE="${x//*\//}" | ||
+ | BASE="${FILE%.*}" | ||
+ | FULL="${OUTP}/${BASE}.obj" | ||
+ | rm "$FULL" | ||
+ | if [ -z "$PARALLEL" ]; then | ||
+ | dmake debug=t "$FULL" | ||
+ | fi | ||
+ | ERR=$? | ||
+ | if [ $ERR != 0 ]; then | ||
+ | break | ||
+ | fi | ||
+ | done | ||
+ | # If no error, compile yet uncompiled files and create archive, if any. | ||
+ | if [ $ERR == 0 ]; then | ||
+ | dmake $PARALLEL debug=t | ||
+ | ERR=$? | ||
+ | fi | ||
+ | # Some modules, such as Writer, have an extra archiving step one level up, e.g. | ||
+ | # in sw/source/core/ if files in sw/source/core/layout/ were compiled. | ||
+ | # Do this only if deeper than in module level. | ||
+ | if (( LEVEL > 1 )); then | ||
+ | if [ $ERR == 0 -a -f ../makefile.mk ]; then | ||
+ | pushd .. | ||
+ | dmake debug=t | ||
+ | ERR=$? | ||
+ | popd | ||
+ | fi | ||
+ | fi | ||
+ | # If no error, link library if requested. | ||
+ | if [ $ERR == 0 -a -n "$UTIL" ]; then | ||
+ | UTIL="${SUBS}util" | ||
+ | if [ ! -d "$UTIL" ]; then | ||
+ | echo "No $UTIL directory, no linking." | ||
+ | exit | ||
+ | fi | ||
+ | cd "$UTIL" | ||
+ | dmake debug=t | ||
+ | ERR=$? | ||
+ | fi | ||
+ | exit $ERR | ||
+ | </source> | ||
− | |||
− | |||
− | |||
− | |||
[[Category:Developer Tools]] | [[Category:Developer Tools]] |
Latest revision as of 20:48, 8 September 2010
Here are some Little Helpers for the enthusiastic developer, such as small scripts that help to tame the OOo code base.
Tools for maintaining identifier databases
GNU ID-utils
The GNU ID-utils are a powerful set of utilities to generate and query a database of file names and identifiers, invoke your favourite editor with the resulting set of files, or accomplish any other task with the resultset. Be sure to not use the original version 3.2, use the Debian package instead, or maybe some other distribution's package. For details why and how to patch a self-compiled version 3.2d see this blog entry.
The ID-utils come with an
;;; id-utils.el -- emacs interface to `lid -R grep', a.k.a. `gid'
For how to interface with the vim editor see the
Vim editor's GNU ID-utils section.
Generally, the editor invoking functionality of ID-utils uses the shell
variables VISUAL or EDITOR, EIDARG, EIDLDEL and EIDRDEL, so
it should be possible to invoke any capable editor. Citing from the
documentation:
`eid' invokes the editor defined by the environment variable `VISUAL'. If `VISUAL' is undefined, it uses the environment variable `EDITOR' instead. If `EDITOR' is undefined, it defaults to `vi'. It is possible for `eid' to pass the editor an initial search pattern so that your cursor will immediately alight on the token of interest. This feature is controlled by the following environment variables: `EIDARG' A printf(3) format string for the editor argument to search for the matching token. For `vi', this should be `+/%s/'. `EIDLDEL' The regular-expression meta-character(s) for delimiting the beginning of a word (the ``eid' Left DELimiter'). `eid' inserts this in front of the matching token when a word-search is desired. For `vi', this should be `\<'. `EIDRDEL' The regular-expression meta-character(s) for delimiting the end of a word (the ``eid' Right DELimiter'). `eid' inserts this in end of the matching token when a word-search is desired. For `vi', this should be `\>'.
The ID-utils use an extension → language mapping file id-lang.map. Either edit the system-wide file of your installation or a local copy thereof. Here we're assuming a local copy as $HOME/devbase/id-lang.map, add the following entries:
# Treat OOo/SO resource header files as C files *.hrc C # Treat OOo/SO header files generated from *.idl as C++ files *.hdl C++ # Treat OOo IDL files as C++ files, not exactly a header file, but ... *.idl C++ # Treat OOo/SO resource files as C files *.src C # Treat OOo/SO *.mk files as makefiles *.mk make
Note: The *.mk make entry doesn't seem to work, the makefile.mk's IDs are not added to the database, didn't investigate yet why.
Then the script below may be invoked either
- In a module's directory without parameters, creating an ID database for just the single module.
- In the $SRC_ROOT directory for all modules:
mkid-script '*'
Note the literal '*' asterisk that is not to be expanded by the shell.
The file size of the generated ID file using this method currently (m223) is 31MB. - In the $SRC_ROOT directory for specified modules:
mkid-script '{module1,module2,solver}'
Again, note the literal argument enclosed in single quotes for the file name expansion, which is done by the script. If the argument was not passed literally, only the first module would be included, and other strange things may happen.. Wildcards may be used as usual.
It is a good idea to include the solver module to gather identifiers from delivered header files.
Ignore messages like
mkid: can't lstat `unxlngi4.pro' from `.../SRC680/src.m180/solver' or
mkid: can't lstat `build' from `.../SRC680/src.m180/module1/unxlngi4.pro/misc'
They result from the INPATH relevant arguments passed for each module and don't harm.
You may also manually invoke mkid in the $SRC_ROOT directory for all
modules, this is a safe bet but may include more than you want if you have
output directories for multiple platforms, all identifiers present there will
get duplicated, triplicated, ... the command line for this is
mkid --lang-map=$HOME/devbase/id-lang.map --statistics
mkid-script
The module-wise script, suggested name: $HOME/devbase/mkid-script
#!/bin/tcsh # Either the current module, or all modules can be ID'ed if $1 is # specified as literal '*' unexpanded. Will be expanded here. # Instead of '*' _any_ shell wildcard should be possible, e.g. '{.,bf_*}'. # Output directories except $INPATH/inc and $INPATH/misc/build are skipped in # these cases. # A simple ALL generator, not ignoring any directory, is the parameter 'all'. # Warning, that may create a huge database and massively duplicated entries if # more than one platform's output directory exists. if ( { ( which mkid >> /dev/null ) } ) then echo generating IDs if ( "$1" == "-o" ) then set output="--output=$2" shift shift else set output="" endif if ( "$1" == "" ) then set module="." #set exclude=./{common,unxlngi6,unxsols4,wntmsci10}{,.pro} # Wildcards not only make updates unnecessary but also suppress "no # match" error messages. The CVS* and .svn* directories are included # for the case of a freshly checked out source that does not have any # output directories yet. Otherwise that would still lead to a "no # match" error if no wildcarded names matched. set exclude=./{CVS*,.svn*,common*,*unxlng*,*unxsol*,*unxmac*,*wntmsc*} else if ( "`basename '$1'`" == "*" ) then set module="$1" echo module: $module # prevent command line overflow with a full exclude set exclude="x" echo exclude: $exclude else if ( "$1" == "all" ) then set module="$1" echo module: $module set exclude="nothing" echo exclude: $exclude else set module="$1" echo module: $module set exclude=$1/{CVS*,.svn*,common*,*unxlng*,*unxsol*,*unxmac*,*wntmsc*} echo exclude: $exclude endif if ( "`basename '$1'`" == "*" ) then # test for ls overrun set dcommand="ls -d $module/*" if ( ! { ( $dcommand >> /dev/null ) } ) then echo "$0 : ls overrun, trying find $module -mindepth 1 -maxdepth 1" # test for find mindepth/maxdepth availability set dcommand="find $module -mindepth 1 -maxdepth 1" if ( ! { ( $dcommand >> /dev/null ) } ) then echo "$0 : find doesn't know options -mindepth -maxdepth" echo "$0 : too bad, giving up." exit 1 endif endif # Only positive list of module subdirectories and files, # excluding output directories except $INPATH/{inc,misc/build} set dirs="$module/$INPATH/inc $module/$INPATH/misc/build `$dcommand | sed -e '/\(\/\(CVS\|common\|.*unxlng\|.*unxsol\|.*unxmac\|.*wntmsc\|Jamfile\|cscope\.\|tags\|ID\)\)\|^solver\//d'`" echo dirs: $dirs echo Creating output: $output mkid --lang-map=$HOME/devbase/id-lang.map --include='C C++ asm perl java make' $output --statistics $dirs else if ( "$1" == "all" ) then echo Creating output: $output mkid --lang-map=$HOME/devbase/id-lang.map --include='C C++ asm perl java make' $output --statistics else # all but negative list plus INPATH relevants echo Creating output: $output mkid --lang-map=$HOME/devbase/id-lang.map --include='C C++ asm perl java make' $output --statistics --prune="$exclude" $module $module/$INPATH/inc $module/$INPATH/misc/build endif else echo no ID-utils endif
Exuberant Ctags
The Exuberant Ctags utility interfaces nicely with Emacs and Vim and enables quick lookup for declarations and definitions of macros, typedefs, constants, enums, variables, structs and classes and their methods and implementation. You should get the latest version available at http://ctags.sourceforge.net/, which currently (2006-08-27) is v5.6, older versions included by distributions for example don't automatically recognize .mk files as makefiles, and v5.6 also added a patch needed for the vim 7.0 omni-completion feature. Ctags creates a file tags in the current directory, if not told otherwise.
As creating a tags file over all modules and directories exceeded the 2GB file size limit, a positive directory list was used to go along with a '*' parameter, identical to the one used in the mkid-script above. The file size of the tags file generated for '*' currently (m182) is 398MB.
ctags-script
For use with the OOo code base a script with a syntax similar to the ID-utils script above comes handy, suggested name: $HOME/devbase/ctags-script
#!/bin/tcsh # Either the current module, or all modules can be ctag'ed if $1 is # specified as literal '*' unexpanded. Will be expanded here. # Instead of '*' _any_ shell wildcard should be possible, e.g. '{.,bf_*}'. # NOTE: ctags on '*' exceeded 2GB file size limit if for _all_ OOo modules and # no positive dirs list was used. if ( "$?MYCTAGS" == "0" ) then set MYCTAGS="ctags" endif if ( { ( which "$MYCTAGS" >> /dev/null ) } ) then echo generating ctags # Options necessary for the Vim OmniCppComplete plugin, # http://www.vim.org/scripts/script.php?script_id=1520 # --c++-kinds=+p : Adds prototypes in the database for C++ files. # --fields=+iaS : Adds inheritance (i), access (a) and function # signatures (S) informations. # --extra=+q : Adds context to the tag name. Note: Without this # option, the script cannot get class members. set omnicppoptions="--c++-kinds=+p --fields=+iaS --extra=+q" if ( "$1" == "--global" ) then if ( ! $?UPDMINOREXT ) set UPDMINOREXT="" "$MYCTAGS" -h "+.hdl.hrc" --langmap=c:+.hdl.hrc.src $omnicppoptions -R $SOLARVERSION/$INPATH/inc$UPDMINOREXT else if ( "$1" == "" ) then set module="." else set module="$1" echo module: $module endif # test for ls overrun set dcommand="ls -d $module/*" if ( ! { ( $dcommand >> /dev/null ) } ) then echo "$0 : ls overrun, trying find $module -mindepth 1 -maxdepth 1" # test for find mindepth/maxdepth availability set dcommand="find $module -mindepth 1 -maxdepth 1" if ( ! { ( $dcommand >> /dev/null ) } ) then echo "$0 : find doesn't know options -mindepth -maxdepth" echo "$0 : too bad, giving up." exit 1 endif endif # Only positive list of module subdirectories and files, # excluding output directories except $INPATH/{inc,misc/build} set dirs="$module/$INPATH/inc $module/$INPATH/misc/build `$dcommand | sed -e '/\(\/\(CVS\|\.svn\|common\|.*unxlng\|.*unxsol\|.*unxmac\|.*wntmsc\|Jamfile\|cscope\.\|tags\|ID\)\)\|^solver\//d'`" echo dirs: $dirs "$MYCTAGS" -h "+.hdl.hrc" --langmap=c:+.hdl.hrc.src $omnicppoptions -R $dirs endif else echo no ctags endif
Ignore messages like
ctags: Warning: cannot open source file "./unxlngi6.pro/misc/build" : No such file or directory
or consider them purely informational.
Note that also here, if more than one module is to be specified, the shell
filename glob-patterns and metanotations have to be passed in single quotes.
Though tagging an entire OOo code base would result in a "file overflow" with
more than 2GB this isn't a problem in practice, at least with Vim, don't know
about other editors, since it may search the tags files going up the
directory hierarchy if a tag is not found in the current directory's tags file.
So generate the tags file in the modules you are interested in, using the
script without parameters, then cd $SRC_ROOT
and invoke
scriptname --global
to produce a tags file for the solver.
A final ctags note: In some cases, you might have more than one version of ctags on your system. E.g., there is a version that ships with Emacs (and is often in /usr/local/bin) that doesn't support the same arguments as Exhuberant ctags; if this is the case (you'll see an error message from the script like "unrecognized option `--langmap=c:+.hdl.hrc.src'") then you can set the MYCTAGS variable, e.g., from a bash shell:
MYCTAGS=/usr/bin/ctags $HOME/devbase/ctags-script --global MYCTAGS=/usr/bin/ctags CTAGS=-e $HOME/devbase/ctags-script --global # generate TAGS for Emacs
If all you have is the Emacs version, you will want to rewrite the script (or provide a better solution here).
Cscope
Cscope is another utility to query a database for code elements. It comes with a cumbersome screen-oriented interactive tool to browse source files, but also interfaces nicely with Vim and Emacs. Unfortunately it is not able to cope with the entire OOo source base it seems, so for '*' even when called with a list of files to work on, at the end it displayed Input string too long, limit 50251 and no output was generated. Didn't investigate yet what exactly is the problem. However, using it on a subset of several modules is possible.
cscope-script
This script may be used to generate a cscope.out database file, same parameter syntax as the mkid-script and ctags-script above. Suggested name: $HOME/devbase/cscope-script
#!/bin/tcsh # Either the current module, or all modules can be tagID'ed if $1 is # specified as literal '*' unexpanded. Will be expanded here. # Instead of '*' _any_ shell wildcard should be possible, e.g. '{.,bf_*}'. # NOTE: cscope on '*' hanged if for _all_ OOo modules and no positive dirs list # was used. Even with the generated cscope.files it still refuses to complete # its work. if ( { ( which cscope >> /dev/null ) } ) then echo generating cscope if ( "$1" == "" ) then set module="." else set module="$1" echo module: $module endif # test for ls overrun set dcommand="ls -d $module/*" if ( ! { ( $dcommand >> /dev/null ) } ) then echo "$0 : ls overrun, trying find $module -mindepth 1 -maxdepth 1" # test for find mindepth/maxdepth availability set dcommand="find $module -mindepth 1 -maxdepth 1" if ( ! { ( $dcommand >> /dev/null ) } ) then echo "$0 : find doesn't know options -mindepth -maxdepth" echo "$0 : too bad, giving up." exit 1 endif endif # Only positive list of module subdirectories and files, # excluding output directories except $INPATH/{inc,misc/build} set dirs="$module/$INPATH/inc $module/$INPATH/misc/build `$dcommand | sed -e '/\(\/\(CVS\|\.svn\|common\|.*unxlng\|.*unxsol\|.*unxmac\|.*wntmsc\|Jamfile\|cscope\.\|tags\|ID\)\)\|^solver\//d'`" echo dirs: $dirs ( find $dirs -name '*.[hc]' -o -name '*.[hc]xx' -o -name '*.[hc]pp' -o -name '*.[hs]rc' >cscope.files ) >>& /dev/null if ( `uname` == "SunOS" ) then cscope -b -c else cscope -b -c -q endif else echo no cscope endif
Note that the find command is executed in a subshell with stderr redirected to /dev/null to suppress all the find: ./unxlngi6.pro/misc/build: No such file or directory and the like warning messages. Remove the parentheses and the redirection in case you suspect errors in your environment.
All together now
Surely we don't want to invoke all these scripts separately all the times, so here's a small wrapper just to prove that the suggested names actually make sense ;-) let's call it $HOME/devbase/tagsID
#!/bin/tcsh # Either the current module, or all modules can be tagID'ed if $1 is # specified as literal '*' unexpanded. Will be expanded here. # Instead of '*' _any_ shell wildcard should be possible, e.g. '{.,bf_*}'. # NOTE: ctags on '*' exceeds 2GB file size limit if for _all_ OOo modules. # NOTE: cscope on '*' hangs if for _all_ OOo modules. # Which actually is the reason we invoke it last just in case we forgot.. ${0:h}/ctags-script "$1" ${0:h}/mkid-script "$1" ${0:h}/cscope-script "$1"
The same syntax as with the other scripts applies: filename glob-patterns and metanotations have to be passed as literals, enquoted with single quotes. Invoking it in a module's directory without passing an argument creates databases for that single module.
Build selected source code files with debug
Sometimes only a few files need to be build with debug instead of an entire module, which significantly saves time. Change into the directory and invoke the following script with the files of interest passed as arguments, for example, in sc/source/core/tool
mkd token.cxx compiler.cxx interpr*.cxx
To also link the library in the module's util directory pass the --link or -l option:
mkd -l token.cxx compiler.cxx interpr*.cxx
mkd
#!/bin/bash
# Compile source files (in current directory!) passed as arguments with debug.
# Option --link or -l also links the library in the module's util directory.
# Do parallel build, set to empty if not wanted.
PARALLEL="-P4"
if [ -z "$INPATH" ]; then
echo "No \$INPATH, source environment!"
exit 1
fi
UTIL=""
if [ "$1" == "--link" -o "$1" == "-l" ]; then
UTIL="Yes"
shift
fi
# Determine the current hierarchy depth by looking upwards for the prj/d.lst
# file, but no more than MAX levels up.
DLST="prj/d.lst"
SUBS=""
MAX=5
for (( LEVEL=0 ; LEVEL < MAX ; ++LEVEL )); do
if [ -f "${SUBS}${DLST}" ]; then
break
fi
SUBS="../$SUBS"
done
OUTP="${SUBS}${INPATH}/slo"
if [ $LEVEL == $MAX ]; then
echo "No ${SUBS}${DLST} found! (LEVEL $LEVEL)"
exit 1
fi
ERR=0
# Force compilation of files passed as arguments.
for x in "$@"; do
FILE="${x//*\//}"
BASE="${FILE%.*}"
FULL="${OUTP}/${BASE}.obj"
rm "$FULL"
if [ -z "$PARALLEL" ]; then
dmake debug=t "$FULL"
fi
ERR=$?
if [ $ERR != 0 ]; then
break
fi
done
# If no error, compile yet uncompiled files and create archive, if any.
if [ $ERR == 0 ]; then
dmake $PARALLEL debug=t
ERR=$?
fi
# Some modules, such as Writer, have an extra archiving step one level up, e.g.
# in sw/source/core/ if files in sw/source/core/layout/ were compiled.
# Do this only if deeper than in module level.
if (( LEVEL > 1 )); then
if [ $ERR == 0 -a -f ../makefile.mk ]; then
pushd ..
dmake debug=t
ERR=$?
popd
fi
fi
# If no error, link library if requested.
if [ $ERR == 0 -a -n "$UTIL" ]; then
UTIL="${SUBS}util"
if [ ! -d "$UTIL" ]; then
echo "No $UTIL directory, no linking."
exit
fi
cd "$UTIL"
dmake debug=t
ERR=$?
fi
exit $ERR