xyzzy

KTAGS.KEX

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

top   1.1 New features

    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.

top   1.2 Tags file

    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.

top   1.3 Installation

    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

top   2.1 Tags created by KTAGS.KEX

    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.

top   2.2 Tags created explicitly

    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).

top   2.3 Tags created manually

    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...

top   2.4 Other hypertext databases

    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

top   3.1 Help topics

    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.

top   3.2 KTAGS configuration

    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'.

top   3.3 Creating a topic file

    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.

top   KEXX  /  REXX scripts.


XHTML validator Last update: 8 Dec 2002 22:00 by F.Ellermann