The ZIP-Archive (40 KB) contains the KEDIT-macro ktags.kex, a manual
ktags.doc (this text as plain text), help topics for MS C 6.0 Quickhelp ktags.qh,
for Watcom C/C++ 10.0 WHelp ktags.wh, and for OS/2 View ktags.os2 as examples.
1. Introduction
1.1 New features
1.2 Tags file
1.3 Installation
2. CTAGS data
2.1 Tags created by KTAGS.KEX
2.2 Tags created explicitly
2.3 Tags created manually
2.4 Other hypertext databases
3. Help tool
3.1 Help topics
3.2 KTAGS configuration
3.3 Creating a topic file
1. Introduction
KTAGS.KEX is a near relative of XTAGS.KEX by Chris Dunford, which was
the successor of CTAGS.KEX by Nico Mak of Mansfield Software. Unlike
its predecessors KTAGS.KEX works with "normal" tags created for vi or
other editors supporting the vi-style of /^line$/-targets. I have
changed this, because I wanted to use tags created by UNIX and Watcom
ctags. Especially Watcom's CTAGS.EXE offers many advanced features
not found in other ctags-tools.
In a typical KTAGS-session you browse through various sources to find
the definitions of function names, and then you want to return to the
point where you started. KTAGS notes all sources and points within
these sources for a later return, XTAGS notes only the previous file.
XTAGS works with existing tags files, KTAGS allows you to create tags
on the fly if it doesn't exist. If you need it (as I did), KTAGS.KEX
can work with more than one environment, e.g. use Watcom's WHELP.EXE
for library functions if \WATCOM\ appears in the INCLUDE-setting, or
use QH (quick help) otherwise. It's possible to use other help tools
like man, VIEW or Windows Help, as soon as you have created a topic
file for whatever help tool you have, see below.
The general format of lines in a tags file is item + source + target,
where item is a function name, #defined symbol, typedef, struct, or
enum tag etc. For the purposes of KTAGS.KEX item can be any string
of alphanumeric characters as returned by Kedit's focusword.1() - so
if you want to look up a symbol at the cursor position, simply press
the KTAGS key. In my Kedit profile I define C-H to do 'macro ktags'
(C help) and A-H as 'khelp' (Kedit help). F1, the traditional help
key, issues 'macro C-H' in *.C, *.H, *.ASM files, otherwise it calls
'macro A-H'. This way I have always both help keys available, and F1
gives me the most likely needed help depending on the file type.
The source in a line of a tags file is simply the file name. Without
path you can use the tags only in the directory where you created it.
The most general approach uses absolute paths, and then you can use
arbitrary tags files whereever you are. The format is determined by
the source specifications, when you created the tags file with CTAGS.
The rest of a line in the tags file is a line target, some examples:
main intro.c /^int main( void ) \/*no arguments needed \/*$/
myprintf intro.h /^#define myprintf cprintf \/* no stdio.h \/*$/
In the vi-style of regular expressions /^ and $/ match the begin and
end of a line, and for Kedit KTAGS simply removes /^ and $/, it uses
Kedit's TFIND to look for complete lines in a source. This form of
regular expressions requires to escape any / in the target, therefore
//, /* and */ appear as \/\/, \/*, and *\/ in the tags file. Using \
as escape character of course requires to escape any \ in the source,
so something like C:\OS2 would appear as C:\\OS2 in the tags file.
KTAGS simply removes all \ escape characters in string targets before
locating source lines with Kedit's TFIND. As XTAGS.KEX and CTAGS.KEX
are based on Mansfield's CTAGS.EXE, which specifies line targets by
something like delimit( line ), e.g. /line/ in lines without /, they
cannot work with the traditional vi-style of tags files. KTAGS.KEX
looks for /^ at the beginning of line targets, assuming vi-style if
found, and Kedit delimiters (without \ escape characters) otherwise.
Traditional ctags tools don't support spaces in source names, and so
a simple parse var TAGSLINE ITEM SOURCE TARGET splits a tags line in
its components. Watcom's CTAGS separates ITEM, SOURCE, and TARGET by
tabs instead of spaces, and therefore KTAGS.KEX supports both ways.
As mentioned above you should normally define a help key like C-H for
KTAGS.KEX, in my INITIAL.KML I have something like the following:
:F1
if wordpos(ft.1(), 'C H ASM') > 0 then 'macro C-H' ; else 'khelp'
:C-H
'macro KTAGS'
The INITIAL.KML is "defined", i.e. declared as in-line macro library,
in my Kedit profile PROFILE.KEX:
if initial() then
do
'define INITIAL.KML'
/* ... more stuff ... */
end
Unlike XTAGS.KEX you can use KTAGS.KEX also directly from the command
line, just enter KTAGS printf or whatever you want to know about C.
To return to the previous point(s) in the source(s) where you invoked
KTAGS, enter KTAGS without argument or press the C-Help-Key while the
cursor is on the command line.
2. CTAGS data
Obviously you need a ctags-tool to create tags. Sources are widely
available, and as mentioned above KTAGS.KEX works with both vi-style
and Kedit targets. A traditional ctags writes its output to stdout:
ctags *.c *.h *.cpp *.hpp > tags
Watcom's CTAGS.EXE writes its output by default in the file tags, but
you can specify another file with the -f option:
ctags *.c *.h *.cpp *.asm -ftags
If KTAGS.KEX does not find a tags file in the current directory, it
opens a dialog box (d = drive, cwd = current working directory):
OK to create cTAGS on the fly
or specify another cTAGS file
d:\cwd\TAGS..................
[OK] [cancel]
If you want to use an existing tags file in another directory, then
simply overwrite d:\cwd\TAGS and press Enter (resp. click OK). KTAGS
assumes that you want to use this tags file for the whole session and
won't bother you again, unless the specified tags file doesn't exist.
If you want to create a tags file d:\cwd\TAGS on the fly, then simply
press Enter (resp. click OK). KTAGS.KEX then issues a ctags command
like the following:
dosn ctags -qdst *.c *.h -fd:\cwd\TAGS
If you want to use other options like -dstc adding C++ classes to the
tags, or more sources like *.cpp, then you have to "configure" KTAGS
before by editing the line CTAGS = 'ctags -qdst *.c *.h -f' near the
top of KTAGS.KEX. For a traditional ctags tool instead of Watcom's
CTAGS.EXE you have to replace -f by > in the CTAGS-line, for example:
CTAGS = 'ctags *.c *.h >'
These examples let the OS locate CTAGS.EXE in your PATH, and for some
obscure reasons (still working with DOS :-) I configured KTAGS.KEX to
use an absolute path:
CTAGS = 'C:\WATCOM\BINB\CTAGS.EXE -qdst *.c *.h -f'
Probably your environment is different, and then you have to modify a
few lines including CTAGS = in the configurable section of KTAGS.KEX.
A more sophisticated approach to create tags and keep them upto date
is possible with makefiles (example taken from XTAGS.DOC):
# inference rule to compile and run CTAGS.EXE when sources change
.c.obj:
cl $@
ctags $*.c > $*.tag
# at end of MAKE combine CTAGS output for all files in system
always:
copy *.tag tags > nul
Today it's no problem to create tags from scratch on the fly, and so
another approach could be to delete tags in .c.obj: and clean: rules,
just to be (almost) sure that whatever existing tags are upto date.
As shown above you can use a tags file only in the current directory,
not enough for big projects with sources in many directories. If all
source directories have the _SAME_ relative path, use something like:
ctags ..\*.c ..\*.h >> ..\tags [traditional ctags]
ctags -qdsta ..\*.c ..\*.h -f..\tags [Watcom's CTAGS.EXE]
Then specify ..\tags, when KTAGS.KEX asks for you for the tags file.
If all your projects are organized in the _SAME_ way, you can bypass
the KTAGS.KEX question by adding 'editv set KTAGS.C ..\tags' to your
Kedit profile. In a Kedit session use the Kedit command ...
editv set KTAGS.C new_tags
... to change the tags file again. Sometimes you are not interested
in tags and want to use KTAGS.EXE only for C library functions (etc.)
based on your compiler's help. A simple way to avoid KTAGS questions
in this case is to create a dummy tags file containing just one empty
line. Or let KTAGS.KEX create a tags file, and as it doesn't contain
library functions (normally), you then will get your compiler's help
without further questions (in this directory).
You can add tags not found by CTAGS.EXE to your tags file "manually",
i.e. with other tools like awk, perl, or Rexx scripts. As an example
Watcom's CTAGS.EXE does not recognize cProc macros found in assembler
sources, but the following piece of Rexx code does the trick:
TAGS = 'c:\msc\src\tags' /* the tags file */
/* ... stuff to visit all c:\msc\src\sub directories omitted */
/* ... assume NEXT = next *.asm source file below c:\msc\src */
do while lines( NEXT ) > 0
LINE = linein( NEXT ) .
if abbrev( LINE, 'cProc' ) then do /* found a cProc */
parse var LINE . 7 NAME ',' . /* get rid of it */
NAME = strip( NAME ) /* remove <...>: */
NAME = strip( strip( NAME, 'L', '<' ), 'T', '>' )
LINE = '/' || LINE || '/' /* add delimiter */
call lineout TAGS, NAME || d2c(9) || NEXT || d2c(9) || LINE
end
end
call stream NEXT, 'c', 'close' /* free the NEXT file handle */
call stream TAGS, 'c', 'close' /* close for access by CTAGS */
The script visits all subdirectories, handles *.c and *.h sources by
'ctags -dsta -f' || TAGS ABSOLUTE || '*.c' ABSOLUTE || '*.h' with its
append option (-a), and then for each subdirectory NEXT *.asm sources
as shown using their ABSOLUTE paths. If I don't understand QuickHelp
for library functions, then after 'editv set KTAGS.C c:\msc\src\tags'
KTAGS.KEX shows me directly the corresponding sources. Make your own
c:\gcc\lib.src\gnu.tag if you like...
You guess it, as long as your tags have the form item + file + target
separated by tab characters, you can use KTAGS.KEX as some kind of a
Kedit hypertext engine. If targets don't begin with /^, which would
trigger the un-escape mechanism as shown in 1.2, they can be anything
recognized by Kedit's TFIND, including line numbers like :214 etc.
To transform a MS C source browser database in an ordinary tags file
you need CREF.EXE 6.0 (shipped with MASM 6.0). Use the CL resp. ML
options -Fr -Zs to create single source browser files (*.SBR), this
is similar to the creation of single tag files (*.TAG) with CTAGS.
Then use PWBRMAKE -oANY.BSC *.SBR to combine source browser files in
a source browser database, similar to the combination of *.TAG files
into one tags file. Finally CREF ANY.BSC, ANY.REF generates a cross
reference listing of all symbols in these sources. To transform the
cross reference list into a tags file for KTAGS use a Kedit macro or
something like the following Rexx script fragment:
ITEM = '' ; CREF = 'any.ref' ; TAGS = 'tags' /* file names */
do while lines( CREF ) > 0
LINE = linein( CREF )
if LINE = '' | LINE = d2c( 12 ) then iterate
if left( LINE, 1 ) <> ' ' then do
if words( LINE ) = 1 then ITEM = LINE /* found a tag */
iterate
end
parse value LINE '0' with WORD LINE /* test number */
if abbrev( LINE, 'Cross-Reference' ) then iterate
if \ datatype( left( '0' || WORD, length( WORD )), 'w' ) then
do
FILE = WORD /* note source */
parse var LINE WORD LINE /* 2nd word */
if \ datatype( left( '0' || WORD, length( WORD )), 'w' )
then do /* CREF quirk: */
FILE = FILE || WORD /* more source */
WORD = '.' /* patch '.' */
end
if right( FILE, 1 ) = '.' /* CREF quirk: */
then FILE = left( FILE, length( FILE ) - 1 )
do while WORD = '.' /* skip '.' */
parse var LINE WORD LINE /* search line */
end
end
do until LINE = '' /* WORD is nnn or nnn# */
if right( WORD, 1 ) = '#' then do /* handle nnn# */
WORD = left( ':' || WORD, length( WORD ))
call lineout TAGS, ITEM || d2c(9) || FP || d2c(9) WORD
end
parse var LINE WORD LINE /* on all line numbers */
end
end
3. Help tool
Almost all C compilers are shipped with some form of a help tool like
QH.EXE (MS C 6.0 QuickHelp), WHELP.EXE (Watcom C/C++ 10.0 under DOS),
VIEW.EXE and library help files (OS/2), man pages (*NIX), and so on.
If you press the C-Help-key for an unknown function, you want to see
either its source file or the compiler's help for a library function.
XTAGS.KEX used a separate database with known QuickHelp topics, which
was a great help for me as long as I used MS C and QuickHelp. So the
first I did with XTAGS.KEX for the use with Watcom's WHELP.EXE was to
replace QH by WHELP CLIB and oops... Watcom doesn't support all its
library funtions as separate WHELP topics, e.g. for _dos_findnext the
command for direct help would be 'whelp clib "_dos_find Functions"'.
The next I tried was to extend the XTAGS.KEX database to support such
group topics like "_dos_find Functions" in a macro called WTAGS.KEX:
$_dos_findnext$_dos_find Functions [WHELP group topic]
$_dos_freemem$ [normal WHELP topic]
This worked, but finally I decided to use a general approach for both
tags and help topics. When tags have the form item + file + target,
then topics can have the form item + nothing + command, where nothing
means no file and + is a tab character d2c(9) as in the Watcom tags.
With this solution there is no more necessary difference between tags
and topics, the tags are something like local topics, and the topics
are something like global tags. This btw also simplifies KTAGS.KEX,
as the procedure to locate and handle tags resp. topics is the same.
All KTAGS needs to know about "global tags", i.e. help topics, is the
name of your topic file. The default until you configured KTAGS is:
TOPIC = 'ktags.os2' /* OS/2 Watcom clib topics */
if opsys.1() <> 'OS/2' then do
if pos( 'WATCOM', translate( dosenv( 'INCLUDE' ))) > 0
then TOPIC = 'ktags.wh' /* file with Watcom topics */
else TOPIC = 'ktags.qh' /* otherwise use QH topics */
end
This way KTAGS uses KTAGS.WH, if the token WATCOM appears in your OS
environment setting for INCLUDE, and KTAGS.QH otherwise. If you only
specify the file name, KTAGS looks for the topic file in your normal
PATH, and as a last resort in Kedit's MACROPATH. If you have not set
or used a macro path until today, here's an example:
SET KEDIT=WIDTH 2048 MACROPATH KEX
SET KEX=C:\REXX\KEX
Of course you can "configure" (edit :-) KTAGS.KEX to use an absolute
path to whatever topic file depending on whatever condition you want,
just look for the line(s) TOPIC = below the other "configurable" line
CTAGS = 'C:\WATCOM\BINB\CTAGS -qdst *.c *.h -f'.
The topic file KTAGS.QH ready for QH or KTAGS.WH ready for WHELP most
likely cannot help you, and you have to create your own topic file.
Okay, it's difficult, but you can use it as long as you use Kedit and
the same help tool. You need to know all topics of your help tool,
therefore save the table(s) of contents in a file KTAGS.TOC, if your
help tool supports this somehow. If this is impossible, concatenate
all library include files into one huge KTAGS.TOC file. Now edit the
KTAGS.TOC leaving only the topics left adjusted, erase anything else.
Some cups of coffee later KTAGS.TOC has this (sorted) form:
#
##
#@
#define
#elif
...
write
xycoord
y0
y1
yn
Now add two tab characters and the corresponding help command to all
topics. Two tabs are shown here as two spaces, example for QH:
# qh #
## qh ##
#@ qh #@
#define qh #define
#elif qh #elif
...
write qh write
xycoord qh xycoord
y0 qh y0
y1 qh y1
yn qh yn
That's it, move the new KTAGS.TOC to the directory with KTAGS.KEX in
your macro path, and configure TOPIC = 'ktags.toc' in KTAGS.KEX. The
example in this form is obviously overkill, but you're free to extend
it in many different ways, another example, 2 tabs shown as 2 spaces:
__minreal whelp clib "Global Data"
__win_flags_alloc whelp clib "Global Data"
__win_flags_realloc whelp clib "Global Data"
_amblksiz whelp clib "Global Data"
_arc whelp clib "_arc, _arc_w, _arc_wxy"
_arc_w whelp clib "_arc, _arc_w, _arc_wxy"
_arc_wxy whelp clib "_arc, _arc_w, _arc_wxy"
_asctime whelp clib "asctime Functions"
...
write whelp clib "write"
y0 whelp clib "bessel Functions"
y1 whelp clib "bessel Functions"
yn whelp clib "bessel Functions"
As long as the topics are different you can collect topics of several
help tools in one KTAGS.TOC, add QH MASM topics, WHELP CPPLIB topics,
VIEW REXXAPI topics, whatever you like.
KEXX / REXX scripts.
Last update: 8 Dec 2002 22:00 by F.Ellermann